我已经使用雪花一段时间了,但实际上还没有使用涉及事务的存储过程,我有使用流的要求,一个这样的情况是涉及一些业务逻辑要放入带有条件事务的 sp 中回滚。我已经写了一个这样的程序,但到目前为止还没有成功回滚。
这是我想要实现的伪代码:
CREATE OR REPLACE PROCEDURE TEST_SP(STREAM_NAME varchar,RECORD_ID_KEY varchar)
RETURNS VARCHAR
LANGUAGE javascript
AS
$$
var source_table_row1 = `SELECT RECORD_CONTENT::string from ${STREAM_NAME} limit 1;`;
var statement1 = snowflake.createStatement({sqlText:source_table_row1});
var raw_json='';
try
{
var result_set1=statement1.execute();
while (result_set1.next())
{
raw_json = result_set1.getColumnValue(1);
}
} catch(err)
{
var result = "Failed: Code: " + err.code + "\n State: " + err.state;
result += "\n Message: " + err.message;
return "detailed error is:"+result;
}
snowflake.execute({sqlText:"begin transaction"});
if(raw_json)
{
try
{
//run DDL & DML statmetents
var result_set2=snowflake.createStatement({sqlText:"DDL STMT"}).execute();
var rs=snowflake.createStatement({sqlText: "DML STMT"}).execute();
var rs2=snowflake.createStatement({sqlText: "FINAL DML STMT"}).execute();
}catch(err){
snowflake.execute ({sqlText: "rollback"});
var errorMessage= "Failed: Code: " + err.code + "\n State: " + err.state;
errorMessage += "\n Message: " + err.message+" with net_status="+net_status;
return errorMessage;
}
}
else
{
snowflake.execute({sqlText: "rollback"});
return "no data present in source table";
}
snowflake.execute({sqlText:"rollback"});
return "successfully completed "
$$;
这里的问题是,如果一切顺利,我可以看到 sp 执行所需的操作,但对于查询失败的情况(例如,尝试复制不存在的表单表)。 ,代码进入 catch 块,存储过程完成,但我看不到任何回滚活动的结果。 有人能告诉我我在这里错过了什么。 谢谢。
答案 0 :(得分:2)
问题是事务中的 DDL 代码:
snowflake.execute({sqlText:"begin transaction"});
...
//run DDL & DML statmetents
var result_set2=snowflake.createStatement({sqlText:"DDL STMT"}).execute(); -- here
var rs=snowflake.createStatement({sqlText: "DML STMT"}).execute();
var rs2=snowflake.createStatement({sqlText: "FINAL DML STMT"}).execute();
...
snowflake.execute ({sqlText: "rollback"});
<块引用>
显式事务应仅包含 DML 语句和查询语句。 DDL 语句隐式提交活动事务(有关详细信息,请参阅 DDL 部分)。
DDL
每个 DDL 语句都作为单独的事务执行。
如果在事务处于活动状态时执行 DDL 语句,则 DDL 语句:
隐式提交活动事务。
将 DDL 语句作为单独的事务执行。
因为 DDL 语句是它自己的事务,所以不能回滚 DDL 语句;包含 DDL 的事务在您可以执行显式 ROLLBACK 之前完成。