Oracle 重用过程/函数以使用不同的值执行相同的操作

Oracle 重用过程/函数以使用不同的值执行相同的操作,oracle,function,plsql,Oracle,Function,Plsql,我有许多程序可以做同样的事情: 它们刷新物化视图并检查计数是否不是0,然后将该数据推送到生产表中。这是每个视图所做工作的框架,唯一需要更改的是物化视图的名称。我曾想过创建一个函数,以MV的名义对其进行处理,但它不起作用:( 您必须使用executeimmediate或DBMS\u SQL来实现这一点;在您的情况下,第一个应该更容易使用 EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM 'SEMANTIC.' || mv_to_refresh INTO COUNT

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


您必须使用
executeimmediate
DBMS\u SQL
来实现这一点;在您的情况下,第一个应该更容易使用

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

应该做到这一点。

您必须使用
立即执行
数据库管理系统SQL
来做到这一点;在您的情况下,第一个应该更容易使用

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

应该做到这一点。

为此,您应该使用动态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;
请确保传递没有架构前缀的视图名称作为输入参数

您还应该注意,scinceit函数应该返回值或引发异常。但在您的示例中,函数在异常情况下不会返回任何内容

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

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

为此,应使用动态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;
请确保传递没有架构前缀的视图名称作为输入参数

您还应该注意,scinceit函数应该返回值或引发异常。但在您的示例中,函数在异常情况下不会返回任何内容

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

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