【问题标题】:Reusing PROCEDURE/ FUNCTION whichever to do the same thing using different values重用 PROCEDURE/FUNCTION 使用不同的值来做同样的事情
【发布时间】: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;

【问题讨论】:

    标签: oracle function plsql


    【解决方案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;
      

      【讨论】:

        猜你喜欢
        • 2022-01-05
        • 1970-01-01
        • 2020-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-16
        • 1970-01-01
        相关资源
        最近更新 更多