如何防止未来的批次完成时出错并回滚?
如果我有以下 SQL 查询
CREATE TABLE #t1
(a INT NOT NULL PRIMARY KEY);
SET XACT_ABORT ON
go
BEGIN TRANSACTION
INSERT INTO #t1 VALUES (1);
INSERT INTO #t1 VALUES (2);
INSERT INTO #t1 VALUES (3);
INSERT INTO #t1 VALUES (2); -- PK violation error
go
INSERT INTO #t1 VALUES (4);
go
COMMIT TRANSACTION
SET XACT_ABORT OFF
当我运行查询时我得到这个输出
(1 行受影响)
(1 行受影响)
(1 行受影响)消息 2627,级别 14,状态 1,第 7 行 主键约束“PK_#t1______66D536B1”。无法插入 对象“dbo.#t1”中的重复键。
(1 行受影响)消息 102,级别 15,状态 1,第 8 行不正确 '#t1' 附近的语法。
#t1 的值是
a
-----------
4
我需要做什么才能使脚本中止并且不运行第二批?
编辑:
尝试了 JNK 的解决方案
begin try
BEGIN TRANSACTION
INSERT INTO #t1 VALUES (1)
INSERT INTO #t1 VALUES (2)
INSERT INTO #t1 VALUES (3)
INSERT INTO #t1 VALUES (2) -- PK violation error
go
INSERT INTO #t1 VALUES (4)
go
COMMIT TRANSACTION
end try
begin catch
IF @@trancount > 0 Rollback
END catch
select * from #t1
truncate table #t1
但是我得到了这个输出
Msg 102, Level 15, State 1, Line 6
Incorrect syntax near ')'.
(1 row(s) affected)
Msg 102, Level 15, State 1, Line 5
Incorrect syntax near 'begin'.
Msg 102, Level 15, State 1, Line 8
Incorrect syntax near 'END'.
并且该表仍然包含 4 之后
EDIT2:
try catch 的错误是因为 GO 语句,我需要将其用于我的真实脚本这个测试用例。所以看来 try/catch 不适用于这种情况。
If I have the following SQL query
CREATE TABLE #t1
(a INT NOT NULL PRIMARY KEY);
SET XACT_ABORT ON
go
BEGIN TRANSACTION
INSERT INTO #t1 VALUES (1);
INSERT INTO #t1 VALUES (2);
INSERT INTO #t1 VALUES (3);
INSERT INTO #t1 VALUES (2); -- PK violation error
go
INSERT INTO #t1 VALUES (4);
go
COMMIT TRANSACTION
SET XACT_ABORT OFF
When I run the query I get this output
(1 row(s) affected)
(1 row(s) affected)
(1 row(s) affected) Msg 2627, Level 14, State 1, Line 7 Violation of
PRIMARY KEY constraint 'PK_#t1______66D536B1'. Cannot insert
duplicate key in object 'dbo.#t1'.(1 row(s) affected) Msg 102, Level 15, State 1, Line 8 Incorrect
syntax near '#t1'.
And the value of #t1 is
a
-----------
4
What do I need to do so the script will abort out and not run the second batch?
EDIT:
Tried JNK's solution
begin try
BEGIN TRANSACTION
INSERT INTO #t1 VALUES (1)
INSERT INTO #t1 VALUES (2)
INSERT INTO #t1 VALUES (3)
INSERT INTO #t1 VALUES (2) -- PK violation error
go
INSERT INTO #t1 VALUES (4)
go
COMMIT TRANSACTION
end try
begin catch
IF @@trancount > 0 Rollback
END catch
select * from #t1
truncate table #t1
However I get this output
Msg 102, Level 15, State 1, Line 6
Incorrect syntax near ')'.
(1 row(s) affected)
Msg 102, Level 15, State 1, Line 5
Incorrect syntax near 'begin'.
Msg 102, Level 15, State 1, Line 8
Incorrect syntax near 'END'.
And the table still contains a 4 afterward
EDIT2:
the errors with the try catch is because of the GO statement, which I need to have for my real script instead of this test case. so it appears try/catch will not work for this case.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
添加错误处理:
ROLLBACK
是可选的,它将撤消在错误发生之前完成的任何插入。您还可以添加多个事务,因此,如果说前 3 个插入稍后与其他一些内容无关,请将它们包装在一个事务中并提交它,然后再为不相关的过程创建另一个事务。Add error handling:
The
ROLLBACK
is optional and will undo any inserts that completed before the error occured. You can also add multiple transactions, so if say the first 3 inserts are independent of some other stuff later on, wrap those in a transaction and commit it, then have another tran later on for the unrelated process.来自 MSDN:
”
将 GO 解释为应将当前批次的 Transact-SQL 语句发送到 SQL Server 实例的信号。当前批次的语句由自上次 GO 以来输入的所有语句组成,或者自临时会话或脚本开始(如果这是第一个 GO)以来输入的所有语句组成。
Transact-SQL 语句不能与 GO 命令占用同一行。但是,该行可以包含注释。
”
From MSDN:
"
interpret GO as a signal that they should send the current batch of Transact-SQL statements to an instance of SQL Server. The current batch of statements is composed of all statements entered since the last GO, or since the start of the ad hoc session or script if this is the first GO.
A Transact-SQL statement cannot occupy the same line as a GO command. However, the line can contain comments.
"