Snowflake存储过程查询失败时如何将query_id等信息写入日志表
Snowflake存储过程错误日志落地方案
首先提前创建统一的错误日志表,参考DDL如下:
create or replace table error_table ( error_time timestamp_tz default current_timestamp(), error_code varchar, error_message varchar, failed_query_id varchar, failed_query_text varchar, procedure_name varchar default 'ERROR_LOG_TEST' );
优化后的完整存储过程实现:
create or replace procedure error_log_test() returns varchar not null language JAVASCRIPT as $$ let copy_into_cmd = `copy into my_table from @my_stage file_format=(format_name= 'my_file_format') on_error = skip_file;`; let copy_into_stmt = snowflake.createStatement({sqlText: copy_into_cmd}); try { let result_set = copy_into_stmt.execute(); result_set.next(); return '执行成功'; } catch (err) { // 使用绑定变量插入日志,避免SQL注入和特殊字符转义问题 const log_insert_stmt = snowflake.createStatement({ sqlText: `insert into error_table (error_code, error_message, failed_query_id, failed_query_text) values (?, ?, ?, ?)`, binds: [ err.code, err.message, copy_into_stmt.getQueryId(), copy_into_stmt.getSqlText() ] }); log_insert_stmt.execute(); return `执行失败,错误信息:${err.message}`; } $$;
核心优化说明
- 解决了原代码异常块引用未初始化变量的问题:失败SQL的query_id和语句文本直接从语句对象
copy_into_stmt获取,不依赖只有执行成功才会返回的结果集对象 - 采用绑定变量传参:避免直接拼接SQL带来的注入风险,也无需手动处理错误信息里的引号、特殊字符转义问题
- 补全了语法逻辑,避免原有代码的语法报错、二次异常问题
- 日志表默认带执行时间、存储过程名字段,降低后续排查成本
可选扩展建议
- 如需更详细的排查信息,可以追加
err.stack字段存入错误堆栈信息 - 如果存储过程内要执行多段SQL,可以封装通用的日志插入方法复用代码
- 可根据日志量给日志表配置时间分区,提升大数量下的查询效率
内容的提问来源于stack exchange,提问作者viswa
相关产品推荐
相关产品推荐

