繁体   English   中英

将 JSON object 传递给 Snowflake 中的存储过程

[英]Pass a JSON object to a stored procedure in Snowflake

我想调用 Snowflake 程序并传入 JSON object,但出现绑定错误。

/*
Function to insert one record into the database.

@param tableName : string = Name of table to insert into
@param record: object with the columns and their respective values. Expected format:

var record = {'severity': 'I',message:'TestMess\"\'age'};

In the above, column severity detected type string due to value 'I'
and message 'TestMess"'age', where the surrounding single quotes (')
will not be inserted.  

@return True if the insert success
*/
create or replace procedure sc_hub_insert(tableName varchar,record object)
    RETURNS boolean
    LANGUAGE javascript
    strict 
    execute as owner 
    as 
    $$
    var result = false;

    var columnNames=[];
    var quotedValues=[];
    var SINGLE_QUOTE_CHAR="'";
    var DOUBLE_QUOTE_CHAR="\"";
    var COMMA_CHAR=",";
    var LEFT_PARENTHESIS="(";
    var RIGHT_PARENTHESIS=")";
    var ESCAPED_SINGLE_QUOTE_CHAR="\\'";
    var ESCAPED_DOUBLE_QUOTE_CHAR="\\\"";
    for(var propertyName in record) {
        columnNames.push(propertyName);
        var recordValue=record[propertyName];
        var quotedValue=recordValue;
        if(typeof(recordValue)==='string') {
            var escapeStep1=recordValue.replace(SINGLE_QUOTE_CHAR,ESCAPED_SINGLE_QUOTE_CHAR);
            var escapeStep2=escapeStep1.replace(DOUBLE_QUOTE_CHAR,ESCAPED_DOUBLE_QUOTE_CHAR);
            quotedValue=SINGLE_QUOTE_CHAR+escapeStep2+SINGLE_QUOTE_CHAR;
        }
        quotedValues.push(quotedValue);
    }
    var sql_command = "insert into "+tableName+LEFT_PARENTHESIS+columnNames.join(",")+RIGHT_PARENTHESIS+
    " values "+LEFT_PARENTHESIS+quotedValues.join(",")+RIGHT_PARENTHESIS);

    try {
        snowflake.execute ({sqlText: sql_command});
        result = true;
    } catch(error) {
        result = false;
    }

    return result;
    $$
    ;

/*
Function to log message into SC_HUB_LOG_MESSAGES table

@param tableName : string = Name of table to insert into
@param record: object with the columns and their respective values. Expected format:

var record = {'severity': 'I',message:'TestMess\"\'age'};

In the above, column severity detected type string due to value 'I'
and message 'TestMess"'age', where the surrounding single quotes (')
will not be inserted.  

@return True if the insert success
*/
create or replace procedure sc_hub_log_message(severity varchar,message varchar)
    RETURNS varchar
    LANGUAGE javascript
    strict 
    execute as owner 
    as 
    $$
    var result = 'UNKNOWN';
    var record = {'severity': SEVERITY,message:MESSAGE};
    var SINGLE_QUOTE_CHAR="'";
    var DOUBLE_QUOTE_CHAR="\"";
    var COMMA_CHAR=",";
    var LEFT_PARENTHESIS="(";
    var RIGHT_PARENTHESIS=")";
    var ESCAPED_SINGLE_QUOTE_CHAR="\\'";
    var ESCAPED_DOUBLE_QUOTE_CHAR="\\\"";
    try {
        statement = snowflake.createStatement(
            {
            sqlText: "call SC_HUB_INSERT(?,?);",
            binds:['SC_HUB_LOG_MESSAGES',record]
            }
        );
        statementResult = statement.execute();
        statementResult.next();
        result = 'SUCCESS';
    } catch(error) {
        result = 'FAILURE: '+error;
    }

    return result;
    $$
    ;

当我使用以下语法调用下面的 sc_hub_log_message 例程时:

call sc_hub_log_message('I','***TestMessage');

我得到 1 FAILURE: Unsupported type for binding argument [object Object] 作为结果值。

