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

时间:2019-10-15 09:02:20

标签: snowflake-data-warehouse

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

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

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

  

存储过程执行错误:不支持的语句类型'SET'。在Snowflake.execute

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

有什么解决方法吗?

1 个答案:

答案 0 :(得分:3)

无法在存储过程中设置会话变量的原因是,默认情况下,执行模式设置为 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);
$$
;