我一直在尝试创建触发器来减少需要编写的客户端代码。我编写了以下两个 tSQL 触发器,它们似乎都产生相同的结果,我只是想知道哪一个是更正确的方法。如果这有什么区别的话,我正在使用 SQL Server 2012。
即
- 哪一个使用的资源较少
- 执行速度更快
- 更安全地抵御攻击
- 等等...
CREATE TRIGGER tr_ProductGroup_INSERT_GroupMap
ON [qmgmt].[dbo].[ProductGroup]
After INSERT
AS
BEGIN
if (
select count([inserted].[groupID])
from [inserted]
where [inserted].[groupID] = 1
) = 0
begin
insert into [qmgmt].[dbo].[GroupMap]([parentGroupID], [childGroupID])
select 1, [inserted].[groupID]
from [inserted]
end
END
GO
或
CREATE TRIGGER tr_ProductGroup_INSERT_GroupMap
ON [qmgmt].[dbo].[ProductGroup]
After INSERT
AS
BEGIN
insert into [qmgmt].[dbo].[GroupMap]([parentGroupID], [childGroupID])
select 1, [inserted].[groupID]
from [inserted]
Where[inserted].[groupID] in
(
select [inserted].[groupID]
from [inserted]
where [inserted].[groupID] <> 1
)
END
GO
更新:
根据这里的一些评论,我正在使用插入内容。无论我使用哪个触发器,GroupMap 表都有相同的结果。
insert into [qmgmt].[dbo].[ProductGroup]([groupName], [groupDescription]) values ('root', 'The root of all groups')
insert into [qmgmt].[dbo].[ProductGroup]([groupName], [groupDescription]) values ('orphans', 'This is where the members of deleted groups go')
insert into [qmgmt].[dbo].[ProductGroup]([groupName], [groupDescription]) values ('SMGMT', 'Support Management')
insert into [qmgmt].[dbo].[ProductGroup]([groupName], [groupDescription]) values ('ST1', 'Support Tier 1')
insert into [qmgmt].[dbo].[ProductGroup]([groupName], [groupDescription]) values ('ST2', ' Support Tier 2')
insert into [qmgmt].[dbo].[ProductGroup]([groupName], [groupDescription]) values ('ST3', 'Support Tier 3')
insert into [qmgmt].[dbo].[ProductGroup]([groupName], [groupDescription]) values ('SaaSMGMT', 'Express Management')
insert into [qmgmt].[dbo].[ProductGroup]([groupName], [groupDescription]) values ('SaaSSup', 'Support Express')
最佳答案
由于评论太小,无法放入此示例,因此我将其放入答案中。人们说您的触发器在功能上不同的原因是,尽管您的测试逐行插入,但当您在一次操作中将多行插入表中时,触发器也会触发。根据您的示例,您可以尝试以下操作:
insert into [qmgmt].[dbo].[ProductGroup]([groupName], [groupDescription])
SELECT 'root', 'The root of all groups'
UNION ALL
SELECT 'orphans', 'This is where the members of deleted groups go'
UNION ALL
SELECT 'SMGMT', 'Support Management'
执行此查询时,inserted
表将保存 3 行,并且(取决于数据)2 个触发器代码示例的结果可能会给出不同的结果。
别担心,这是一个常见的误解。 SQL 的经验法则是始终考虑记录集,而不是“带有字段的单个记录”。
至于你的问题(是的,我想要一个真正的答案=)
我建议对第二个进行变体。
CREATE TRIGGER tr_ProductGroup_INSERT_GroupMap
ON [qmgmt].[dbo].[ProductGroup]
After INSERT
AS
BEGIN
insert into [qmgmt].[dbo].[GroupMap]([parentGroupID], [childGroupID])
select 1, [inserted].[groupID]
from [inserted]
where [inserted].[groupID] <> 1
END
这样,服务器只需运行一次inserted
,决定“保留”哪些记录,然后立即将它们存储到目标表中。
现在的问题是,这是否符合您的要求......
关于sql - tSQL触发器逻辑,有IF子句更好,还是IN子句更好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22967608/