调用存储过程抛出错误时如何使任务失败
Posted
技术标签:
【中文标题】调用存储过程抛出错误时如何使任务失败【英文标题】:How to make the task fail when the calling stored procedure throws an error 【发布时间】:2021-09-07 16:33:16 【问题描述】:我有一个存储过程从任务调用的阶段插入数据。如果加载失败(由于 on_error=skip_file 选项),它会抛出一个错误并被处理。但任务的状态显示为成功。存储过程出错时如何使任务失败。 这是示例代码
create or replace procedure sample_procedure()
returns varchar not null
language javascript
execute as caller
as
$$
try
try
var ct_table_cmd = `create or replace table sample_table_temp like sample_table`;
var ct_table_stmt = snowflake.createStatement(sqlText: ct_table_cmd);
var result_set= ct_table_stmt.execute();
result_set.next();
catch(err)
var queryId = ct_table_stmt.getQueryId();
var queryText = ct_table_stmt.getSqlText();
var log_insert_into=snowflake.createStatement(sqlText:`insert into error_table
(code, message, queryid, querytext) VALUES (?,?,?,?);`
,binds : [err.code, err.message,queryId,queryText]
);
log_insert_into.execute();
var ct_task_ret_value = snowflake.createStatement(sqlText: `call system$set_return_value('err.message');`).execute();
return err.message;
var copy_cmd = `copy into smaple_table_temp from @mystage
file_format=(format_name= 'sample_csv_format')
files=('/file_name')
on_error=skip_file;`;
var copy_cmd_stmt = snowflake.createStatement(sqlText:copy_cmd);
var result_set =copy_cmd_stmt.execute();
result_set.next();
if(result_set.getColumnValue(2)=='LOADED')
var swap_cmd = `alter table sample_table_temp swap with sample_table;`;
var swap_stmt = snowflake.createStatement(sqlText: swap_cmd);
swap_stmt.execute();
else if (result_set.getColumnValue(2)== 'LOAD_FAILED')
var err_message= result_set.getColumnValue(7);
var queryId = copy_cmd_stmt.getQueryId();
var queryText = copy_cmd_stmt.getSqlText();
var log_insert_into=snowflake.createStatement(sqlText:`insert into error_table
(code, message, queryid, querytext) VALUES (?,?,?,?);`
,binds : [err.code, err.message,queryId,queryText]
);
var task_ret_value = snowflake.createStatement(sqlText: `call system$set_return_value('err_message');`).execute();
log_insert_into.execute();
return err_message
$$
;
调用过程的错误日志表和任务是:
create or replace table error_table (ts timestamp_ntz, src varchar(50),code varhcar(100) ,
message varchar, queryid varchar, querytext varhcar);
创建或替换任务示例任务 仓库 = '我的仓库' 时间表='10分钟' 作为 调用 sample_procedure();
当任务调用该位置中没有数据的过程时,它会在任务历史记录中抛出一个错误,如“存储过程示例过程中的执行错误:
SQL 编译错误: 位置 47 的语法错误行意外“远程”。在 statement.execute,第 172 行位置 111”。但实际错误是“远程文件不存在。有几个潜在的原因。该文件可能不存在。所需的凭据可能丢失或无效。"
当表不存在时,信息模式的task_history中显示的错误不同。它没有显示独立调用过程时显示的错误(即调用 sample_procdure())。
任何建议都有帮助。
【问题讨论】:
【参考方案1】:您在此处设置任务的返回值:
var ct_task_ret_value = snowflake.createStatement(sqlText: `call system$set_return_value('err.message');`).execute();
您在此处设置存储过程的返回值:
return err.message;
问题是err.message
是一个包含错误消息文本的字符串,它不是错误指示。您已经发现了错误,就 Snowflake 而言,它已得到处理。
要在 SP 执行时指示错误,您可以 1) 不捕获错误或 2) 捕获错误、处理它并抛出错误。
选项 2 似乎是您想要做的。像您已经在做的那样捕获错误,但不要返回err.message
,而是这样做:
//return err.message;
throw err.message;
Snowflake 将使用自己的错误文本包装错误消息。目前没有办法避免这种情况,因此您可能需要在文本中做一些事情来引起对错误文本的注意,例如 *wrapping in stars* 或类似的东西。 Snowflake Stored Procedure Exception & Failure
【讨论】:
name: @Greg 使用 throw err.message 时,它显示为未捕获的错误,但将错误记录到日志表中,但是当使用 return err.message 时,它给出了实际错误。如何处理?以上是关于调用存储过程抛出错误时如何使任务失败的主要内容,如果未能解决你的问题,请参考以下文章
Postgresql 11:存储过程调用错误 - 要调用过程,请使用 CALL、Java