从文档中,我假设 JSON object 的 DB 类型是 object,但我不确定。 I'm also not sure if I need to do any kind of JSON conversion, (ie. treat the object like a string then de-serialize it to a true JavaScript JSON object).

其次,鉴于显然没有console.log或服务器output(如Oracle)的概念,人们如何使用它?

如您所说,不支持 object 作为绑定变量,您需要进行一些 JSON 转换。 You can convert your JSON object to varchar when binding in sc_hub_log_message, and then you can convert back to JSON in your sc_hub_insert function.

我修复了一些语法错误,还包括从参数中读取的额外变量定义,并删除了注释以使其更短:

create or replace procedure sc_hub_insert(tableName varchar,record varchar)
    RETURNS boolean
    LANGUAGE javascript
    strict 
    execute as owner 
    as 
    $$
    var result = false;

    var columnNames=[];
    var quotedValues=[];
    var SINGLE_QUOTE_CHAR="'";
    var DOUBLE_QUOTE_CHAR="\"";
    var COMMA_CHAR=",";
    var LEFT_PARENTHESIS="(";
    var RIGHT_PARENTHESIS=")";
    var ESCAPED_SINGLE_QUOTE_CHAR="\\'";
    var ESCAPED_DOUBLE_QUOTE_CHAR="\\\"";
    var record = JSON.parse(RECORD)
    var tableName = TABLENAME;
    for(var propertyName in record) {
        columnNames.push(propertyName);
        var recordValue=record[propertyName];
        var quotedValue=recordValue;
        if(typeof(recordValue)==='string') {
            var escapeStep1=recordValue.replace(SINGLE_QUOTE_CHAR,ESCAPED_SINGLE_QUOTE_CHAR);
            var escapeStep2=escapeStep1.replace(DOUBLE_QUOTE_CHAR,ESCAPED_DOUBLE_QUOTE_CHAR);
            quotedValue=SINGLE_QUOTE_CHAR+escapeStep2+SINGLE_QUOTE_CHAR;
        }
        quotedValues.push(quotedValue);
    }
    var sql_command = "insert into "+tableName+LEFT_PARENTHESIS+columnNames.join(",")+RIGHT_PARENTHESIS+
    " values "+LEFT_PARENTHESIS+quotedValues.join(",")+RIGHT_PARENTHESIS;

    try {
        snowflake.execute ({sqlText: sql_command});
        result = true;
    } catch(error) {
        result = false;
    }

    return result;
    $$
    ;



create or replace procedure sc_hub_log_message(severity varchar,message varchar)
    RETURNS varchar
    LANGUAGE javascript
    strict 
    execute as owner 
    as 
    $$
    var result = 'UNKNOWN';
    var record = {'severity': SEVERITY,message:MESSAGE};
    var SINGLE_QUOTE_CHAR="'";
    var DOUBLE_QUOTE_CHAR="\"";
    var COMMA_CHAR=",";
    var LEFT_PARENTHESIS="(";
    var RIGHT_PARENTHESIS=")";
    var ESCAPED_SINGLE_QUOTE_CHAR="\\'";
    var ESCAPED_DOUBLE_QUOTE_CHAR="\\\"";
    try {
        statement = snowflake.createStatement(
            {
            sqlText: "call SC_HUB_INSERT(?,?);",
            binds:['SC_HUB_LOG_MESSAGES',JSON.stringify(record) ]
            }
        );
        statementResult = statement.execute();
        statementResult.next();
        result = 'SUCCESS';
    } catch(error) {
        result = 'FAILURE: '+error;
    }

    return result;
    $$
    ;

您说得对,可能会有更好的“日志记录”功能,也许您可以将此想法发布到 Snowflake 想法:

https://community.snowflake.com/s/ideas

要获取详细错误,请使用它在 catch 块中记录错误日志

               catch(err)
   {
       var result_set= "";
        result_set =  "Failed: Code: " + err.code + " State: " + err.state + " Message: " + err.message +" Stack Trace:" + err.stackTraceTxt;

--返回结果集; --- 或登录表 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM