我在Snowflake中存储了一个示例程序,该程序一个接一个地执行以下步骤,
这里的问题是当给定的表名在数据库中不存在时,存储的过程以错误退出,但是它不更新带有错误详细信息的元数据,而元数据条目显示状态为“进行中”而存储的过程失败在第二点。
当数据库中不存在该表时,我正在寻找一个干净的出口,然后存储proc应该使用错误详细信息更新元数据并干净地退出。
有人可以看看下面的代码,并建议我是否在这里缺少什么。我是雪花和程序的新手。谢谢。
CREATE OR REPLACE PROCEDURE abc.PROC_GET_COUNT(table_name varchar)
RETURNS VARCHAR(16777216)
LANGUAGE JAVASCRIPT
EXECUTE AS OWNER
AS $$
// SQL Queries
var get_execution_id_sql = "select t.nextval from table(getnextval(EXECUTION_SEQUENCE)) t";
var get_count_sql = `select count(*) from abc.`+ TABLE_NAME +;
var result_set1 = snowflake.createStatement({sqlText: get_execution_id_sql}).execute();
result_set1.next();
var seq_num= result_set1.getColumnValue(1);
var insert_meta_sql1= `INSERT into abc.ERROR_LOG (EXECUTION_ID, STATUS, START_TS) values ( '` +seq_num+ `', 'In_Progress', CURRENT_TIMESTAMP)`;
try {
message = 'In insert Metadata with start details';
snowflake.execute({sqlText: insert_meta_sql1});
message = 'In Process of get count';
get_count_out = snowflake.execute ({sqlText: get_count_sql});
get_count_out.next();
rec_count = get_count_out.getColumnValue(1);
upd_meta_sql = `UPDATE abc.ERROR_LOG SET END_TS = current_timestamp, STATUS = 'SUCCESS', MESSAGE = '` + TABLE_NAME + ` - Total count: ` + rec_count + `' where EXECUTION_ID = '` + seq_num + `';
message = 'In update Metadata with end details';
snowflake.execute ({sqlText: upd_meta_sql});
} catch (err) {
upd_meta_sql = `UPDATE abc.ERROR_LOG SET
END_TS = current_timestamp,
STATUS = 'FAILED',
MESSAGE = '` + message + `. Error Details -- \n Code: `+ err.code +`\n State: `+ err.state +`\n Message: `+ err.message +`\n Stack Trace: `+ err.stackTraceTxt +`'
where EXECUTION_ID = '` + seq_num + `';
snowflake.execute ({sqlText: upd_meta_sql});
return "Failed: " + message + ' -- ' +err;
}
return 'SUCCESS';
$$;
答案 0 :(得分:0)
示例代码中有一些语法错误,但是我认为所有这些都是在您将脚本复制到此处时引起的。主要问题是err.message包含带有单引号字符的文本,从而破坏了最后一个SQL。
这是我的测试环境的脚本(如果您在询问需要调试的问题时与他人共享您的脚本,这将对其他人非常有帮助)
create schema abc;
create table deneme ( id number ) as select seq4()
from table(generator(rowcount=>100));
create or replace table ERROR_LOG (EXECUTION_ID number,
MESSAGE varchar, STATUS varchar, START_TS timestamp , END_TS timestamp);
create or replace sequence seq1;
这是该过程的固定版本:
CREATE OR REPLACE PROCEDURE abc.PROC_GET_COUNT(table_name varchar)
RETURNS VARCHAR(16777216)
LANGUAGE JAVASCRIPT
EXECUTE AS OWNER
AS $$
var get_execution_id_sql = "select t.nextval from table(getnextval(seq1)) t";
var get_count_sql = `select count(*) from abc.`+ TABLE_NAME ;
var result_set1 = snowflake.createStatement({sqlText: get_execution_id_sql}).execute();
result_set1.next();
var seq_num= result_set1.getColumnValue(1);
var insert_meta_sql1= `INSERT into abc.ERROR_LOG (EXECUTION_ID, STATUS, START_TS) values ( ` + seq_num + `, 'In_Progress', CURRENT_TIMESTAMP)`;
try {
message = 'In insert Metadata with start details';
snowflake.execute({sqlText: insert_meta_sql1});
message = 'In Process of get count';
get_count_out = snowflake.execute ({sqlText: get_count_sql});
get_count_out.next();
rec_count = get_count_out.getColumnValue(1);
upd_meta_sql = `UPDATE abc.ERROR_LOG SET END_TS = current_timestamp, STATUS = 'SUCCESS', MESSAGE = '` + TABLE_NAME + ` - Total count: ` + rec_count + `' where EXECUTION_ID = '` + seq_num +`'`;
message = 'In update Metadata with end details';
snowflake.execute ({sqlText: upd_meta_sql});
} catch (err) {
upd_meta_sql = `UPDATE abc.ERROR_LOG SET
END_TS = current_timestamp,
STATUS = 'FAILED',
MESSAGE = '` + message + `. Error Details -- \n Code: `+ err.code +`\n State: `+ err.state +`\n Message: `+ err.message.replace( /'/g , "''" ) +`\n Stack Trace: `+ err.stackTraceTxt +`'
where EXECUTION_ID = '` + seq_num + `'`;
snowflake.execute ({sqlText: upd_meta_sql});
return "Failed: " + message + ' -- ' +err;
}
return 'SUCCESS';
$$;
您可能会注意到,生成SQL时,我使用err.message.replace(/'/ g,“''”)代替err.message。
call PROC_GET_COUNT( 'deneme' ); -- succesful as the table exits
call PROC_GET_COUNT( 'deneme21' ); -- shows error
这是第二次尝试的消息列的内容:
In Process of get count. Error Details --
Code: 100183
State: P0000
Message: SQL compilation error:
Object 'GOKHAN_DB.ABC.DENEME21' does not exist or not authorized.
Stack Trace: At Snowflake.execute, line 20 position 30
答案 1 :(得分:0)
我认为问题与错误消息中返回的单引号有关。
我建议,设置消息变量。当您编写较短的代码时,它会更加神秘且更难找到问题。
通过将代码分解为更简单的步骤,您会发现问题更容易。
CREATE OR REPLACE SCHEMA abc;
USE SCHEMA ABC;
CREATE SEQUENCE IF NOT EXISTS EXECUTION_SEQUENCE
WITH
START WITH = 1
INCREMENT BY = 1
COMMENT = 'DEMO SEQUENCE ' ;
CREATE OR REPLACE TABLE abc.ERROR_LOG(EXECUTION_ID number , STATUS varchar, MESSAGE VARCHAR, START_TS timestamp_ltz , END_TS timestamp_ltz);
CREATE TABLE ABC.TEST_TABLE1(ID NUMBER, MESSAGE VARCHAR);
INSERT INTO ABC.TEST_TABLE1(ID, MESSAGE)
SELECT SEQ4() + 1 , RANDSTR(50, RANDOM())
FROM TABLE(GENERATOR(ROWCOUNT=>50));
SELECT * FROM ABC.TEST_TABLE1 ORDER BY 1 ASC;
CREATE OR REPLACE PROCEDURE abc.PROC_GET_COUNT(table_name varchar)
RETURNS VARCHAR(16777216)
LANGUAGE JAVASCRIPT
EXECUTE AS OWNER
AS $$
// SQL Queries
var get_execution_id_sql = "select t.nextval from table(getnextval(EXECUTION_SEQUENCE)) t";
var get_count_sql = `select count(*) from abc.`+ TABLE_NAME +`;`
var result_set1 = snowflake.createStatement({sqlText: get_execution_id_sql}).execute();
result_set1.next();
var seq_num= result_set1.getColumnValue(1);
var insert_meta_sql1= `INSERT into abc.ERROR_LOG (EXECUTION_ID, STATUS, START_TS,MESSAGE) values ( '` +seq_num+ `', 'In_Progress', CURRENT_TIMESTAMP(), '`+TABLE_NAME+`')`;
try {
message = 'In insert Metadata with start details';
snowflake.execute({sqlText: insert_meta_sql1});
message = 'In Process of get count';
get_count_out = snowflake.execute ({sqlText: get_count_sql});
get_count_out.next();
rec_count = get_count_out.getColumnValue(1);
upd_meta_sql = `UPDATE abc.ERROR_LOG SET END_TS = current_timestamp(), STATUS = 'SUCCESS', MESSAGE = '` + TABLE_NAME + ` - Total count: ` + rec_count + `' where EXECUTION_ID = ` + seq_num + `;`
message = 'In update Metadata with end details';
snowflake.execute ({sqlText: upd_meta_sql});
} catch (err) {
message = `Error Details\r\nCode: ` + err.code + `\r\nState:` + err.state +`\r\nMessage: ` + err.message + `\r\nStack Trace: ` + err.stackTraceTxt;
// **** you need to replace the single quotes that are being returned in your error message
message = message.replace(/'/g, `"`);
upd_meta_sql = `UPDATE abc.ERROR_LOG
SET END_TS = current_timestamp()
,STATUS = 'FAILED'
, MESSAGE = '` + message +`' where EXECUTION_ID = ` + seq_num + `;`
snowflake.execute ({sqlText: upd_meta_sql});
return "Failed: " + message + ' -- ' +err;
}
return 'SUCCESS';
$$;
CALL abc.PROC_GET_COUNT('TEST_TABLE1');
CALL abc.PROC_GET_COUNT('TEST_TABLE_MISSING');
SELECT * FROM abc.ERROR_LOG ORDER BY 1 ASC;
解决方案是here: