是否可以在存储过程中设置变量以便视图使用它?

Is it possible to SET a variable inside a stored procedure so that a view uses it?

我有一个依赖于会话变量的视图:

create or replace view test as 
(
    select getvariable('MY_VAR')::int as col1
) ;

我可以这样查询该视图:

set MY_VAR=5;
select * from test; -- 5
set MY_VAR=6;
select * from test; -- 6

现在我想从存储过程执行相同的查询:

create or replace procedure myproc()
    returns VARCHAR
    language javascript
    as 
$$
    var stmt = snowflake.createStatement({sqlText: "select * from test"});
    var rs = stmt.execute();
    rs.next(); // .next().getColumnValue(1);

    return rs.getColumnValue(1);
$$
;

call myproc() -- this work as long as MY_VAR is set outside before the call proc

问题是我想在过程中设置会话变量,这是不允许的

Stored procedure execution error: Unsupported statement type 'SET'. At Snowflake.execute

最终目标是有一个 运行 存储过程的 Snowflake TASK,我需要能够以某种方式设置变量(TASK 也不允许 运行 设置,存储过程也没有)。

有什么解决办法吗?

您无法在存储过程中设置会话变量的原因是默认情况下,执行模式设置为 EXECUTE AS OWNER,这是一个更出于安全考虑限制模式。

请参阅此 Snowflake docs page 了解更多信息。

因此,只有将存储过程的执行模式设置为 EXECUTE AS CALLER,才能在存储过程中设置(和使用)会话变量。这是您的存储过程的修订版本,演示了会话变量的使用(使用任意值 7):

CREATE OR REPLACE PROCEDURE MYPROC()
  RETURNS VARCHAR
  LANGUAGE JAVASCRIPT
  EXECUTE AS CALLER
AS $$
    snowflake.execute({"sqlText": "SET MY_VAR = 7"});
    var stmt = snowflake.createStatement({"sqlText": "select * from test"});
    var rs = stmt.execute();
    rs.next(); // .next().getColumnValue(1);

    return rs.getColumnValue(1);
$$
;