替换字符串中的所有实例

问题描述

我有下面的 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')