tSQL触发逻辑,最好有IF子句或IN子句吗?

时间:2014-04-09 15:43:42

标签: sql sql-server triggers sql-server-2012

我一直在尝试创建触发器以减少需要编写的客户端代码。我编写了以下两个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

UPDATE:

基于这里的一些评论是我正在使用的插入。无论我使用哪种触发器,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')

1 个答案:

答案 0 :(得分:2)

由于评论有点太小而无法放入此示例,我将把它放在答案中。人们说你的触发器在功能上有所不同的原因是,虽然你的测试逐行插入,但是当你在一次操作中向表中插入多行时,触发器也会触发。根据您的示例,您可以尝试以下方法:

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上运行一次,决定哪些记录要保留&#39}。然后将它们直接存储到目标表中。

现在的问题是,如果这样做你想做它...