SqlSever中事务的使用

   了解SqlServer2000的事务很久了,不过一直没有真正用过,前段时间做库存管理系统时终于敢用了。我的代码大致是这样的:

CREATE   PROCEDURE  InsertData
AS
BEGIN   TRANSACTION

INSERT   INTO  A  VALUES  ( '' , '' ) -- 语句1
INSERT   INTO  B  VALUES  ( '' , '' ) -- 语句2 

IF   @@ROWCOUNT   >   0
 
COMMIT   TRANSACTION
ELSE
 
ROLLBACK   TRANSACTION


刚开始我还挺乐的,代码如此简单又好看,可是晚上睡觉的时候,大家讨论的时候我才觉得有个问题没有考虑,下面看看联机丛书:

@@ROWCOUNT
返回受上一语句影响的行数。

语法
@@ROWCOUNT

返回类型
integer

注释
任何不返回行的语句将这一变量设置为 0 ,如 IF 语句。


本来我用事务的目的就是让语句1和语句2同事执行成功,如果有一个失败,整个事务就回滚。问题在于:IF @@ROWCOUNT > 0 能判断两个语句
都执行成功了吗?   答案是不能的。  如果语句1失败了,语句2执行成功了,那么系统变量@@ROWCOUNT的值仍然是大于0的。所以这个事务是没有什么
意义的。

严格的代码如下:

CREATE   PROCEDURE  InsertData
AS

BEGIN   TRANSACTION
 
INSERT   INTO  A  VALUES  ( '' , '' ) -- 语句1

IF   @@ERROR <> 0  
 
BEGIN
  
ROLLBACK   TRANSACTION
  
RETURN
 
END

INSERT   INTO  B  VALUES  ( '' , '' ) -- 语句2

IF   @@ERROR <> 0  
 
BEGIN
  
ROLLBACK   TRANSACTION
  
RETURN
 
END

COMMIT   TRANSACTION

 下面看看联机丛书中对@@Error的解释:

@@ERROR
返回最后执行的 Transact-SQL 语句的错误代码。

语法
@@ERROR

返回类型
integer

注释
当 Microsoft SQL Server 完成 Transact-SQL 语句的执行时,如果语句执行成功,则 @@ERROR 设置为 0。若出现一个错误,则返回一条错误信息。@@ERROR 返回此错误信息代码

,直到另一条 Transact-SQL 语句被执行。您可以在 sysmessages 系统表中查看与 @@ERROR 错误代码相关的文本信息。

由于 @@ERROR 在每一条语句执行后被清除并且重置,应在语句验证后立即检查它,或将其保存到一个局部变量中以备事后查看。

  下面的这个例子可以更好的帮助我们学会事务的使用:

USE  Pubs
GO
DECLARE   @del_error   int , @ins_error   int
-- 开始事务
BEGIN   TRAN
-- 执行删除命令
DELETE  authors  WHERE  au_id = 409 - 56 - 16088
-- 捕获执行完删除操作后的@@ERROR变量的值
SELECT   @del_error = @@ERROR
-- 执行插入操作
INSERT  authors  VALUES (“ 409 - 56 - 16088 ”,”Bennet”,”Abraham”,” 416   658 - 9932 ”,” 6223  Bateman ST.”,“Berkeley”,”CA”,” 941605 ”, 1 )
-- 捕获执行完插入操作后的@@ERROR变量的值
SELECT   @ins_error = @@ERROR
-- 测试捕获到的@@ERROR的值
IF   @del_error = 0   AND    @ins_error = 0
    
BEGIN
        
-- 成功执行确定事务的操作
         PRINT  “The author information has been replaced”
        
COMMIT   TRAN
    
END
ELSE

BEGIN
    
-- 有错误发生,检查究竟是哪个语句有问题
     -- 然后回滚整个事务
     IF   @del_error <> 0
        
Print  “An error occurred during execution  of  the  DELETE  statement.”
    
IF   @ins_error <> 0
        
Print  “An error occurred during execution  of  the INSRET statement.”
    
ROLLBACK   TRAN
END
GO

 

你可能感兴趣的:(sql)