You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 02:01:15