我们有一个客户端应用程序在SQL Server 2005上运行一些SQL,如下所示:
BEGIN TRAN;
INSERT INTO myTable (myColumns ...) VALUES (myValues ...);
INSERT INTO myTable (myColumns ...) VALUES (myValues ...);
INSERT INTO myTable (myColumns ...) VALUES (myValues ...);
COMMIT TRAN;
Run Code Online (Sandbox Code Playgroud)
它由一个长字符串命令发送.
如果其中一个插入失败,或者命令的任何部分失败,SQL Server是否会回滚事务?如果它没有回滚,我是否必须发送第二个命令才能回滚?
我可以给出关于我正在使用的api和语言的细节,但我认为SQL Server应该对任何语言做出相同的响应.
它们会立即回滚吗?它们会在一段时间后回滚吗?他们是否处于未承诺状态?
如果使用连接池并且只是重置连接,行为是否相同?
我发现SQL存储过程非常有趣和有用.我已经编写了存储过程,但我想为任何类型的要求编写精心设计,性能良好的调优和简洁的SP,并且也希望了解存储过程的任何技巧或良好实践.如何在编写存储过程时从初学者升级到高级阶段?
更新:从评论中发现我的问题应该更加具体.每个人都有一些技巧,我期待他们在他们的代码中使用SP的技巧和做法,使他们与其他人区别开来,更重要的是提高写作和使用存储过程的工作效率.
在Dan Guzman的博客上阅读这篇文章,我想知道:为什么不是SET XACT_ABORT ON默认行为?是否有一个地方是有害的,或案件多比不太理想/效率SET XACT_ABORT OFF?
我从未理解嵌套事务的好处.提交嵌套事务不会提交任何内容 - 它只会减少@@TRANCOUNT.并ROLLBACK回滚一切.
BEGIN TRANSACTION
//do an update
BEGIN TRANSACTION
//do an insert
COMMIT TRANSACTION
COMMIT TRANSACTION
Run Code Online (Sandbox Code Playgroud)
与此有什么不同:
BEGIN TRANSACTION
//do an update
//do an insert
COMMIT TRANSACTION
Run Code Online (Sandbox Code Playgroud)
请举例说明为什么要使用嵌套事务以及它们如何产生影响.
问候,Petar
我们目前正在使用SQL 2005,我正在将旧的Foxpro系统迁移到由SQL Server支持的新Web应用程序.我在T-SQL中使用TRY CATCH进行事务处理,它似乎工作得很好.工作中的其他程序员之一担心这一点,因为他说他听说过一些问题,其中的口号并不总能发现错误.我已经击败了sproc to death并且无法让它失败(错过捕获)并且我在网上搜索的唯一问题是它不会返回错误编号<5000的正确错误编号.有没有人经历任何其他在T-SQL中使用TRY CATCH的问题 - 特别是如果它错过了捕获?感谢您提供的任何输入.
我正在使用SQL Server 2008,当我在Management studio中运行此Statement时,Catch Block中的Select语句按预期执行
BEGIN TRY
INSERT INTO IDontExist(ProductID)
VALUES(1)
END TRY
BEGIN CATCH
SELECT 'There was an error! ' + ERROR_MESSAGE()
END CATCH
Run Code Online (Sandbox Code Playgroud)
但是,当我运行此语句时,Catch Block中的语句永远不会执行,而错误只显示在结果选项卡中
BEGIN TRY
Select * from IDontExist
END TRY
BEGIN CATCH
SELECT 'There was an error! ' + ERROR_MESSAGE()
END CATCH
Run Code Online (Sandbox Code Playgroud)
它们都返回相同的错误号'208''无效的对象名称:IDontExist'那么为什么要处理它而另一个不处理?
根据联机丛书文档SET XACT_ABORT ON,我得到的印象是,如果T-SQL语句引发运行时错误,整个事务将终止并回滚:
备注
当SET XACT_ABORT为ON时,如果Transact-SQL语句引发运行时错误,则终止并回滚整个事务.
在SQL Server 2008 R2中测试:
SET XACT_ABORT ON;
BEGIN TRANSACTION;
PRINT 'TranCount befor an error = '+CAST(@@Trancount AS varchar(50))
DROP TABLE QuertyAsdf
PRINT 'TranCount after an error = '+CAST(@@Trancount AS varchar(50))
Run Code Online (Sandbox Code Playgroud)
给出输出:
TranCount befor an error = 1
Msg 3701, Level 11, State 5, Line 6
Cannot drop the table 'QwertyAsdf', because it does not exist or you do not have permission.
TranCount after an error = 1
Run Code Online (Sandbox Code Playgroud)
如果我使用SqlCommand运行存储过程并且SqlCommand超时,StoredProc会继续执行还是在SqlCommand断开连接时强行退出?
如何以某种方式编写该过程,以便每当其中的任何语句出错时我都可以ROLLBACK所有INSERT,UPDATE和DELETE语句.
请注意,我的程序可能会也可能不会按顺序列出语句.换句话说,我有一个INSERT语句,然后是一些IF逻辑,然后是一个select语句,然后是另一个INSERT,然后是UPDATE,然后是逻辑然后是DELETE语句等.
我只想在任何语句发生错误时ROLLBACK所有INSERT,UPDATE和DELETE语句.我找到了这段代码http://msdn.microsoft.com/en-us/library/ms181299.aspx 和 http://en.allexperts.com/q/MS-SQL-Server-1801/Rollback-SP.htm
但他们没有回答我的问题.
我正在尝试改进当前系统的错误处理,以产生更有意义的错误消息。我有一个“根”存储过程,该存储过程对其他嵌套存储过程进行了多次调用。
在根sp中,XACT_ABORT将其设置为,ON但在嵌套过程中,XACT_ABORT将其设置为OFF。我想从较低级别的过程中捕获特定的错误,而不是获取根过程的错误。
我经常看到错误, uncommittable transaction is detected at the end of the batch, the transaction is being rolled back.
将这些“混合”环境与XACT_ABORTs?
另外,如果您对高级错误处理有任何建议,将不胜感激。我想我想使用它,sp_executesql这样我就可以传递参数来获取错误输出,而不必修改所有存储过程并用于RAISERROR调用父过程的CATCH块。
我想SET XACT_ABORT ON在事务中设置SQL Server 2008R2存储过程,所以在创建脚本中这样做:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET XACT_ABORT ON
GO
CREATE PROCEDURE MyProc
AS
BEGIN TRAN
...
IF @@ERROR <> 0
BEGIN
GOTO Done
END
...
IF @@ERROR <> 0
BEGIN
GOTO Done
END
COMMIT TRAN
Done:
IF @@ERROR <> 0
BEGIN
ROLLBACK TRAN
END
GO
Run Code Online (Sandbox Code Playgroud)
成功创建后,我通过单击"修改"存储过程选项检查事务,并在生成的ALTER PROCEDURE脚本中看不到SET XACT_ABORT ON行:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE MyProc
AS
BEGIN TRAN
...
Run Code Online (Sandbox Code Playgroud)
我错在哪里或者诀窍是什么?如何正确定义SET …
t-sql sql-server stored-procedures transactions sql-server-2008
我试图使用第一个表中的主键一次插入两个表以插入第二个表,但我不知道如何进行。
我的表结构如下:
人
PersonId
FirstName
Surname
Run Code Online (Sandbox Code Playgroud)
员工
EmployeeId
HoursWorked
Run Code Online (Sandbox Code Playgroud)
PersonId表中Person是一个自动递增的列。EmployeeId第二个表中的主键和外键应与 相同PersonId。
我一直在尝试使用在谷歌上找到的这个查询字符串,但运气不佳:
string queryString = "BEGIN TRANSACTION DECLARE @DataID int; "
+"INSERT INTO Person(FirstName, Surname) VALUES(@firstName, @surname);"
+ "SELECT @DataID = scope_identity();"
+ "INSERT INTO Employee VALUES(@DataId, @hoursWorked);"
+ "COMMIT";
Run Code Online (Sandbox Code Playgroud) sql-server ×12
sql ×5
transactions ×5
t-sql ×4
xact-abort ×2
c# ×1
database ×1
sql-insert ×1
sqlcommand ×1
timeout ×1
try-catch ×1