Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server事务成功,Id错误_Sql_Sql Server_Transactions_Sql Server 2014 - Fatal编程技术网

SQL Server事务成功,Id错误

SQL Server事务成功,Id错误,sql,sql-server,transactions,sql-server-2014,Sql,Sql Server,Transactions,Sql Server 2014,我有一个简单的SQL语句来创建如下表: Create table tblAccountBalance ( Id int, AccountName nvarchar(200), Balance int ) insert into tblAccountBalance values (1, 'Mark', 1000); insert into tblAccountBalance values (2, 'Mary', 1000); begin try begin tr

我有一个简单的SQL语句来创建如下表:

Create table tblAccountBalance
(
    Id int,
    AccountName nvarchar(200),
    Balance int
)

insert into tblAccountBalance values (1, 'Mark', 1000);
insert into tblAccountBalance values (2, 'Mary', 1000);
begin try
    begin transaction   -- must have transaction keyword here!
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = 2

        commit transaction --or simply commit, but by default, it is commit WORK - thus you cannot specify transaction name, best is to put transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction --or simply rollback, but again, it might be similar to transaction, best is to put transaction keyword
    print 'Transaction is rolled back!'
end catch
begin try
    begin transaction
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = '24'    -- note the Id here is changed

        commit transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction
    print 'Transaction is rolled back!'
end catch
begin try
    begin transaction
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = 'A24'     -- note the Id here is changed

        commit transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction
    print 'Transaction is rolled back!'
end catch
导致

Id AccountName Balance
-----------------------
1  Mark        1000
2  Mary        1000
然后我创建一个如下的事务:

Create table tblAccountBalance
(
    Id int,
    AccountName nvarchar(200),
    Balance int
)

insert into tblAccountBalance values (1, 'Mark', 1000);
insert into tblAccountBalance values (2, 'Mary', 1000);
begin try
    begin transaction   -- must have transaction keyword here!
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = 2

        commit transaction --or simply commit, but by default, it is commit WORK - thus you cannot specify transaction name, best is to put transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction --or simply rollback, but again, it might be similar to transaction, best is to put transaction keyword
    print 'Transaction is rolled back!'
end catch
begin try
    begin transaction
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = '24'    -- note the Id here is changed

        commit transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction
    print 'Transaction is rolled back!'
end catch
begin try
    begin transaction
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = 'A24'     -- note the Id here is changed

        commit transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction
    print 'Transaction is rolled back!'
end catch
执行时,只需将100个单位的钱从Mark转移给Mary:

Id AccountName Balance
-----------------------
1  Mark        900
2  Mary        1100
现在,从上面的更新表继续,为了在事务中引入错误,我将事务更改为使第二个update语句具有
nvarchar
,Id如下:

Create table tblAccountBalance
(
    Id int,
    AccountName nvarchar(200),
    Balance int
)

insert into tblAccountBalance values (1, 'Mark', 1000);
insert into tblAccountBalance values (2, 'Mary', 1000);
begin try
    begin transaction   -- must have transaction keyword here!
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = 2

        commit transaction --or simply commit, but by default, it is commit WORK - thus you cannot specify transaction name, best is to put transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction --or simply rollback, but again, it might be similar to transaction, best is to put transaction keyword
    print 'Transaction is rolled back!'
end catch
begin try
    begin transaction
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = '24'    -- note the Id here is changed

        commit transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction
    print 'Transaction is rolled back!'
end catch
begin try
    begin transaction
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = 'A24'     -- note the Id here is changed

        commit transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction
    print 'Transaction is rolled back!'
end catch
令我惊讶的是,执行上述查询会导致:

(1 row(s) affected)
(0 row(s) affected)
Transaction successful!

Id  AccountName Balance
-----------------------
1   Mark        800
2   Mary        1100
这不是期望的结果

但是,如果我继续使用修改过的事务(同样,在第二个更新Id中)从上面不需要的更新表结果继续,如下所示:

Create table tblAccountBalance
(
    Id int,
    AccountName nvarchar(200),
    Balance int
)

insert into tblAccountBalance values (1, 'Mark', 1000);
insert into tblAccountBalance values (2, 'Mary', 1000);
begin try
    begin transaction   -- must have transaction keyword here!
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = 2

        commit transaction --or simply commit, but by default, it is commit WORK - thus you cannot specify transaction name, best is to put transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction --or simply rollback, but again, it might be similar to transaction, best is to put transaction keyword
    print 'Transaction is rolled back!'
end catch
begin try
    begin transaction
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = '24'    -- note the Id here is changed

        commit transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction
    print 'Transaction is rolled back!'
end catch
begin try
    begin transaction
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = 'A24'     -- note the Id here is changed

        commit transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction
    print 'Transaction is rolled back!'
end catch
这导致:

(1 row(s) affected)
(0 row(s) affected)
Transaction is rolled back!

Id  AccountName Balance
------------------------
1   Mark        800
2   Mary        1100
这是我想要的结果。第二笔交易怎么了?为什么更新仍在执行


如果有必要的话,我将使用SQL Server 2014。

