雪花、任务和会话变量问题

Posted

技术标签:

【中文标题】雪花、任务和会话变量问题【英文标题】:Snowflake, Tasks and Session variables problem 【发布时间】:2019-11-01 09:47:58 【问题描述】:

我在 Snowflake 中遇到问题,其中任务执行存储过程,并且 SP 正在使用我想用于记录目的的会话变量 QUERY_TAG。 当 Task 执行 SP 时,我会得到错误: “会话变量 '$QUERY_TAG' 不存在” EXECUTE AS CALLER 在那里 我尝试在哪里设置 QUERY_TAG(在第一个任务前置代码或定义中)并不重要。

任务和 SP 由我作为 SYSADMIN 创建

当我在查询编辑器(Snowflake、DBeaver 等)中执行 SP 时,它运行良好,因此 SP 中没有编码错误。 SET QUERY_TAG = '一个不错的查询标签' 调用 TASK_SCHEMA.SP_TASK_ONE()

当我在 Worksheet 或 DBeaver 或类似工具中调用它时,它运行良好。 SP 中的两种方式都有效(内联 SQL 或通过 getQueryTag 函数)

这是Tasks和SP的代码

CREATE OR REPLACE TASK TASK_SCHEMA.TASK_ONE_PRECOND
    WAREHOUSE = TASK_WH
    SCHEDULE = '2 minute'
    QUERY_TAG = 'My Query Tag'
AS
    SET QUERY_TAG = 'My Query Tag 2'


CREATE OR REPLACE TASK TASK_SCHEMA.TASK_ONE
    WAREHOUSE = TASK_WH
    AFTER TASK_SCHEMA.TASK_ONE_PRECOND
AS
    CALL TASK_SCHEMA.SP_TASK_ONE()


create or replace procedure TASK_SCHEMA.SP_TASK_ONE()
    RETURNS VARCHAR(50)
    LANGUAGE javascript
    EXECUTE AS CALLER
as $$    

function getQueryTag()

    var QueryTag;
    rs_QT = snowflake.execute (  sqlText: `SELECT $QUERY_TAG;`   );
    if( rs_QT.next())
    
        QueryTag = rs_QT.getColumnValue(1); // get the QueryTag
    

    return QueryTag; 
   

    var qtag = getQueryTag();

    //rs = snowflake.execute (  sqlText: 
    //`INSERT INTO "LOG"."TESTSESSIONLOG"
    //  ("SESSION_NAME")
    //SELECT $QUERY_TAG
    //`   );


    snowflake.execute(
               sqlText: `INSERT INTO LOG.TESTSESSIONLOG 
               (SESSION_NAME) 
               VALUES (?)`
               ,binds: [ qtag]
    );   

    return "SESSION_OK"; 

  $$;

【问题讨论】:

【参考方案1】:

编辑 2019 年 11 月 4 日:我在下面的回答并不完全正确,有一种方法可以在任务及其后继者之间传递值。请参阅SYSTEM$SET_RETURN_VALUE 上的文档。

即使您定义了任务之间的依赖关系,这并不意味着任务会从任务树中的前任继承任何内容。

因此,如果您在一项任务中设置变量,则该变量会在任务完成时丢失。

这与在会话中执行的命令之间保留会话状态的普通会话(如在 GUI 中)不同。

任务之间,唯一相关的是前任的结束时间和后继的开始时间。

在提取查询标签时,最好向系统索取:

function getQueryTag()

    var rs_QT = snowflake.execute (  sqlText: `SHOW PARAMETERS LIKE 'QUERY_TAG'`   );
    return rs_QT.next() && rs_QT.getColumnValue("value"); // get the QueryTag
 

【讨论】:

如果我在第一个任务中设置 QUERY_TAG 并从那里调用该过程,会有所不同吗? SP 是否在“任务会话”中运行并有权访问 $QUERY_TAG 或者 SP 是否在独立于任务的自己的会话中执行?创建或替换任务 TASK_SCHEMA.TASK_ONE_PRCOND WAREHOUSE = TASK_WH SCHEDULE = '2 分钟' QUERY_TAG = '我的查询标签' AS CALL TASK_SCHEMA.SP_TASK_ONE() 这会让一切变得不同。有关如何提取 QUERY_TAG 会话参数的信息,请参见我上面的函数...应该不需要 SQL 变量 $QUERY_TAG... 我不知道 docs.snowflake.net/manuals/sql-reference/functions/… 可以让您将任务结果传递给后续任务。

以上是关于雪花、任务和会话变量问题的主要内容,如果未能解决你的问题,请参考以下文章

如何使用代理与 Snowpark 会话构建器连接到雪花

在雪花任务上授予监视器

雪花 - 任务未运行

父级暂停和子级恢复后雪花子任务未运行

如何在雪花任务语句中使用复制存储集成?

雪花任务多个计划