【问题标题】:Snowflake error on parsing JSON as single quotes are not escaped将 JSON 解析为单引号时的雪花错误未转义
【发布时间】:2021-11-05 09:43:40
【问题描述】:

我在处理 Snowflake 数据仓库中的一些数据时尝试记录错误。

我在特定数据文件上遇到的错误如下,我需要将它放入一个名为DATA_LOAD_LOG的表中:

INSERT INTO DWH_OPS.DATA_LOAD_LOG 选择“数据加载过程”,?,?, (datediff('毫秒', ?, ?)/1000), current_schema(), current_database(), current_user(), current_role(), ?, parse_json('[{"Error":"Can't parse 'n/a' as date with format 'YYYY-MM-DD'","调查名称":"data.csv","阶段 名称":"@DWH_OPS.AZURE_BLOB","执行持续时间(在 秒)":5.405}]')::VARIANT

错误信息是:

“无法将 'n/a' 解析为格式为 'YYYY-MM-DD' 的日期”

catch 部分返回不同的语法错误,因为 t'YYYY-MM-DD' 之前有单引号。所以日志不会添加到表中。

这里是捕获部分脚本:

try {
  // Try code
} catch (err) {
  var obj = {};
  var res = [];
  obj["Error"] = "Exists";
  obj["Error Message"] = err.message;
  obj["Status"] = err.status;
  obj["Error Code"] = err.code;
  res.push(obj);
  var insert_into_data_log =
    "INSERT INTO DWH_OPS.DATA_LOAD_LOG select 'DATA LOAD PROCEDURE', current_timestamp(), " +
    "current_timestamp(), 0, " +
    "current_schema(), current_database(), current_user(), current_role(), " +
    "'SCRIPT ERROR', parse_json('" +
    JSON.stringify(res) +
    "')::VARIANT";
  var data_log_stmt = snowflake
    .createStatement({ sqlText: insert_into_data_log })
    .execute();

  return err;
}

我尝试用空格替换或转义它:

var errorMsg = err.message; obj['错误信息'] = errorMsg.replace("'","").replace("."," ").replace("\n"," ");

但它根本不起作用,并且抛出了同样的错误。

【问题讨论】:

    标签: javascript json escaping try-catch snowflake-cloud-data-platform


    【解决方案1】:

    如果您打算通过构造 SQL 而不是使用绑定变量直接插入字符串和日期,则必须转义的不仅仅是单引号。您还必须至少避开反斜杠和换行符。这是您可以用来执行此操作的辅助函数。

    function escapeString(str){
        str = str.replace(/'/g, "''");
        str = str.replace(/\\/g, "\\\\");
        str = str.replace(/(\r\n|\n|\r)/gm," ");
        return str;
    }
    

    在你的 SP 中使用:

    try {
      // Try code
    } catch (err) {
      var obj = {};
      var res = [];
      obj["Error"] = "Exists";
      obj["Error Message"] = escapeString(err.message);
      obj["Status"] = escapeString(err.status);
      obj["Error Code"] = err.code;
      res.push(obj);
      var insert_into_data_log =
        "INSERT INTO DWH_OPS.DATA_LOAD_LOG select 'DATA LOAD PROCEDURE', current_timestamp(), " +
        "current_timestamp(), 0, " +
        "current_schema(), current_database(), current_user(), current_role(), " +
        "'SCRIPT ERROR', parse_json('" +
        JSON.stringify(res) +
        "')::VARIANT";
      var data_log_stmt = snowflake
        .createStatement({ sqlText: insert_into_data_log })
        .execute();
    
      return err;
    
    
    function escapeString(str){
        str = str.replace(/'/g, "''");
        str = str.replace(/\\/g, "\\\\");
        str = str.replace(/(\r\n|\n|\r)/gm," ");
        return str;
    }
    
    }
    

    【讨论】:

      【解决方案2】:

      你可以使用这个方法来转义单引号:

      obj["Error Message"] = obj["Error Message"].replace(/'/g, "\\''");
      

      这是一个简单的测试脚本:

      create table DATA_LOAD_LOG ( t timestamp, v variant );
      
      create or replace procedure test_sp()
      returns string  
      language javascript
      as
      $$
      var obj = {};
      var res = [];
      obj["Error"] = "Exists";
      obj["Error Message"] = "Can't parse 'n/a' as date with format 'YYYY-MM-DD'";
      
      obj["Error Message"] = obj["Error Message"].replace(/'/g, "\\''");
      obj["Error Code"] = 200;
      res.push(obj);
      
      var insert_into_data_log =
      "INSERT INTO DATA_LOAD_LOG select current_timestamp(), " +
      "parse_json('" + JSON.stringify(res) + "')::VARIANT";
      var data_log_stmt = snowflake.createStatement({ sqlText: insert_into_data_log }).execute();
       
      return "Ok";
      
      $$;
      
      call test_sp();
      

      【讨论】:

      • 这个替换在 Snowflake 脚本中的外观如何,新的 Snowflake 功能?
      猜你喜欢
      • 2019-10-14
      • 2021-08-09
      • 1970-01-01
      • 2022-01-18
      • 2020-07-29
      • 2021-04-11
      • 2015-10-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多