雪花存储过程 - 如何检索 CTAS 语句创建的行数

Posted

技术标签:

【中文标题】雪花存储过程 - 如何检索 CTAS 语句创建的行数【英文标题】:Snowflake Stored Procedure - how do I retrieve the number of rows created by a CTAS Statement 【发布时间】:2019-12-16 16:33:41 【问题描述】:

在雪花存储过程中,我正在执行 CTAS 语句并希望检索结果对象中的行数。我们无权访问 QUERY_HISTORY(我们得到一个错误),并且 RESULT_SCAN(LAST_QUERY_ID()) 也无济于事(它返回了 Table xyz Created 结果,但没有元数据,即创建的行数)。

我可以在单独的查询中使用 Select Count(*) 来做到这一点,但这似乎是一个 hack,因为行计数就在历史记录中。

    CREATE OR REPLACE PROCEDURE EDW_ADMIN.DAG_TEST()
    RETURNS VARCHAR(512)
    LANGUAGE javascript
    AS 
    $$
    
    let strCTAS = "";
    let rsCTAS;
    let rsRowsAffected;
    let rowsAffected = 0;   

    strCTAS = "CREATE OR REPLACE TABLE EDW_ADMIN.DEMO_PROC_TEMP AS SELECT * FROM RAW_BIR.H_RPTUNIT;";
    rsCTAS = snowflake.execute( sqlText: strCTAS );

    // This works in a Query Worksheet in the browser, but gives me the following error when called from a procedure
    //      "[Stored procedure execution error: Requested information on the current user is not accessible in stored procedure.]"
    rsRowsAffected = snowflake.execute( sqlText: "SELECT ROWS_PRODUCED FROM TABLE(INFORMATION_SCHEMA.QUERY_HISTORY(RESULT_LIMIT=>100)) WHERE QUERY_ID = LAST_QUERY_ID();" );
    rsRowsAffected.next();
    rowsAffected = rsRowsAffected.getColumnValue(1); 


    // This works, but you are doing execute i/o which is really un-necessary
    // rsRowsAffected = snowflake.execute( sqlText: "SELECT COUNT(*) FROM EDW_ADMIN.DEMO_PROC_TEMP;" );
    // rsRowsAffected.next();
    // rowsAffected = rsRowsAffected.getColumnValue(1); 

    // This does NOT work, RESULT_SCAN has no metadata associated with it, this returns "Table DEMO_PROC_TEMP successfully created."
    // rsRowsAffected = snowflake.execute ( sqlText: "SELECT * FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()));"  );
    // rsRowsAffected.next();
    // rowsAffected = rsRowsAffected.getColumnValue(1); 

    return rowsAffected;

$$
;

CALL EDW_ADMIN.DAG_TEST();

DROP EDW_ADMIN.DEMO_PROC_TEMP;
DROP PROCEDURE EDW_ADMIN.DAG_TEST();

【问题讨论】:

【参考方案1】:

尝试将 execute as caller 添加到存储过程声明中。例如:

create or replace procedure p() 
returns text
language javascript
execute as caller
as
  $$
  const stmt1 = snowflake.createStatement(  sqlText: "create or replace table t as select $1 x from values (1),(2),(3)"  )
  const rs1 = stmt1.execute()

  const stmt2 = snowflake.createStatement(  sqlText: "SELECT ROWS_PRODUCED FROM TABLE(INFORMATION_SCHEMA.QUERY_HISTORY(RESULT_LIMIT=>100)) WHERE QUERY_ID = LAST_QUERY_ID()"  )
  const rs2 = stmt2.execute()
  rs2.next()
  const rowsAffected = rs2.getColumnValue(1)
  return rowsAffected
  $$
;


call p();

返回 3

【讨论】:

您也可以在这里使用 QUERY_HISTORY_BY_SESSION 和 RESULT_LIMIT => 1。避免在您的选择中返回 100 个结果。 两种方法都运行良好,但我必须指定 RESULT_LIMIT=>2 并添加 where 子句。 抱歉处理延迟 - 似乎有道理,将在假期后确认。祝大家休息愉快!!!

以上是关于雪花存储过程 - 如何检索 CTAS 语句创建的行数的主要内容,如果未能解决你的问题,请参考以下文章

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

雪花 JDBC 驱动程序内部错误:无法检索第一个箭头块的行数:null - 仅发生在 SELECT 语句上

雪花存储过程多语句列表参数

当我在存储过程中使用相同的公式计算日期时,日期值格式不同 - 雪花

如何获取雪花中执行存储过程的名称?

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