Snowflake存储过程报错:绑定变量:STARTTIME未设置
问题描述
我创建了一个用于跟踪已开启变更追踪的表中新增插入记录的存储过程,代码如下:
create or replace procedure sp_audit_insert_counts(TABLENAME varchar, FILTER varchar, STARTTIME timestamp_ltz, ENDTIME timestamp_ltz) returns integer language sql as $$ declare iInsertCount integer default 0; begin select count(*) into :iInsertCount from identifier(:TABLENAME) changes(information => default) at(timestamp => :STARTTIME) end(timestamp => :ENDTIME) where metadata$action = 'INSERT' and metadata$isupdate = 'FALSE'; return iInsertCount; end; $$ ;
调用该过程时出现错误:
Bind variable :STARTTIME not set
调用语句为:
call sp_audit_insert_counts('TEST_TABLE', null, to_timestamp('2022-08-23 00:00:00'), to_timestamp('2022-08-23 09:00:00'))
若在过程中硬编码时间戳则可正常运行,请问问题出在哪里?
问题原因与解决方法
问题核心:Snowflake中
changes()语法的at()/end()属于查询的语法结构部分,而非普通过滤条件,无法直接绑定存储过程参数。Snowflake会将:STARTTIME识别为未赋值的外部绑定变量,而非存储过程内部参数,因此报错。解决方法:使用动态SQL拼接完整查询语句,将表名、时间参数嵌入到SQL字符串中执行,修正后的存储过程代码如下:
create or replace procedure sp_audit_insert_counts(TABLENAME varchar, FILTER varchar, STARTTIME timestamp_ltz, ENDTIME timestamp_ltz) returns integer language sql as $$ declare iInsertCount integer default 0; v_sql varchar; begin -- 拼接动态SQL,将参数嵌入查询结构 v_sql := 'select count(*) from ' || identifier(:TABLENAME) || ' changes(information => default) ' || 'at(timestamp => ''' || :STARTTIME || ''') end(timestamp => ''' || :ENDTIME || ''') ' || 'where metadata$action = ''INSERT'' and metadata$isupdate = ''FALSE'''; -- 执行动态SQL并获取结果 execute immediate :v_sql into :iInsertCount; return iInsertCount; end; $$ ;
- 补充说明:如果需要启用
FILTER参数,可在动态SQL中添加条件判断,当FILTER不为空时,将其拼接至WHERE子句后,注意处理空值避免语法错误。
内容的提问来源于stack exchange,提问作者Siddharth Kumar
相关产品推荐
相关产品推荐

