Snowflake创建Javascript存储过程时正则反斜杠被删除问题求助
问题原因
这个问题是两层转义叠加导致的:
- 第一层转义:存储过程的代码是JavaScript,你写在反引号模板字符串里的
\\.会首先被JS引擎解析,两个反斜杠转义为1个反斜杠,此时传递给SQL执行的内容里已经只剩下\. - 第二层转义:Snowflake SQL本身也会把反斜杠识别为转义字符,传入的
\.里的反斜杠会被SQL直接当作转义标记消耗掉,最终实际传入正则函数的模式就变成了.,自然匹配逻辑完全错误。
解决方法
以下是3种可行方案,按推荐度排序:
方案1:使用绑定变量传递参数(最推荐,完全避免转义问题)
不要把正则模式直接拼在SQL文本里,用Snowflake支持的绑定变量传参即可,修改后的存储过程示例代码:
CREATE or replace PROCEDURE TESTING_FUNC_1_THIS_CAN_BE_DELETED() RETURNS VARCHAR LANGUAGE javascript AS $$ // 正则模式直接定义为JS变量,按正常规则写转义即可 const regexPattern = '\\.[A-Z]{2,3}'; var rs = snowflake.execute( { sqlText: ` CREATE OR REPLACE VIEW Database.Schema.Table AS SELECT REXP_REPLACE_ME('APPLE.COM',?,' ') as column_cleaned `, // 按顺序传入绑定变量,框架会自动处理转义逻辑 binds: [regexPattern] } ); $$;
该方案不需要关心转义层数,也不会因为后续语法改动出现转义失效问题。
方案2:叠加转义层数,写4个反斜杠
如果一定要把正则写在SQL文本里,需要保证经过两层转义后最终还能保留1个反斜杠,因此要把原有的\\.替换为\\\\.:
CREATE or replace PROCEDURE TESTING_FUNC_1_THIS_CAN_BE_DELETED() RETURNS VARCHAR LANGUAGE javascript AS $$ var rs = snowflake.execute( { sqlText: ` CREATE OR REPLACE VIEW Database.Schema.Table AS SELECT REXP_REPLACE_ME('APPLE.COM','\\\\.[A-Z]{2,3}',' ') as column_cleaned ` } ); $$;
逻辑:JS层将\\\\转义为\\,SQL层再将\\转义为\,最终传入正则函数的就是正确的\.规则。
方案3:使用双美元符包裹正则字符串
Snowflake的SQL支持用$$包裹字符串,内部的反斜杠不会被SQL层转义,因此只需要处理JS层的转义即可,示例:
SELECT REXP_REPLACE_ME('APPLE.COM',$$\\.[A-Z]{2,3}$$,' ')
这种方式只需要写2个反斜杠,不需要叠加到4个,也能避免SQL层的转义消耗。
内容的提问来源于stack exchange,提问作者mikelowry
相关产品推荐
相关产品推荐

