Snowflake存储过程:for循环使用结果集值时遇标识符错误求解
解决Snowflake存储过程中"invalid identifier 'RECORD.USER_ID'"错误
问题根源
你遇到的错误核心是Snowflake的标识符大小写处理规则:
- 未用双引号包裹的标识符会被自动转为大写
- 你的查询里用
"user_id"指定了小写列名,游标结果中的列名实际是小写的user_id,但调用时写record.user_id会被解析为大写USER_ID,导致系统找不到对应字段。
另外你之前手动在调用参数里加双引号的方式也容易引发混淆,建议在存储过程内部统一处理表名的大小写问题。
修正后的代码方案
方案一:修正游标列名引用
CREATE OR REPLACE PROCEDURE refreshData(sourceTable VARCHAR, targetTable VARCHAR) RETURNS BOOLEAN NOT NULL LANGUAGE SQL AS $$ DECLARE res resultset DEFAULT (SELECT DISTINCT "user_id" FROM IDENTIFIER(:sourceTable)); cur CURSOR FOR res; BEGIN FOR record IN cur DO -- 用双引号包裹小写列名,匹配游标结果中的字段名 CALL userDataRefresh(record."user_id", sourceTable, targetTable); END FOR; RETURN TRUE; END; $$; -- 调用时直接传表名,无需手动加双引号 CALL refreshData('temp_table', 'table');
方案二:显式变量接收游标值(更直观)
CREATE OR REPLACE PROCEDURE refreshData(sourceTable VARCHAR, targetTable VARCHAR) RETURNS BOOLEAN NOT NULL LANGUAGE SQL AS $$ DECLARE -- 直接将查询逻辑写在游标声明中 cur CURSOR FOR SELECT DISTINCT "user_id" FROM IDENTIFIER(:sourceTable); v_user_id VARCHAR; -- 显式声明变量存储用户ID BEGIN OPEN cur; LOOP FETCH cur INTO v_user_id; EXIT WHEN cur%NOTFOUND; -- 无数据时退出循环 CALL userDataRefresh(v_user_id, sourceTable, targetTable); END LOOP; CLOSE cur; RETURN TRUE; END; $$; CALL refreshData('temp_table', 'table');
关键优化点
- 大小写匹配:引用游标中的小写列名时,必须用双引号包裹(
record."user_id"),否则会被解析为大写标识符导致错误。 - 表名传递简化:调用存储过程时直接传入原始表名字符串,
IDENTIFIER(:sourceTable)会自动处理表名的大小写映射,无需手动添加双引号,减少出错概率。
内容的提问来源于stack exchange,提问作者tim_cashion
相关产品推荐
相关产品推荐

