重用 PROCEDURE/FUNCTION 使用不同的值来做同样的事情

Posted

技术标签:

【中文标题】重用 PROCEDURE/FUNCTION 使用不同的值来做同样的事情【英文标题】:Reusing PROCEDURE/ FUNCTION whichever to do the same thing using different values 【发布时间】:2014-06-26 13:00:44 【问题描述】:

我有很多程序做同样的事情: 他们刷新物化视图并检查计数是否不为 0,然后将该数据推送到生产表中。这是每个人所做的框架,唯一改变的是物化视图的名称。我考虑过创建一个函数,以 MV 的名称对其进行处理,但它不起作用:(

create or replace 
function  REFRESH_MV (mv_to_refresh IN VARCHAR2)
    RETURN VARCHAR2
AUTHID CURRENT_USER 
AS

COUNTS INT;
begin
     DBMS_MVIEW.REFRESH(mv_to_refresh,'C');

     COMMIT;
     SELECT COUNT(*) INTO COUNTS FROM 'SEMANTIC.' || mv_to_refresh;

     IF COUNTS = 0 THEN  
        RETURN 'SEMANTIC.' || mv_to_refresh || ' is empty';
     ELSE
        'SEMANTIC_READ_ONLY.' || RELOAD_TABLE(mv_to_refresh);        
        RETURN  'SEMANTIC_READ_ONLY.' || mv_to_refresh || ' has been refreshed today';
     END IF;

    EXCEPTION WHEN OTHERS THEN NULL;
end;

【问题讨论】:

【参考方案1】:

您必须使用EXECUTE IMMEDIATEDBMS_SQL 来执行此操作;在您的情况下,第一个应该更容易使用。

 EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM 'SEMANTIC.' || mv_to_refresh  INTO COUNTS;

应该可以解决问题。

【讨论】:

【参考方案2】:

您应该为此使用动态 SQL:

CREATE OR REPLACE FUNCTION REFRESH_MV (mv_to_refresh IN VARCHAR2)
    RETURN VARCHAR2
    AUTHID CURRENT_USER 
AS
  COUNTS INT;
  VSQL VARCHAR2(100);
begin
    DBMS_MVIEW.REFRESH('SEMANTIC.' || mv_to_refresh, 'C');
    COMMIT;

    VSQL := 'SELECT COUNT(1) FROM SEMANTIC.' || mv_to_refresh;
    EXECUTE IMMEDIATE VSQL INTO COUNTS;

    IF COUNTS = 0 THEN  
        RETURN 'SEMANTIC.' || mv_to_refresh || ' is empty';
    ELSE
        SEMANTIC_READ_ONLY.RELOAD_TABLE(mv_to_refresh);  
        RETURN  'SEMANTIC_READ_ONLY.' || mv_to_refresh
        || ' has been refreshed today';
    END IF;

    EXCEPTION
        WHEN OTHERS THEN
            RETURN 'Error has occured: ' || SQLERRM;
END;

请确保您将不带架构前缀的视图名称作为输入参数传递。

您还应该注意,由于它起作用,它应该返回值或引发异常。但是在您的示例函数中,如果出现异常,则不会返回任何内容。

我没有完全理解 RELOAD_TABLE() 过程的语义。在给定的示例中,它应该是 SEMANTIC_READ_ONLY 模式中的某个过程。如果您确实需要动态评估适当的函数,您可以再次使用动态 SQL 构造包含代码的有效字符串并调用它:

vsql := 'begin SCHEMA_NAME.' || GET_PROCEDURE_FOR(mv_to_refresh) || '; end;';
execute immediate vsql;

【讨论】:

以上是关于重用 PROCEDURE/FUNCTION 使用不同的值来做同样的事情的主要内容,如果未能解决你的问题,请参考以下文章

MySQL存储过程(PROCEDURE)

What is the difference between routine , method , procedure , function ? please explain it with exam

oracle‘s package,function,proceture编译时无响应(解决)

Oracle包编译,调用或调试Package时卡死问题

为啥 OkHttp 不重用它的连接?

UITableView 不使用情节提要重用单元格