如何修改Snowflake JS存储过程实现批量检测SQL脚本合法性
问题描述
我有一张存储id与SQL脚本的表,因脚本数量达上千条,无法手动用Explain plan检测脚本是否可执行,需实现动态批量检测。表样例如下:
id | script 1 | Select current_date(); 2 | Select current_timestamps(); 3 | Select * from t1 where t1 > 1000; 4 | select * from t2 where date < current_date();
其中id为3的脚本存在错误。我编写了名为TestQuery的JavaScript存储过程,期望返回所有错误脚本的id组成的逗号分隔字符串,但当前过程遇到第一个错误脚本就抛出异常终止运行。请问应如何调整try/catch逻辑,实现记录错误id后继续执行下一个脚本?
当前存储过程代码如下:
create or replace procedure TestQuery (table_name VARCHAR,column_name1 string,column_name2 string) returns string not null language javascript as $$ var op = ""; // Dynamically compose the SQL statement to execute. var sqlCommand = "select " + COLUMN_NAME1 + "," + COLUMN_NAME2 + " from " + TABLE_NAME; // Prepare statement. var stmt = snowflake.createStatement( { sqlText: sqlCommand } ); // Execute Statement var res = stmt.execute(); while (res.next()) { v_col_name = res.getColumnValue(2); sqlcommand2 = "explain using tabular " + v_col_name var stmt2 = snowflake.createStatement( { sqlText: sqlcommand2 } ); var res2 = stmt2.execute(); while (res2.next()) { try{ //do nothing } catch{ op = op + "," + res.getColumnValue(1); } } } if (op = "") { return "all success" } else { return op} $$;
调整方案
原代码的核心问题是try/catch未包裹可能抛出异常的执行逻辑,且存在赋值判断错误。调整后的代码如下:
create or replace procedure TestQuery (table_name VARCHAR,column_name1 string,column_name2 string) returns string not null language javascript as $$ var op = ""; // 动态拼接查询表数据的SQL var sqlCommand = `select ${COLUMN_NAME1}, ${COLUMN_NAME2} from ${TABLE_NAME}`; var stmt = snowflake.createStatement({ sqlText: sqlCommand }); var res = stmt.execute(); while (res.next()) { var scriptId = res.getColumnValue(1); var sqlScript = res.getColumnValue(2); var explainSql = `explain using tabular ${sqlScript}`; try { // 将可能抛出异常的操作全部放入try块 var stmt2 = snowflake.createStatement({ sqlText: explainSql }); var res2 = stmt2.execute(); // 遍历结果集,避免Snowflake资源泄漏 while (res2.next()) {} } catch (err) { // 拼接错误ID,避免开头出现多余逗号 op = op ? `${op},${scriptId}` : scriptId; } } // 修正空值判断逻辑 return op === "" ? "all success" : op; $$;
关键改动说明
- 修正try/catch范围:将创建语句、执行Explain的操作全部放入try块,确保脚本执行出错时能被捕获,不会终止整个存储过程。
- 修复空值判断错误:把
if (op = "")改为op === "",避免将空字符串赋值给op的逻辑错误。 - 优化错误ID拼接:通过
op ?${op},${scriptId}: scriptId的写法,避免结果开头出现多余的逗号。 - 补充结果集遍历:即使Explain执行成功,也要遍历结果集,防止Snowflake因未读取结果导致的资源问题。
- 变量命名优化:将模糊的变量名改为
scriptId、sqlScript,提升代码可读性。
内容的提问来源于stack exchange,提问作者danD
相关产品推荐
相关产品推荐

