问题描述
我有下面的 SNowflake Javascript 存储过程,我需要在其中替换 sql 语句中字符串的多个实例。
arr2.forEach((obj) => {
const idx = arr1.findindex((o) => o.traits.id === obj.user_id);
if (idx !== -1) {
arr1[idx] = { ...arr1[idx],traits: { ...obj } }
}
})
console.log(arr1[0]) // { name: 'Bob',traits: { name: 'Bob',user_id: 1,dog: 'puppy' } }
当我执行上述存储过程时,得到以下输出。在这里, CREATE OR REPLACE PROCEDURE MYSCHEMA.CountryDelete(COUNTRY VARCHAR)
RETURNS string
LANGUAGE JAVASCRIPT
AS
$$
var error_msg = 'Success';
try
{
var sql_cmd_temp = `DELETE FROM MYSCHEMA.CountryTable_{country}
WHERE COUNTRY_CODE = '{country}';`
var sql_cmd = sql_cmd_temp.replace("{country}",COUNTRY);
return sql_cmd;
}
catch(err)
{
error_msg += "ERROR : " + err.message;
}
return sql_cmd;
$$;
的第一个实例被替换为 {country}
(其中 CH
是我在执行此存储过程时发送的参数值)而不是第二个。
CH
我期待以下输出。
DELETE FROM ODP_SUBNATIONAL_STAGING.IDP_SUBNATIONAL_SALES_CH
WHERE COUNTRY_CODE = '{country}';
我也尝试过 Javascript 的 DELETE FROM ODP_SUBNATIONAL_STAGING.IDP_SUBNATIONAL_SALES_CH
WHERE COUNTRY_CODE = 'CH';
而不是 replaceAll
,但它返回 replace
。
请注意,由于我必须在多行中对 sql 进行硬编码,因此在将 sql 字符串存储到变量中时,我需要使用 Grave 重音符号。否则我会使用 [NULL]
符号来存储 sql 并使用 "
符号使其动态化。
如果有人能帮助解决这个问题,那将非常感谢。
解决方法
最后,我找到了一个使用 RegExp 对象的构造函数的解决方案。
var sql_cmd = sql_cmd_temp.replace(new RegExp('{country}','g'),COUNTRY);
这是更新后的代码。
CREATE OR REPLACE PROCEDURE MYSCHEMA.CountryDelete(COUNTRY VARCHAR)
RETURNS string
LANGUAGE JAVASCRIPT
AS
$$
var error_msg = 'Success';
try
{
var sql_cmd_temp = `DELETE FROM MYSCHEMA.CountryTable_{country}
WHERE COUNTRY_CODE = '{country}';`
var sql_cmd = sql_cmd_temp.replace(new RegExp('{country}',COUNTRY);
return sql_cmd;
}
catch(err)
{
error_msg += "ERROR : " + err.message;
}
return sql_cmd;
$$;
这是结果。
DELETE FROM ODP_SUBNATIONAL_STAGING.IDP_SUBNATIONAL_SALES_CH
WHERE COUNTRY_CODE = 'CH';
,
您可以使用 JavaScript 模板文字 ${myVariable}
;那么您不必对用作字符串模板的每个变量进行替换。只要您用反引号终止字符串文字,这就会起作用。
CREATE OR REPLACE PROCEDURE CountryDelete(COUNTRY VARCHAR)
RETURNS string
LANGUAGE JAVASCRIPT
AS
$$
var error_msg = 'Success';
try
{
var sql_cmd = `DELETE FROM MYSCHEMA.CountryTable_${COUNTRY}
WHERE COUNTRY_CODE = '${COUNTRY}';`
return sql_cmd;
}
catch(err)
{
error_msg += "ERROR : " + err.message;
}
return sql_cmd;
$$;
,
更安全的方法是使用绑定 - 如果您的计划是在存储过程中执行查询:
create or replace temp table prefix_delete_me as
select 1 x,'me' as country;
CREATE OR REPLACE PROCEDURE testbind(COUNTRY VARCHAR)
RETURNS string
LANGUAGE JAVASCRIPT
AS
$$
var stmt = snowflake.createStatement({
sqlText: `
select *
from identifier(:2)
where country=:1
and country != concat('hello',:1,:1)
`,binds:[COUNTRY,'prefix_delete_'+COUNTRY]
});
// execute the statement to prove its correct
stmt.execute();
// just get the sql statement
return stmt.getSqlText();
$$;
call testbind('me')