Transactions 与「;“尝试/抓住”;使用IBM Informix数据库中的回滚
我正在处理数据库。我希望在事务内部执行一些查询,如果出现错误,我希望回滚所有编辑,因此在SQL Server中与此相当的内容:Transactions 与「;“尝试/抓住”;使用IBM Informix数据库中的回滚,transactions,informix,Transactions,Informix,我正在处理数据库。我希望在事务内部执行一些查询,如果出现错误,我希望回滚所有编辑,因此在SQL Server中与此相当的内容: BEGIN TRY BEGIN TRAN -- insert, update, delete statements etc. COMMIT TRAN END TRY BEGIN CATCH IF(@@TRANCOUNT > 0) ROLLBACK TRAN; END CATCH 以下是: 当我搜索“info
BEGIN TRY
BEGIN TRAN
-- insert, update, delete statements etc.
COMMIT TRAN
END TRY
BEGIN CATCH
IF(@@TRANCOUNT > 0)
ROLLBACK TRAN;
END CATCH
以下是:
当我搜索“informix try catch”时,我得到的第一个链接是关于,但是,没有一个页面显示了关于如何捕获异常和回滚的完整语法示例,我在internet上的任何地方都找不到这样的示例。我尝试执行以下查询:
begin work;
create table test_abc
(
test_value int
);
on exception
rollback work;
end exception
commit work;
我的期望是,第一次这个查询可以工作,但第二次它会失败,因为表已经存在。然而,在我第一次遇到这个错误时:
begin work;
create table test_abc
(
test_value int
);
on exception
#^
# 201: A syntax error has occurred.
#
rollback work;
end exception
commit work;
所以这个语法是无效的
正确的语法是什么
编辑:关于我正在做什么的更多信息。我有一个新任务,我需要添加一些新表,并在其中的一些表中放入几行。即使可以在所有环境(test、prod等)上一次(或一个接一个)执行所有语句,我还是希望可以将所有语句打包到一个事务中,以避免在出现问题时需要清理。Jonathan Leffler建议创建存储过程,并使用异常上的
处理异常捕获,但我只需要使用一次事务,这并不保证创建存储过程。从技术上讲,我可以使用事务创建存储过程,运行它并删除它,但如果有一种方法可以避免创建存储过程,那么最好知道如何使用SPL(存储过程语言)处理异常。
既然有可能,我假设您正在存储过程中工作
您的示例是正确的,但是错误地放置了异常处理代码:
——问题中的错误代码
开始工作;
创建表test_abc
(
测试值int
);
例外
回滚工作;
结束例外
投入工作;
您需要在可能生成异常的代码之前指定异常处理。更接近正确的代码片段是:
CREATE PROCEDURE make_test_abc()
BEGIN WORK;
BEGIN
ON EXCEPTION
ROLLBACK WORK;
END EXCEPTION;
CREATE TABLE test_abc
(
test_value INT
);
COMMIT WORK;
END;
END PROCEDURE;
EXECUTE PROCEDURE make_test_abc();
上述注释适用于工程;多个类似的版本不起作用。SPL有时会变得非常棘手
我的库中还有一个“事务状态”函数,它在异常时使用:
CREATE PROCEDURE tx_state() RETURNING VARCHAR(14);
DEFINE errcode INTEGER;
ON EXCEPTION IN (-256, -535) SET errcode
IF errcode = -256 THEN
RETURN "TX-Unavailable";
ELIF errcode = -535 THEN
RETURN "In-TX";
END IF;
END EXCEPTION
BEGIN WORK;
ROLLBACK WORK;
RETURN "No-TX";
END PROCEDURE
现在,创建表练习还有其他机制:
DROP TABLE IF EXISTS test_abc;
CREATE TABLE IF NOT EXISTS test_abc(test_value INT);
创建和删除过程也有类似的选项:
DROP PROCEDURE IF EXISTS make_test_abc;
CREATE PROCEDURE IF NOT EXISTS make_test_abc()
…
END PROCEDURE;
CREATE OR REPLACE PROCEDURE make_test_abc()
…
END PROCEDURE;
这两个variantCREATE PROCEDURE
语句与Informix以外的不同DBMS兼容。“或替换”选项需要14.10版本(以及最新版本之一;我认为14.10.FC1中没有提供)。EXISTS选项在12.10中也可用(但同样,不一定在旧的12.10版本中)
当然,即使使用IF[NOT]EXISTS子句(或or REPLACE子句),如果您没有相关权限,操作也可能失败
但是,我假设这个问题比如何创建一个没有例外的表更一般。这应该会给你行动的指引。ON EXCEPTION子句在SPL(存储过程语言)中不可用,这意味着它只能在CREATE procedure(或CREATE FUNCTION)语句中使用
执行语句,失败时不提交
如果使用DB Access执行一系列命令,则可以使用以下大纲创建脚本(称为script.sql
):
BEGIN WORK;
CREATE …
DROP …
CREATE …
GRANT …
…
COMMIT WORK;
然后,您可以在批处理模式下运行它,并在环境中设置环境变量DBACCNOIGN
(DB Access“no ignore errors”)
$DBACCNOIGN=1 dbaccess yourdb脚本
…可讨论的输出-一些到标准输出,一些到标准错误…
$
语句成功时将有输出,但如果其中一个语句失败,脚本将停止并回滚事务。如果所有语句都成功,将执行提交工作并提交事务
还考虑检查SqLCMD(从中可用),我写的是在shell访问上下文中始终保持一致的行为,其中DB访问没有。它可以追溯到1986年(在出现
dbaccess
之前;在那些日子里,您使用的是isql
,而-DB访问是在一个晚上从isql
中分割出来的)。它与微软的johnny come Latesty程序没有任何关系,只是名称不同,并且具有相同的通用性(操作SQL数据库)。与DB Access不同,SQLCMD在出现错误时不会继续,除非您告诉它这样做(-c
命令行选项,或脚本文件中的继续;
)
$sqlcmd-d yourdb-f script.sql
$
与DB Access不同,SQLCMD不会有任何输出,除非您遇到错误,或选择某个内容,或使用-x
(跟踪)选项或-v
(详细)选项请求输出,或使用-B
请求基准测试(计时),或以其他方式请求输出。谢谢您的回答。你举的例子很有帮助。然而,我并不真正“需要”交易。我编辑了这个问题,并提供了更多细节。我只需要为所有环境中的新任务添加一些数据。它并不保证必须为此创建sp,但如果没有其他方法,它肯定是一个选项。“因为有可能出现异常,我假设您正在存储过程中工作。”。不,本来我不打算使用存储过程(但是在这个答案之后,我会考虑它,谢谢)。只是除了“on exception”语句之外,我找不到其他任何东西。当我搜索“informix try-catch”时,DDG和Google中的第一个链接是“on exception”,并且没有实际try/catch的迹象。我希望找到关于try/catch的文档(就像在SQLServer中一样),但没有找到。据我所知,现在尝试/捕获语法d
BEGIN WORK;
CREATE …
DROP …
CREATE …
GRANT …
…
COMMIT WORK;