Snowflake /当存储过程作为OWNER执行时如何获取原始调用者

Posted

技术标签:

【中文标题】Snowflake /当存储过程作为OWNER执行时如何获取原始调用者【英文标题】:Snowflake / How get the original caller when a stored procedure is executed as OWNER 【发布时间】:2020-05-31 09:59:27 【问题描述】:

我创建了一个存储过程,其行为以所有者身份执行(我需要所有者的权限)。

我正在寻找调用它的用户的原始角色,有什么办法吗? 不幸的是,正如预期的那样,select current_role() 语句返回了所有者的角色......

如果存在解决方法,如果您能向我描述一下,我将不胜感激。

按照 Mike 的建议:这里有我为测试 Harsh 的解决方案所做的代码:

又失败了^^ 这是我的代码。也许你会看到我的错误。

create or replace procedure do_noting_proc()
returns string
language javascript
execute as OWNER
AS
$$
 var retour="Resultat";
 try
   rs0=snowflake.createStatement(sqlText:"SELECT $QUERY_TAG;").execute();
   cR=rs0.getColumnValue(1);
   return "QRValue= "+callerRole;        
 catch(err)
    return "do_noting_proc KO: "+ err.message+";";
 
$$;

create or replace procedure test_proc()
returns string
language javascript
execute as CALLER
AS
$$
var rString="Result -->";
try
  rs0=snowflake.createStatement(sqlText:"SELECT CURRENT_ROLE();").execute();
  rs0.next();
  cr="testQT"+rs0.getColumnValue(1);
  snowflake.createStatement(sqlText:"alter session set QUERY_TAG="+cr+";").execute();
  rs=snowflake.createStatement(sqlText:"call  PUBLIC.do_noting_proc();").execute();
  rs.next();
  rString+=rs.getColumnValue(1);
catch(err)
    return "test_proc: "+ err.message+";";

return "test_proc : "+rString;
$$;

那么call share_view_or_table(); ==>test_proc : ** 结果 -->do_noting_proc KO:在所有者权限存储过程中不允许使用会话变量“$QUERY_TAG”;** (由系统管理员创建并以系统管理员身份执行的过程)

另外,如果我运行“代码” 选择 $QUERY_TAG;

我收到错误:SQL 编译错误:第 1 行错误,位置 7 会话变量“$QUERY_TAG”不存在

SHOW PARAMETERs LIKE 'QUERY_TAG' IN SESSION ; 

工作正常并打印 TESTQTSYSADMIN

@Harsh 非常感谢您抽出宝贵时间

【问题讨论】:

您的意思是来自 SP 内部吗? 我错过了您的评论(抱歉,迈克)。是的,就是这样,在存储过程中 【参考方案1】:

当使用EXECUTE AS OWNERrules do not permit reading the caller's session details时,包括他们的身份或角色:

所有者权限存储过程在会话中遵循以下规则:

[…]

无法访问大多数特定于呼叫者的信息。例如:

无法查看、设置或取消设置调用者的会话变量。

只能读取特定的会话参数,不能设置或取消设置调用者的任何会话参数。

无法查询基于当前用户返回结果的 INFORMATION_SCHEMA 表函数,例如 AUTOMATIC_CLUSTERING_HISTORY。

虽然不方便,但您可以使用存储过程中的逻辑来强制调用者的角色名称应作为参数传递:

CREATE OR REPLACE PROCEDURE PROC(ROLE_NAME STRING)
[…]
var VALID_ROLES_ARRAY = ["FOO", "BAR"];
var IS_VALID_CALLER_ROLENAME = VALID_ROLES_ARRAY.includes(ROLE_NAME);
[…];

CALL PROC(CURRENT_ROLE());

【讨论】:

您好苛刻,谢谢您的帮助。当我尝试使用“SHOW PARAMETERS LIKE 'QUERY_TAG';”获取 query_tag 会话参数时,我错过了一些东西。我得到: Erreur do_nothing_proc():存储过程执行错误:不支持的语句类型'SHOW PARAMETER'。 (do_nothing_proc() 由作为 CALLER 的过程 TEST() 作为 OWNER 执行)有什么想法吗? 它不工作。我用代码添加了一个新的答案(很多字符来发表新评论) 谢谢 Harsh。这就是我最终得出的结论。我认为文档在这些点上不是很清楚。可能是您已经扣除了,但目标是根据参数控制程序的使用。最后,我成功地使用了“curent_user()”函数和从视图“INFORMATION_SCHEMA.APPLICABLE_ROLES”中检索到的用户角色

以上是关于Snowflake /当存储过程作为OWNER执行时如何获取原始调用者的主要内容,如果未能解决你的问题,请参考以下文章

在雪花存储过程中捕获成功消息

如何更改 Snowflake 存储过程中的会话参数

在存储过程中创建 Snowflake 仓库会更改当前仓库

Snowflake - 系统/内置存储过程

将存储过程从 Teradata BTEQ 迁移到 Snowflake

使用 Snowflake 中的任务调用存储过程