我在表上有一个SQL触发器,它会在插入,更新和删除后触发。
我将所有受影响的记录插入到单独的物理表中,其中的代码定义了更新状态。以下代码片段是定义的触发器。
CREATE TRIGGER [dbo].[DATA_CACHE]
ON [dbo].[DATA_USAGE]
for Insert,Update,Delete
AS
BEGIN
if(select COUNT(*) from inserted)>0
begin
if (select COUNT(*) from deleted)>0
BEGIN
--update
INSERT INTO CACHE_UPDATE_TABLE (CODE, ID, DATE, COUNT)
SELECT 2, ins.ID, ins.DATE, ins.COUNT
from inserted ins
END
else
begin
-- insert
INSERT INTO CACHE_UPDATE_TABLE (CODE, ID, DATE, COUNT)
SELECT 1, ins.ID, ins.DATE, ins.COUNT
from inserted ins
end
END
else
BEGIN
-- delete
INSERT INTO CACHE_UPDATE_TABLE (CODE, ID, DATE, COUNT)
SELECT 3, del.ID, del.DATE, del.COUNT
from deleted del
end
END
SELECT * FROM CACHE_UPDATE_TABLE
正如您在上面的触发器中看到的那样,我在MISTAKE触发后添加了一个附加语句,从目标表中选择所有值。这个语句是在定义的触发器之后,但是当我试图改变触发器时,通过右键单击触发器并选择modify,它还向我显示了触发器结束块之后的select语句。
这是否意味着,每次触发触发器时,此select语句都会执行?这是我的第一个问题(问题A) - 可能是一个愚蠢的问题,但我对此有点困惑。
我的第二个问题是(问题B)我在CACHE_UPDATE_TABLE上遇到锁定问题,这可能是锁定的原因吗?还有一个SQL作业每分钟运行一次以检查CACHE_UPDATE_TABLE表,然后我执行一些操作(链接服务器相关)并在完成后从CACHE_UPDATE_TABLE中删除这些记录。锁定问题可能是因为这个?如果是这样,我该如何反击呢?
我的第三个问题是(问题C)这是使用触发器执行此操作的最佳方法还是我可以通过其他方式执行此操作?触发器是否正确定义?
- 任何帮助将不胜感激...谢谢。
答案 0 :(得分:1)
你有很多不同的问题,这可能就是你没有收到任何答案的原因,但我会尽我所能。
A)实际上这是一个非常有趣的问题。我会假设它什么都不做 - 它会在你创建触发器时执行但是它不会成为触发器的一部分 - 但是我之前已经注意到奇怪的行为,所以我用一个简单的存储过程测试:
CREATE PROCEDURE dbo.test ( @i INT ) AS
BEGIN
SELECT @i
END;
SELECT 'hi'
GO
执行存储过程会导致SELECT 'hi'
以及SELECT @i
。我仍然没有你的问题的答案,但我肯定会确保在你因为这个原因创建它时不会在触发器之外有任何迷路SQL。
我刚刚调查了一下,显然存储过程的结束是在程序之后的第一个GO
的任何地方(如果你不使用SQL Server,它会自动添加到最后) 。因此,您可以在END
之后定义整个过程 - 您仍然可以使用参数。
这似乎是因为BEGIN
和END
不是存储过程定义的必需部分 - 它们实际上并不表示存储过程的开始和结束,它们是只是一个不相关的BEGIN...END
块,就像你可能会放在IF
语句之后。您可以在过程定义中拥有任意数量的BEGIN...END
块,或者根本没有。
C)我肯定会改变你的触发器。通过组合3个触发器而不重用任何代码,您已经大量复杂化了它。合并INSERT
,UPDATE
和DELETE
触发器的唯一原因是您不必重复代码。你应该:
INSERT
- 这样就可以删除所有条件逻辑。CODE
,并且只有1 INSERT
个语句。我很想使用3个单独的触发器,或至少单独删除触发器,然后使用CASE del.ID IS NULL THEN 1 ELSE 2 END
代表CODE
/ {INSERT
{1}}触发器。但你可以将它们与(未经测试)结合起来:
UPDATE
答案 1 :(得分:0)
只需删除
即可SELECT * FROM CACHE_UPDATE_TABLE