Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带条件更新的SQL触发器_Sql_Triggers_Conditional - Fatal编程技术网

带条件更新的SQL触发器

带条件更新的SQL触发器,sql,triggers,conditional,Sql,Triggers,Conditional,我需要在一对SQL表上构造以下逻辑。以下是基本的表格结构: TABLE [dbo].[Email]( [IssueId] [int] NOT NULL, [NoErrors] [int] NOT NULL, [EmailBody] [nvarchar](max) NULL, ... ) TABLE [dbo].[Inclusion]( [InclusionId] [int] IDENTITY(1,1) NOT NULL, [IssueId] [i

我需要在一对SQL表上构造以下逻辑。以下是基本的表格结构:

TABLE [dbo].[Email](
    [IssueId] [int] NOT NULL,
    [NoErrors] [int] NOT NULL,
    [EmailBody] [nvarchar](max) NULL,
    ...
)

TABLE [dbo].[Inclusion](
    [InclusionId] [int] IDENTITY(1,1) NOT NULL,
    [IssueId] [int] NOT NULL,
    ...
)
这两个表的主要关系是IssueId字段上的[Issue]表。每个问题记录只有一个关联的电子邮件表,但包含记录为零到多个

我想发生的是

如果删除了一条包含记录,并且它是与问题关联的最后一条包含记录,那么我想将Email.NoErrors设置为-1。如果存在其他包含项(删除后),我想保留Email.NoErrors“原样”

我已经编写了以下似乎有效的触发器:

ALTER TRIGGER [dbo].[trg_Inclusion_Delete]
   ON  [dbo].[Inclusion]
   AFTER DELETE
AS 
BEGIN
   SET NOCOUNT ON;

   UPDATE Email
   SET NoErrors = CASE
      WHEN EXISTS (
            SELECT * FROM Inclusion 
            WHERE IssueId = DELETED.IssueId
         )
         THEN NoErrors    -- Leave existing value
      ELSE
         (-1)
      END
   FROM DELETED
   WHERE Email.IssueId = DELETED.IssueId
END
有两件事我知道得足够多,可以担心。首先,触发器似乎效率低下,因为它总是更新Email.NoErrors文件,即使它不必更新。其次,我知道删除的引用表可能包含多条记录,但我不确定我的脚本是否能正确处理这些记录,但我怀疑不能

如有任何建议/指示,将不胜感激

更新
下面是我最后的代码:

ALTER TRIGGER [dbo].[trg_Inclusion_Delete]
   ON  [dbo].[Inclusion] AFTER DELETE
AS 

IF @@ROWCOUNT = 1
BEGIN
   UPDATE Issue
   SET NoEmailErrors = -1
   FROM DELETED
   WHERE (
      Issue.IssueId = DELETED.IssueId
      AND Issue.NoEmailErrors != -1
      AND NOT EXISTS (
         SELECT * 
         FROM Inclusion
         WHERE Inclusion.IssueId = DELETED.IssueId
      )
   )
END
ELSE
BEGIN
   UPDATE Issue
   SET NoEmailErrors = -1
   FROM DELETED
   WHERE (
      Issue.IssueId IN (
         SELECT IssueId FROM DELETED
      )
      AND Issue.NoEmailErrors != -1
      AND NOT EXISTS (
         SELECT * 
         FROM Inclusion
         WHERE Inclusion.IssueId = DELETED.IssueId
      )
   )
END

此重写可能会帮助您解决效率低下的问题:

ALTER TRIGGER [dbo].[trg_Inclusion_Delete]
    ON [dbo].[Inclusion]
    AFTER DELETE
AS 
BEGIN
SET NOCOUNT ON;

    UPDATE Email
    SET NoErrors = -1
    FROM DELETED
    WHERE Email.IssueId = DELETED.IssueId
        AND NOT EXISTS
        (
            SELECT 'x' FROM Inclusion 
            WHERE Inclusion.IssueId = DELETED.IssueId
        )
END

谢谢你,Eric,你的代码更干净了。我还发现了以下链接,我认为这与我正在尝试做的事情有关。我已经更新了我原来的帖子,加入了新的脚本