Oracle模式用户无法在过程中创建表

Bet*_*ide 1 oracle plsql create-table

我正在尝试在过程中创建临时表:

PROCEDURE pr_create_tmp_bp_table(fp_id NUMBER) IS
    tbl_name CONSTANT VARCHAR2(20) := 'BP_TO_DELETE';
BEGIN
    -- sanity checks removed for readablity

    EXECUTE IMMEDIATE 
        'CREATE GLOBAL TEMPORARY TABLE ' || tbl_name || ' ' ||
        'ON COMMIT PRESERVE ROWS AS ' ||
        'SELECT * FROM infop_stammdaten.bp';

END;
Run Code Online (Sandbox Code Playgroud)

如果我将该BEGIN.._END块复制到 SQL 工作表,则一切正常。所以我认为用户有权创建临时表。如果我从同一个 SQL 工作表执行该过程,我会得到

Fehlerbericht -
ORA-01031: Nicht ausreichende Berechtigungen
ORA-06512: in "INFOP_STAMMDATEN.PA_DELETE_FP", Zeile 16
ORA-06512: in Zeile 6
01031. 00000 -  "insufficient privileges"
*Cause:    An attempt was made to perform a database operation without
           the necessary privileges.
*Action:   Ask your database administrator or designated security
           administrator to grant you the necessary privileges
Run Code Online (Sandbox Code Playgroud)

第 16 行 (Zeile 16) 指向创建临时表的 EXECUTE IMMEDIATE 语句。

对我来说,这看起来像用户在 sql 工作表中没有相同的权限,并且当它执行过程时,该过程也位于它自己的架构中。

APC*_*APC 5

您直接问题的答案是,您得到的答案是ORA-01031: insufficient privileges因为您的用户具有通过角色授予的 CREATE TABLE 权限:Oracle 安全模型强制执行一条规则,即我们不能使用通过 PL/SQL 中的角色授予的权限。因此,您需要 DBA 直接向您的用户授予 CREATE TABLE 权限。

或者你呢?

因为您尝试做的事情在 Oracle 中没有意义。在Oracle中,全局临时表是永久结构;只是其中的数据是临时的。因此,正确的解决方案是使用普通的 DDL 脚本构建一次表,就像任何其他数据库对象一样。然后您可以根据需要插入全局临时表。

您不是本网站上第一个犯此错误的人(请阅读此相关主题)。通常这是因为人们来自另一个数据库,例如 SQL Server,它有一个名为“临时表”的结构,它实际上与 Oracle 的全局临时表不同。如果这就是您的情况,那么您将对 Oracle 18c 称为私有临时表的新功能感兴趣。它们与 SQL Server 临时表完全相同。了解更多