[英]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 想法:
要获取详细错误,请使用它在 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.