当前位置: 首页 > 知识库问答 >
问题:

雪花存储过程:处理多行字符串和单引号

乐正翰
2023-03-14

我在雪花存储过程中使用反勾来构建下面的插入查询,它在激发sql时工作得很好

CREATE OR REPLACE PROCEDURE SP_TEST_CALLPROC()
RETURNS STRING
LANGUAGE JAVASCRIPT
EXECUTE AS OWNER
AS $$
var q = `insert into abc 
         select col1, col2, 
         to_date(col3,'YYYYMMDD') as col3 from def;`
var insrtSql = snowflake.createStatement({sqlText: q});
var result = insrtSql.execute();
result.next()
$$
;

我还想将此查询记录到日志表中,由于TO_DATE函数'yyyymmdd'中的单引号,该查询失败了:

CREATE OR REPLACE PROCEDURE SP_LOAD_LOG_POC(PROCESS_ID FLOAT,
                            PROCESS_NAME STRING,
                            BATCH_ID FLOAT,
                            LOG_TXT STRING)
    RETURNS STRING
    LANGUAGE JAVASCRIPT
    EXECUTE AS OWNER
    AS $$
 
    var query = `INSERT INTO INGESTION_LOG
                  VALUES
                  (${PROCESS_ID},'${PROCESS_NAME}',${BATCH_ID},current_timestamp(),'${LOG_TXT}');`
    var stmt = snowflake.createStatement( { sqlText: query});
    var res = stmt.execute();
 $$
;
CREATE OR REPLACE PROCEDURE SP_TEST_CALLPROC()
RETURNS STRING
LANGUAGE JAVASCRIPT
EXECUTE AS OWNER
AS $$
function log(process_id,process_name,batch_id,log_txt){
        snowflake.createStatement( { sqlText: `call SP_LOAD_LOG_POC(:1,:2,:3,:4)`, binds:[process_id,process_name,batch_id,log_txt] } ).execute();
        }

var q = `insert into abc 
         select col1, col2, 
         to_date(col3,'YYYYMMDD') as col3 from def;`
log(1,'test_procedure',12345,`Firing insert query : ${q}`);
var insrtSql = snowflake.createStatement({sqlText: q});
var result = insrtSql.execute();
result.next()
$$
;

CALL SP_TEST_CALLPROC()

Execution error in store procedure SP_TEST_CALLPROC: 
Execution error in store procedure SP_LOAD_LOG_POC: SQL compilation error: syntax error line 5 at position 23 unexpected 'YYYYMMDD'.
At Statement.execute, line 10 position 19 
At Statement.execute, line 4 position 169

尝试使用javascript函数replaceAll()将单引号替换为2个单引号('->''),但雪花存储过程中不支持此函数。有人能建议如何在插入日志条目时消除此错误吗

共有1个答案

糜运良
2023-03-14

如果必须将SQL作为字符串传递给另一个函数、UDF或SP,除了单个刻度之外,还有许多特殊字符需要考虑。下面是我编写的两个JavaScript帮助器函数,用于确保插入时不同数据类型的安全性。

由于wrapInsertValue函数为文本类型调用escapeInsertString,所以您可以只调用该类型。wrapInsertValue函数的目的是读取列的类型并相应地处理它。注意,escapeInsertString函数也将压缩空白。您可以注释掉s=s.replace(/\s+/g,“”)行;如果您不想这样做。

function wrapInsertValue(value, dataType){
    if (value == 'null'){
        return 'NULL';
    }
    switch (dataType){
        case "TEXT":
            return "'" + escapeInsertString(value) + "'";
        case "OBJECT":
            return "'" + escapeInsertString(value) + "'";
        case "TIMESTAMP_TZ":
            return "'" + value + "'";
        case "TIMESTAMP":
            return "'" + value + "'";
        default: return value;
    }
}

function escapeInsertString(value) {
    var s = value.replace(/\\/g, "\\\\");
    s = s.replace(/'/g, "''" );
    s = s.replace(/"/g, '\\"');
    s = s.replace(/\s+/g, " ");
//  s = s.replace(/[^\x00-\x7F]/g, "");
    return s;
}
 类似资料:
  • Snowflake文档指出,VARCHAR列仅限于16 MB未压缩的https://docs.Snowflake.net/manuals/sql-reference/data-types-text.html#data-types-for-text-strings Snowflake文档指出,VARCHAR数据会自动转换为JavaScript字符串数据类型。 https://docs.Snowfla

  • 1选定列的参数(选定的筛选器/下拉属性或从UI发送的列名) 2 dynamic where子句的参数,用于为点1中选择的类似下拉列表值准备 从视图中获取数据,并以这种方式检索结果 注意:在这一点上没有要求显示特定于某个用户的数据。同样忽略上面代码中的参数插值部分 是否存在任何数据完整性问题,不同的用户将看不到UI上更新的值(为了提供更多的上下文,从此过程中的视图中提取数据,并且该视图数据在应用程序

  • 我正在使用游标连接字符串(以形成稍后执行的查询)。在这里,将要形成的查询将比VARCHAR2(32767)所能处理的要大得多。因此,我在执行过程中得到了错误-ORA-06502:PL/SQL:数值或值错误:字符串缓冲区太小。 我也使用了CLOB数据类型,但得到了错误ORA-06502:PL/SQL:numeric或value错误。 我的代码如下: 我如何处理我的查询字符串,有什么数据类型来完成任务

  • 关于如何使用传递的参数的任何线索。

  • 问题内容: 我有一个将文本字段中的值发送到数据库的应用程序。 例如,我有一个带有一个字段的表单(文本框)。当我按“确定”按钮时,文本字段的内容将作为记录插入到表中。我只是修剪并将文本框的文本提取到变量中,然后将其传递给我的SQL字符串。 问题是,无论何时像“ It’s”或“ Friend’s”之类的单引号都被标识为字符串的结尾。在Delphi中,我看到了避免这种情况的方法。您有什么想法吗? 问题答