这是因为您的第二个实验实际上是成功的,并且已经执行了。当存在比较两种不同数据类型的操作时,SQL Server将执行隐式转换。有关详细信息,请参阅。因此,您的
id='24'
转换为int类型,因此它最终变成
id=24
。因此,实验将从标记中扣除余额,并添加id为24的记录余额,但由于没有具有此id的记录,因此没有任何变化


在第三个实验中,隐式转换失败(无法将
A24
转换为整数类型),最终事务被回滚。

这是因为第二个实验实际成功并执行了。当存在比较两种不同数据类型的操作时,SQL Server将执行隐式转换。有关详细信息,请参阅。因此,您的
id='24'
转换为int类型,因此它最终变成
id=24
。因此,实验将从标记中扣除余额,并添加id为24的记录余额,但由于没有具有此id的记录,因此没有任何变化

update tblAccountBalance set Balance = Balance + 100 where Id = 'A24' --note the Id here is changed

在第三个实验中,隐式转换失败(无法将
A24
转换为整数类型),最终事务被回滚。

第二个事务成功,这就是为什么仍然执行
更新。您更改的
UPDATE
语句:

update tblAccountBalance set Balance = Balance + 100 where Id = '24' --note the Id here is changed
update tblAccountBalance set Balance = Balance + 100 where Id = 'A24' --note the Id here is changed
没有造成任何错误。它只是没有返回任何Id为'24'
的行,但没有错误

您的第三个事务导致了一个错误,这就是
更新被回滚的原因

update tblAccountBalance set Balance = Balance + 100 where Id = 'A24' --note the Id here is changed
上述操作将导致如下错误:

Create table tblAccountBalance
(
    Id int,
    AccountName nvarchar(200),
    Balance int
)

insert into tblAccountBalance values (1, 'Mark', 1000);
insert into tblAccountBalance values (2, 'Mary', 1000);
begin try
    begin transaction   -- must have transaction keyword here!
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = 2

        commit transaction --or simply commit, but by default, it is commit WORK - thus you cannot specify transaction name, best is to put transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction --or simply rollback, but again, it might be similar to transaction, best is to put transaction keyword
    print 'Transaction is rolled back!'
end catch
begin try
    begin transaction
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = '24'    -- note the Id here is changed

        commit transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction
    print 'Transaction is rolled back!'
end catch
begin try
    begin transaction
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = 'A24'     -- note the Id here is changed

        commit transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction
    print 'Transaction is rolled back!'
end catch
将varchar值“A24”转换为数据类型时,转换失败 内部的


由于您的
Id
INT
,SQL Server尝试将
A24
VARCHAR
转换为
INT
,但未能转换,因此出现错误。

您的第二个事务成功,这就是为什么
更新仍然执行的原因。您更改的
UPDATE
语句:

update tblAccountBalance set Balance = Balance + 100 where Id = '24' --note the Id here is changed
没有造成任何错误。它只是没有返回任何Id为'24'
的行,但没有错误

您的第三个事务导致了一个错误,这就是
更新被回滚的原因

update tblAccountBalance set Balance = Balance + 100 where Id = 'A24' --note the Id here is changed
上述操作将导致如下错误:

Create table tblAccountBalance
(
    Id int,
    AccountName nvarchar(200),
    Balance int
)

insert into tblAccountBalance values (1, 'Mark', 1000);
insert into tblAccountBalance values (2, 'Mary', 1000);
begin try
    begin transaction   -- must have transaction keyword here!
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = 2

        commit transaction --or simply commit, but by default, it is commit WORK - thus you cannot specify transaction name, best is to put transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction --or simply rollback, but again, it might be similar to transaction, best is to put transaction keyword
    print 'Transaction is rolled back!'
end catch
begin try
    begin transaction
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = '24'    -- note the Id here is changed

        commit transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction
    print 'Transaction is rolled back!'
end catch
begin try
    begin transaction
        update tblAccountBalance 
        set Balance = Balance - 100 
        where Id = 1

        update tblAccountBalance 
        set Balance = Balance + 100 
        where Id = 'A24'     -- note the Id here is changed

        commit transaction
        print 'Transaction successful!'
end try
begin catch
    rollback transaction
    print 'Transaction is rolled back!'
end catch
将varchar值“A24”转换为数据类型时,转换失败 内部的


由于您的
Id
INT
,SQL Server尝试将
A24
转换为
VARCHAR
,但未能转换为
INT
,因此出现了错误。

您的第二次实验成功,因为
nvarchar
可以隐式转换为
INT
。字符串
'24'
可以转换为
24
的整数值。请参阅。

您的第二个实验成功,因为
nvarchar
可以隐式转换为
int
。字符串
'24'
可以转换为
24
的整数值。看。

哦,天哪。。由于隐式转换,我弄错了。谢谢你的解释。哦,天哪。。由于隐式转换,我弄错了。谢谢你的解释。哦,天哪。。由于隐式转换,我弄错了。谢谢你的解释。谢谢你的回答。这与其他人相同,但您是第一个回答的人,并且引用了MSDN数据类型优先级。哦,我的。。由于隐式转换,我弄错了。谢谢你的解释。谢谢你的回答。这与其他人相同,但您是第一个回答的人,并且引用了MSDN数据类型优先级。哦,我的。。由于隐式转换,我弄错了。谢谢你的解释。哦,天哪。。由于隐式转换,我弄错了。谢谢你的解释。