在HANA存储过程中的当前用户架构中创建表?

问题描述

我有一些存储过程可以创建用于验证目的的表。这些表中的大多数会在下一次执行的过程中删除。

我创建了这些程序,当我运行它们时它们运行良好,但是我的问题是现在我们希望其他人来运行这些程序,但是它们不能。

经过研究,我发现问题在于存储过程正在尝试写入我的模式,因此,由于用户无法访问我的方案,因此他们将得到权限不足错误。

存储过程是否可以通过某种方式在调用存储过程的表中创建表,而不是创建存储过程的人的模式?

这是我创建的用于测试的小型存储过程:

CREATE OR REPLACE PROCEDURE XXX.SP_TMP_TEST ()
LANGUAGE SQLSCRIPT 
SQL SECURITY INVOKER  AS
BEGIN
    CALL XXX.SP_DROP_TABLE_IF_EXISTS ('TMP_TEST');
    CREATE COLUMN TABLE TMP_TEST (TEST INTEGER);
END

GRANT EXECUTE ON XXX.SP_TMP_TEST TO USER_B;

假设USER_A在Schema XXX中创建了此存储过程

现在,每次USER_A调用它时,表TMP_TEST都会创建到USER_A模式中。

比方说USER_B尝试运行它。他们将收到一个错误消息,说两个相同名称的表不能存在。这是因为用于删除表的存储过程将从USER_B的架构中删除该表,但是create table试图在USER_A的架构中创建该表。

唯一可行的方法是将SQL_SECURY更改为DEFINER,但这将使USER_B将表创建为USER_A的架构,而我希望将表创建为USER_B的架构或USER_C或D(无论谁调用存储过程)。

我希望这是有道理的。

提前感谢您的时间和帮助。

关于, 莱昂纳多

解决方法

这种HANA SQLScript行为的确没有记录。

文档告诉我们,如果过程未指定DEFAULT SCHEMA,则会话的 current_schema 用于不合格的对象(即,未提及架构名称的对象)在命令中)。

如果我们依赖于此(至少直到HANA 2 SP 04为止),我们就会遇到OP所描述的情况:代替会话的 current_schema 的是,该过程为“ in”用于不合格的对象。

我个人认为这是文档错误。

现在如何处理需求(可以从其他用户调用的单个过程)?

一种方法可以是在这种情况下使用动态SQL。

CREATE OR REPLACE PROCEDURE do_in_my_schema()

   SQL SECURITY INVOKER 

AS
BEGIN
    
    IF (obj_exists (CURRENT_USER,'TAB_X') = 1) THEN 
        EXEC 'DROP TABLE "'|| current_user ||'"."TAB_X"';
    END IF;
     
    EXEC 'CREATE TABLE "'|| current_user ||'"."TAB_X" (USERNAME NVARCHAR(256) PRIMARY KEY)';
   
END;

OBJ_EXISTS函数是一个自定义函数,用于检查是否存在对象(有关定义,请参见https://www.lbreddemann.org/if-exists-would-exist/)。

主要的“技巧”是使用CURRENT_USER函数为所需操作指定目标架构名称。 这些然后在动态SQL EXEC命令中执行;

所有这些都与SECURITY AS DEFINER设置无关。而是指定安全上下文(谁拥有拥有创建的表),而不指定表所属的命名空间(模式)。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...