Fab*_*bio 7 t-sql sql-server triggers
如何防止在同一个表上同一事件触发的两个触发器之间发生锁定问题?
我正在处理的数据库已经有一个加密的更新触发器,因此我无法对其进行修改.我做了另一个更新触发器来完成一些新任务,当我直接在数据库上测试它时它正常工作,但是当我在前端应用程序上更新产品时失败了.显然,当我的触发器处于活动状态时,两个触发器都会失败.我收到的消息是"文档已经打开,我将增加它的值".
这是锁定问题吗?
有一个相关的问题,有人说我们可以在桌子上有多个触发器(针对同一事件).
这是我的触发器代码:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[tr_st_rep_update]
ON [dbo].[st]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF ( update(ref)
OR update(design)
OR update(u_update)
OR update(u_ativo)
OR update(stock)
OR update(epv1)
OR update(epv2)
OR update(epv3)
OR update(peso)
OR update(u_catnv1)
OR update(u_catnv2)
OR update(u_catnv3)
OR update(u_dpromoi)
OR update(u_dpromof)
OR update(u_destaque) )
BEGIN
IF (SELECT count(*)
FROM Inserted
INNER JOIN Deleted
ON Inserted.ststamp = Deleted.ststamp
WHERE inserted.u_ativo = 1
OR ( Deleted.u_ativo = 1
AND Inserted.u_ativo = 0 )) > 0
BEGIN
INSERT INTO RepData
(id,
REF,
familia,
stock,
epv1,
epv2,
epv3,
peso,
u_accao,
imagem,
process)
SELECT Inserted.ststamp AS id,
Inserted.REF AS REF,
Inserted.familia AS familia,
Inserted.stock AS stock,
Inserted.epv1 AS epv1,
Inserted.epv2 AS epv2,
Inserted.epv3 AS epv3,
Inserted.peso AS peso,
CASE
WHEN Deleted.u_ativo = 1
AND Inserted.u_ativo = 0 THEN 'd'
ELSE 'u'
END AS u_accao,
Inserted.imagem AS imagem,
0 AS process
FROM Inserted
INNER JOIN Deleted
ON Deleted.ststamp = Inserted.ststamp
WHERE inserted.u_ativo = 1
OR ( Deleted.u_ativo = 1
AND Inserted.u_ativo = 0 )
END
END
END
Run Code Online (Sandbox Code Playgroud)
任何帮助,将不胜感激.
更新:数据库是MSSQL 2008
RBa*_*ung 11
使用触发器进行部署后的现场开发和定制是一个诱人但不好的想法,并且毫无疑问会不断为您生成这样的问题.
但是,鉴于此,那么First:表可以有多个触发器,这不是问题.
其次,错误消息" 文档已经打开,我将增加它的值 "来自客户端应用程序或其他(加密)触发器,它不是SQL Server错误消息.鉴于此,您可以尝试将加密触发器设置为先执行,或将触发器设置为最后执行.这可能无法解决问题,但它可能会将错误从加密触发器移动到您的触发器中,您可以以可管理的方式更好地报告和/或处理它.
虽然可以看到,触发器可能出现的唯一问题是,如果另一个触发器也写入RepData
表并且您的双重写入导致重复的键冲突.
触发顺序可以通过sp_settriggerorder
系统过程控制,此处记录.
问题解决了。
我真的不知道问题的根源,尽管我认为这与表锁定有关,在本例中是插入表上的锁定。
我只是更改了内部 select 语句,以便直接从 st 表而不是 Inserted 中获取值。
感谢大家。
归档时间: |
|
查看次数: |
18562 次 |
最近记录: |