Snowflake存储过程执行时Timestamp转换报错求助
错误原因
- 你在JavaScript存储过程中调用
getColumnValue()获取TIMESTAMP类型的new_watermark_value时,返回值是JavaScript原生Date对象。直接将该对象拼接到SQL字符串中时,会自动调用toString()方法输出Fri Jun 11 2021 12:47:38 GMT-0700 (Pacific Daylight Time)格式的字符串,和你指定的DY MON DD HH24:MI:SS TZD YYYY解析格式不匹配,因此触发解析报错。 - 存在冗余转换逻辑:目标字段
watermark_value本身是TIMESTAMP_NTZ类型,不需要先转字符串再赋值,多余的类型转换会大幅提升出错概率。
最优解决方案
推荐使用Snowflake存储过程的绑定变量功能传递参数,完全避免字符串拼接的格式问题,同时还能规避SQL注入风险,代码更简洁。
修改后的完整存储过程代码如下:
CREATE OR REPLACE PROCEDURE test_sp() RETURNS string LANGUAGE javascript EXECUTE AS CALLER AS $$ var result = ""; snowflake.execute( {sqlText: "BEGIN TRANSACTION;"} ); try { var max_sync_sql_command = `SELECT watermark_value,dateadd(minute, -1, sysdate()) as new_watermark_value from APPLICATION_CONTROL WHERE TABLE_NAME = 'TEST1'; ` var max_sync_time_result = snowflake.execute ({ sqlText: max_sync_sql_command }); max_sync_time_result.next(); var max_sync_time = max_sync_time_result.getColumnValue(1); var new_watermark_value = max_sync_time_result.getColumnValue(2); /*Some ETL Code Here*/ -- 直接用绑定变量传时间值,不需要做任何格式转换 var update_watermark_sql_command = `update APPLICATION_CONTROL set watermark_value = :1 WHERE TABLE_NAME = 'TEST1'; ` -- 执行时通过binds参数传递变量 snowflake.execute ({ sqlText: update_watermark_sql_command, binds: [new_watermark_value] }); snowflake.execute( {sqlText: "COMMIT;"} ); result = "Record updated Successfully" } catch (err) { snowflake.execute( {sqlText: "ROLLBACK;"} ); result = "Failed: Code: " + err.code + "\n State: " + err.state; result += "\n Message: " + err.message; result += "\nStack Trace:\n" + err.stackTraceTxt; } return result; $$;
如果你确实需要手动拼接SQL字符串,也可以在JavaScript侧先将Date对象格式化为符合要求的字符串再拼接,不过该方案不如绑定变量稳定,不推荐优先使用。
内容的提问来源于stack exchange,提问作者YogeshR
相关产品推荐
相关产品推荐

