Snowflake存储过程用query_id调用RESULT_SCAN获取DESCRIBE结果失败如何解决
Snowflake存储过程读取DESCRIBE TABLE返回结果的解决方案
问题根因
- 现有代码执行
result_scan查询后没有读取结果集并返回,因此存储过程运行后返回空值。 - 存储过程内部执行的SQL属于存储过程的私有会话上下文,在外部手动调用
result_scan时会话不匹配,因此会抛出statement not found错误,同一会话内的存储过程内部调用result_scan可以正常访问对应query_id。
最优实现方案(无需调用RESULT_SCAN)
DESCRIBE TABLE执行后返回的结果对象本身就可以直接遍历读取,不需要绕RESULT_SCAN,性能更好逻辑更简单,示例代码如下:
CREATE OR REPLACE PROCEDURE GET_TEST_TABLE_DESC() RETURNS VARCHAR LANGUAGE JAVASCRIPT AS $$ // 执行DESCRIBE语句 var desc_sql = `DESCRIBE TABLE TEST_TABLE`; var desc_result = snowflake.execute({sqlText: desc_sql}); var result_arr = []; // 遍历DESCRIBE返回的结果集 while (desc_result.next()) { // 可按需读取DESCRIBE返回的任意字段,常见字段:name(列名)、type(数据类型)、null?(是否可空) var column_name = desc_result.getColumnValue('name'); var column_type = desc_result.getColumnValue('type'); result_arr.push(`列名:${column_name},数据类型:${column_type}`); } // 返回拼接后的结果,也可根据需求返回JSON、数组等其他格式 return result_arr.join('\n'); $$; -- 调用存储过程查看结果 CALL GET_TEST_TABLE_DESC();
确需使用RESULT_SCAN的实现方式
如果业务场景必须通过RESULT_SCAN获取结果,可参考以下代码,注意仅支持在存储过程同一会话内访问对应query_id:
CREATE OR REPLACE PROCEDURE GET_TEST_TABLE_DESC_BY_SCAN() RETURNS VARCHAR LANGUAGE JAVASCRIPT AS $$ var desc_sql = `DESCRIBE TABLE TEST_TABLE`; var desc_run = snowflake.execute({sqlText: desc_sql}); var query_id = desc_run.getQueryId(); // 构造RESULT_SCAN查询 var scan_sql = `SELECT * FROM TABLE(RESULT_SCAN('${query_id}'))`; var scan_result = snowflake.execute({sqlText: scan_sql}); var result_arr = []; while (scan_result.next()) { var column_name = scan_result.getColumnValue('name'); var column_type = scan_result.getColumnValue('type'); result_arr.push(`列名:${column_name},数据类型:${column_type}`); } return result_arr.join('\n'); $$; -- 调用存储过程查看结果 CALL GET_TEST_TABLE_DESC_BY_SCAN();
补充说明
如果需要在存储过程外部访问DESCRIBE的结果,建议直接在存储过程中将结果写入一张临时表或普通表,再在外部查询这张表即可,不要直接跨会话调用RESULT_SCAN。
内容的提问来源于stack exchange,提问作者Ankit Srivastava
相关产品推荐
相关产品推荐

