【问题标题】:Cursor in anonymous block works, but not in procedure匿名块中的游标有效,但在过程中无效
【发布时间】:2023-01-11 11:43:33
【问题描述】:

尝试为 ID(和刷新)过时的物化视图编写查询,我编写了以下代码 - 在 TOAD 或 SQL Plus 中运行时有效:

CREATE OR REPLACE procedure myuser.refresh_materialized_views as
--declare 
    cursor crs_mviews is select owner, mview_name, staleness, last_refresh_date from all_mviews 
    where 
        staleness <> 'FRESH' 
    ;
    mv_row all_mviews%rowtype;
    exec_command varchar(200) default '';
    begin_time timestamp;
    end_time timestamp;
begin
    begin_time := sysdate;
    insert into myuser.MV_REFRESH_LOG values ('BEGINNING', 'SUCCESS', sysdate, sysdate,null);
    commit;
    for mv in crs_mviews
    loop
        exec_command := 'exec dbms_mview.refresh('''||mv.owner||'.'||mv.mview_name||''''||');'
            ||' -- Last refresh: '||mv.last_refresh_date||', status is '||mv.staleness;
--        dbms_output.put_line(exec_command);
--        dbms_mview.refresh(mv.owner||'.'||mv.mview_name);
        end_time := sysdate;
        insert into myuser.MV_REFRESH_LOG values (mv.mview_name, 'SUCCESS', begin_time, end_time,mv.last_refresh_date);
        commit;
    end loop;
    insert into myuser.MV_REFRESH_LOG values ('ENDING', 'SUCCESS', sysdate, sysdate,null);
    commit;
end;

当我在 TOAD 或 SQL Plus 中运行它时它工作正常(我注释掉 CREATE PROCEDURE 并取消注释 DECLARE)。它识别那些陈旧的物化视图。但是当我运行程序本身时,它会创建开始/结束日志条目 - 但不会自行执行循环。

我在网上找到的唯一与此匹配的是 Ask Tom 上的 this posting。描述听起来很准确,但答案似乎并没有解决问题——它只是在谈论权限。当我创建或运行此过程时,我没有收到任何类型的权限错误 - 它只是运行,除了创建 BEGIN 和 END 日志条目之外什么都不做。

我想这是非常明显的事情,但我无法弄清楚。

【问题讨论】:

  • 在 Oracle 中,当您从过程或函数运行代码时,您需要直接访问而不是通过角色访问。您在块中的代码可能正在运行,因为它可以通过角色而不是通过过程进行访问。在运行块之前运行此命令以确认这一点。设置角色无;然后运行该块,如果它失败,那么您需要直接授予对对象的访问权限。

标签: oracle plsql database-cursor


【解决方案1】:

您正在使用光标中的 all_* 视图。您在 all_* 字典视图中看到的数据被过滤到您对其具有有效权限的那些对象。通过编译存储过程,您将失去角色授权而只有系统和对象授权,这会导致您通常在 all_* 视图中看到的行消失。很可能,您没有循环,因为在没有角色的情况下,在您的权限下,这些视图中没有任何内容。

要修复,要么让 DBA 授予您对所涉及对象的权限,要么请求“选择任何字典”系统权限并使用 dba_* 字典视图而不是 all_* 视图。 dba_* 视图不会根据您拥有的权限进行过滤。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-15
    • 1970-01-01
    • 2020-06-15
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多