Snowflake存储过程传字符串参数到SQL查询报Invalid Identifier错误
错误原因排查
Snowflake JavaScript存储过程的入参默认挂载在arguments[]数组下,不能直接用参数名作为变量调用,这是所有写法报错的核心原因。此外你尝试的几种拼接写法也存在语法问题:
- 第一种写法没有给字符串值加单引号,执行时SQL会把SCHNAME的内容当作标识符而非字符串,触发Invalid identifier错误
- 第二种写法手动拼接单引号容易出现转义错误,还存在SQL注入风险
- 第三种写法的JS模板字符串插值语法用错,正确语法是
${变量名}而非{$变量名},且就算语法正确,直接调用SCHNAME也无法取到入参值
可行解决方案
优先使用官方推荐的查询参数绑定方案,无需手动处理转义,也能避免SQL注入风险,修改后的完整存储过程代码如下:
CREATE OR REPLACE PROCEDURE "CREATE_SCHEMA"("SCHNAME" VARCHAR(16777216)) RETURNS VARCHAR(16777216) LANGUAGE JAVASCRIPT COMMENT='Creates schemas' EXECUTE AS CALLER AS $$ // 按参数顺序从arguments数组取入参,第一个入参对应arguments[0] const schName = arguments[0]; // 用?作为参数占位符 const v_sqlCode = "select * from dbschemas where name = ?"; try{ const sqlStmt = snowflake.createStatement({ sqlText: v_sqlCode, // 通过binds数组传入参数,自动处理类型匹配和转义 binds: [schName] }); const sqlRS = sqlStmt.execute(); // 此处可补充后续业务逻辑,例如判断Schema是否存在后执行创建操作 return "Query executed successfully"; }catch(err){ let errMessage = "Failed: Code: " + err.code + "\n State: " + err.state; errMessage += "\n Message: " + err.message + ", SQL: " + v_sqlCode; errMessage += "\nStack Trace:\n" + err.stackTraceTxt; throw 'Encountered error in executing v_sqlCode. \n' + errMessage; } $$;
调用语句无需修改,仍使用CALL CREATE_SCHEMA('SCHEMA_NAME');即可。
如果遇到需要拼接表名、Schema名这类无法用绑定参数的场景,可使用正确的JS模板字符串写法,注意手动转义单引号:
const schName = arguments[0]; // 用两个单引号转义SQL语句中的单引号 const v_sqlCode = `select * from dbschemas where name = '${schName.replace(/'/g, "''")}'`;
内容的提问来源于stack exchange,提问作者RMC_DEV
相关产品推荐
相关产品推荐

