触发器更新引发的异常'无法为更新行集定位:一些值可能已在最后读取后改变', 该怎么修改触发...
来源:百度文库 编辑:神马文学网 时间:2024/06/13 14:00:57
有两个表, 报价单, 订单表, 报价单有一个bit字段 <是否接单> 记录本报价单是否接到订单;订单表中有一个字段 <对应报价单号> 记录本订单对应报价单号.
在删除订单时需要修改对应报价单的是否接单字段.
在订单表中定义如下触发器:
CREATE TRIGGER tg_订单_Del ON [dbo].[订单]
for DELETE
AS
update 报价表
set 是否接单=0
where 报价单号=
(select 对应报价单号
from deleted)
GO
在订单有报价单对应时运行正常.
但当订单没有对应的报价单时(直接下的订单,或对应报价单已经被删除). 将出现 '无法为更新行集定位:一些值可能已在最后读取后改变 '的异常, 我是使用事务进行更新的.
在问专家上看到的回答是:
由于所修改的记录与数据库所存在的记录冲突,导致更改失败(如其他用户已将记录删除),如果没有触发器,其实程序发生警告信息给Errors集合,但不终止程序运行,也不会出实时错误提示。如果你加上触发器,你所进行批更新包括从Deleted表中记录,即所有删除的记录,所有的更新请求都不存在(或已被其它用户删除),所以出现实时运行错误。
对于我的情况, select 对应报价单号 from deleted 将是NULL值, 但这并不影响Update语句的执行啊??
请高手解疑!
CREATE TRIGGER tg_订单_Del ON [dbo].[订单]
for DELETE
AS
if exists (select * from deleted)
update 报价表
set 是否接单=0
where 报价单号=
(select 对应报价单号
from deleted)
GO
update a set a.是否接单=0 from 报价表 a, deleted b where a.报价单号=b.对应报价单号
在我的应用中使用触发器更好
不知道为什么?
其他的还不知道;
就樓主的這條語句來講后面用等號與(select 对应报价单号 from deleted)相連就不委.因為后面查到的一個集合.改成update 报价表 set 是否接单=0 where 报价单号 in (select 对应报价单号 from deleted)好些,當然對一條記錄可以.如果是多條記錄就會產生數據混亂.
至於為什麼會產生樓主所說的問題.樓主為什麼不走另一條路呢.
你有說過訂單有對應報價單時不會錯.那麼我定義一個 變量取得當前訂單的報價單號.不就行了嗎.如下:
CREATE TRIGGER tg_订单_Del ON [dbo].[订单]
for DELETE
AS
declare @報價單號 int
select @報價單號=報價單號 from deleted
if @報價單號 is not null or @報價單號 <> ' ' --條件根據樓主自行定義
update 报价表 set 是否接单=0 where 报价单号= (select 对应报价单号 from deleted)
GO
--上面只是針對單條記錄.如果是多條記錄同時進行.最好還是用游標.
--以上意見僅供參考
CREATE TRIGGER tg_订单_Del ON [dbo].[订单]
for DELETE
AS
if exists (select * from deleted)
update 报价表
set 是否接单=0
where 报价单号=
(select 对应报价单号
from deleted)
GO
使用照样出错, 但是如果在if内加上一个select语句便可以了
if exists (select * from deleted)
select '执行到这 '
update 报价表
set 是否接单=0
where 报价单号=
(select 对应报价单号
from deleted)
猜想:MSSQL事务检测触发器是否成功执行是根据判断返回值的, 如果没有对应的报价单,那么触发器内的update语句的影响行是0, 而有对应的报价单, 触发器内的update影响行是1. 这就导致了有对应报价单时删除可以成功执行,没有时事务会回滚.
另外 这条语句if exists (select * from deleted) 总是为真的.
把它改为:if exists (select 对应报价单号 from deleted) ,而订单中这个字段为空,但语句结果还是为真, 不知道是为什么?
CREATE TRIGGER tg_订单_Del ON [dbo].[订单]
for DELETE
AS
--if exists (select 对应报价单号 from deleted)
--begin
select 对应报价单号 from deleted
--select '存在 '
update 报价表
set 是否接单=0
where 报价单号=
(select 对应报价单号
from deleted)
--end
在删除订单时需要修改对应报价单的是否接单字段.
在订单表中定义如下触发器:
CREATE TRIGGER tg_订单_Del ON [dbo].[订单]
for DELETE
AS
update 报价表
set 是否接单=0
where 报价单号=
(select 对应报价单号
from deleted)
GO
在订单有报价单对应时运行正常.
但当订单没有对应的报价单时(直接下的订单,或对应报价单已经被删除). 将出现 '无法为更新行集定位:一些值可能已在最后读取后改变 '的异常, 我是使用事务进行更新的.
在问专家上看到的回答是:
由于所修改的记录与数据库所存在的记录冲突,导致更改失败(如其他用户已将记录删除),如果没有触发器,其实程序发生警告信息给Errors集合,但不终止程序运行,也不会出实时错误提示。如果你加上触发器,你所进行批更新包括从Deleted表中记录,即所有删除的记录,所有的更新请求都不存在(或已被其它用户删除),所以出现实时运行错误。
对于我的情况, select 对应报价单号 from deleted 将是NULL值, 但这并不影响Update语句的执行啊??
请高手解疑!
- 对我有用[0]
- 丢个板砖[0]
- 引用
- 举报
- 管理
- TOP
- chd2001
- (重启失败)
- 等 级:
- 对我有用[0]
- 丢个板砖[0]
- 引用
- 举报
- 管理
- TOP
- vinsonshen
- (阿呢陀佛,一切皆空(帐号雪藏))
- 等 级:
-
3
CREATE TRIGGER tg_订单_Del ON [dbo].[订单]
for DELETE
AS
if exists (select * from deleted)
update 报价表
set 是否接单=0
where 报价单号=
(select 对应报价单号
from deleted)
GO
- 对我有用[0]
- 丢个板砖[0]
- 引用
- 举报
- 管理
- TOP
- Liroyal
- (胡姬花)
- 等 级:
- 对我有用[0]
- 丢个板砖[0]
- 引用
- 举报
- 管理
- TOP
- 98049522
- (Napoleon Bonapa)
- 等 级:
update a set a.是否接单=0 from 报价表 a, deleted b where a.报价单号=b.对应报价单号
在我的应用中使用触发器更好
- 对我有用[0]
- 丢个板砖[0]
- 引用
- 举报
- 管理
- TOP
- qiliu
- (痴心求学)
- 等 级:
不知道为什么?
- 对我有用[0]
- 丢个板砖[0]
- 引用
- 举报
- 管理
- TOP
- qiliu
- (痴心求学)
- 等 级:
其他的还不知道;
- 对我有用[0]
- 丢个板砖[0]
- 引用
- 举报
- 管理
- TOP
- lipkissnow
- (雨水,我在傘中央)
- 等 级:
就樓主的這條語句來講后面用等號與(select 对应报价单号 from deleted)相連就不委.因為后面查到的一個集合.改成update 报价表 set 是否接单=0 where 报价单号 in (select 对应报价单号 from deleted)好些,當然對一條記錄可以.如果是多條記錄就會產生數據混亂.
至於為什麼會產生樓主所說的問題.樓主為什麼不走另一條路呢.
你有說過訂單有對應報價單時不會錯.那麼我定義一個 變量取得當前訂單的報價單號.不就行了嗎.如下:
CREATE TRIGGER tg_订单_Del ON [dbo].[订单]
for DELETE
AS
declare @報價單號 int
select @報價單號=報價單號 from deleted
if @報價單號 is not null or @報價單號 <> ' ' --條件根據樓主自行定義
update 报价表 set 是否接单=0 where 报价单号= (select 对应报价单号 from deleted)
GO
--上面只是針對單條記錄.如果是多條記錄同時進行.最好還是用游標.
--以上意見僅供參考
- 对我有用[0]
- 丢个板砖[0]
- 引用
- 举报
- 管理
- TOP
- 98049522
- (Napoleon Bonapa)
- 等 级:
CREATE TRIGGER tg_订单_Del ON [dbo].[订单]
for DELETE
AS
if exists (select * from deleted)
update 报价表
set 是否接单=0
where 报价单号=
(select 对应报价单号
from deleted)
GO
使用照样出错, 但是如果在if内加上一个select语句便可以了
if exists (select * from deleted)
select '执行到这 '
update 报价表
set 是否接单=0
where 报价单号=
(select 对应报价单号
from deleted)
猜想:MSSQL事务检测触发器是否成功执行是根据判断返回值的, 如果没有对应的报价单,那么触发器内的update语句的影响行是0, 而有对应的报价单, 触发器内的update影响行是1. 这就导致了有对应报价单时删除可以成功执行,没有时事务会回滚.
另外 这条语句if exists (select * from deleted) 总是为真的.
把它改为:if exists (select 对应报价单号 from deleted) ,而订单中这个字段为空,但语句结果还是为真, 不知道是为什么?
- 对我有用[0]
- 丢个板砖[0]
- 引用
- 举报
- 管理
- TOP
- 98049522
- (Napoleon Bonapa)
- 等 级:
- 对我有用[0]
- 丢个板砖[0]
- 引用
- 举报
- 管理
- TOP
- 98049522
- (Napoleon Bonapa)
- 等 级:
CREATE TRIGGER tg_订单_Del ON [dbo].[订单]
for DELETE
AS
--if exists (select 对应报价单号 from deleted)
--begin
select 对应报价单号 from deleted
--select '存在 '
update 报价表
set 是否接单=0
where 报价单号=
(select 对应报价单号
from deleted)
--end
触发器更新引发的异常'无法为更新行集定位:一些值可能已在最后读取后改变', 该怎么修改触发...
+我整理的一些有趣网站(持续更新中...8.8最后更新)——2
如何为一些特定的邮箱数据库更新设计
电信网通吐血了!我的ADSL1M使用前下载最高下载速度为98K ,安装后为141K(已更新) -
电脑时间无法更新
“word无法读取文档,文档可能损坏!”的解决方法
“word无法读取文档,文档可能损坏!”的解决方法
“word无法读取文档,文档可能损坏!”的解决方法
提示“word无法读取文档,文档可能损坏”的解决方法
局势观察(已更新)
主体思想的最后王朝——北韩游记(更新在第20页)
百度算法更新后的思考
word 无法读取文档 文档可能损坏
我们的器官一直在更新
火爆韩剧-我人生最后的绯闻更新11-12集观看下载
为会在看电影你呢杂了更新哦
IE9:IE9更新完补丁后仍提示需要更新的解决方案 | 电脑知识探讨
席慕蓉诗歌作品朗诵集(地址已更新)
可能改变你人生的一些话
可能改变人生的一些话
用javascript自动显示最后更新时间
网站更新的重要性
四合院的更新发展
世界观的更新