【问题标题】:delete specific tables using stored procedure in Oracle在 Oracle 中使用存储过程删除特定表
【发布时间】:2014-02-25 11:53:37
【问题描述】:

我很困惑。我有一个用户可以在 SQL Developer 中运行以下内容,并且运行良好。

begin
 FOR C IN (SELECT TABLE_NAME FROM ALL_TABLES
              WHERE TABLE_NAME LIKE 'TEMP_%'
              AND OWNER = '<user name in caps>')
    LOOP
      EXECUTE IMMEDIATE('DROP TABLE <user name in caps>.' || C.table_name || ' PURGE');
    END LOOP;
end;

但是 - 如果我将功能包装在存储过程中并运行它,而不会引发异常,则以“temp”开头的表不会删除。我实际上是从三个不同的模式中删除 - 因此是重复。

CREATE OR REPLACE PROCEDURE DELETETEMPTABLES AS 
BEGIN
  --DROP ANY TABLES THAT START WITH "TEMP_"
    FOR C IN (SELECT TABLE_NAME FROM ALL_TABLES
              WHERE TABLE_NAME LIKE 'TEMP_%'
              AND OWNER = '<user name in caps>')
    LOOP
      EXECUTE IMMEDIATE('DROP TABLE <user name in caps>.' || C.table_name || ' PURGE');
    END LOOP;

        FOR C IN (SELECT TABLE_NAME FROM ALL_TABLES
              WHERE TABLE_NAME LIKE 'TEMP_%'
              AND OWNER = '<user name in caps>')
    LOOP
      EXECUTE IMMEDIATE('DROP TABLE <user name in caps>.' || C.table_name || ' PURGE');
    END LOOP;

    FOR C IN (SELECT TABLE_NAME FROM ALL_TABLES
              WHERE TABLE_NAME LIKE 'TEMP_%'
              AND OWNER = '<user name in caps>')
    LOOP
      EXECUTE IMMEDIATE('DROP TABLE <user name in caps>.' || C.table_name || ' PURGE');
    END LOOP;
exception
    WHEN OTHERS THEN
         log_errors (p_error_message => 'Nightly Processing->DeleteTempTables-> ' ||SQLERRM);
END DELETETEMPTABLES;

【问题讨论】:

    标签: oracle plsql oracle11g


    【解决方案1】:

    贾斯汀是对的。但是您通常可以使用 AUTHID 来克服 priv 问题。试试:

    CREATE OR REPLACE PROCEDURE DELETETEMPTABLES
    AUTHID CURRENT_USER
    AS
    

    这在 Oracle 中称为“调用者权限”。默认为定义者权限(authid 定义者)。有关更多信息,请参阅herehere

    子程序中角色的使用取决于它是否执行 定义者的权利或调用者的权利。在定义者的权利范围内 子程序,所有角色都被禁用。角色不用于特权 检查,你不能设置角色。

    在调用者的权限子程序中,角色被启用(除非 子程序被定义者的权限直接或间接调用 子程序)。角色用于权限检查,您可以使用 为会话设置角色的本机动态 SQL。但是,您不能 使用角色来授予对模板对象的权限,因为角色适用 在运行时,而不是在编译时。

    【讨论】:

    • 哦,我明天试试,然后告诉你。感谢您的想法!
    【解决方案2】:

    这很可能是权限问题。

    ALL_TABLES 列出您拥有权限的所有表。当您以交互方式运行它时,这包括您通过角色拥有权限的所有表。但是,当您尝试创建存储过程时,通过角色授予的权限将被排除,您只能看到您直接授予的那些表。如果您希望您的代码工作,对象的所有者(或 DBA)将需要直接将对象的权限授予过程所有者,而不是通过角色。实际上,该过程的所有者还需要直接授予它DROP ANY TABLE 特权(而不是通过像DBA 这样的角色)才能使DROP TABLE 语句成功。

    【讨论】:

    • 啊!说得通。很遗憾,我是 DBA。所以我必须弄清楚这一点。问题是这些用于刷新过程。数据通过 dblink 拉入并放置在我以“temp”开头的表中。然后我更改这些表并添加主键。接下来我关闭数据库链接。然后我删除原始表并通过删除“temp”重命名临时表。我跟进索引/授权/等。这使得关键网站上没有明显的停机时间。但是 - 有时该过程会失败。我想提前清理任何临时文件,如果它们存在的话。关于如何处理的想法?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多