Sql server Msg 102,15级,状态1,程序fireStaff,第17行';附近语法不正确';

Sql server Msg 102,15级,状态1,程序fireStaff,第17行';附近语法不正确';,sql-server,triggers,Sql Server,Triggers,我试图用下面的触发器删除一名工作人员,但当我尝试运行它时,我得到了错误: Msg 102,15级,状态1,程序fireStaff,第17行[批量启动] 第255行]靠近“;”的语法不正确 我在哪里漏掉了什么?你漏掉了一个结尾。如果缩进正确,则会很明显: CREATE TRIGGER fireStaff ON DBO.STAFF FOR DELETE AS BEGIN SET NOCOUNT OFF; DECLARE @id_s INT, @sal INT; SELECT

我试图用下面的触发器删除一名工作人员,但当我尝试运行它时,我得到了错误:

Msg 102,15级,状态1,程序fireStaff,第17行[批量启动] 第255行]靠近“;”的语法不正确


我在哪里漏掉了什么?

你漏掉了一个
结尾
。如果缩进正确,则会很明显:

CREATE TRIGGER fireStaff
ON DBO.STAFF
FOR DELETE AS
BEGIN
    SET NOCOUNT OFF;
    DECLARE @id_s INT, @sal INT;

    SELECT @id_s = STAFF_ID FROM deleted;
    SELECT @sal = salary FROM deleted;

    IF @sal>7000 BEGIN
        RAISERROR('Trigger has been stopped, not allowed to delete a worker who earns salary over 7000.',16,1); ROLLBACK;
    END;
    ELSE BEGIN
        PRINT 'Staff name "'+ Cast(@id_s as nvarchar(20))+'" was  deleted from the database.';
    END;
-- END GOES HERE
GO
根据肖恩的评论,是的,如果你删除多个员工,这个“失败”。因此,以下方法可以解决该问题:

CREATE TRIGGER fireStaff
ON DBO.STAFF
FOR DELETE AS
BEGIN
    SET NOCOUNT OFF;
    --DECLARE @id_s INT, @sal INT;

    --SELECT @id_s = STAFF_ID FROM deleted;
    --SELECT @sal = salary FROM deleted;

    IF (SELECT COUNT(*) FROM deleted WHERE salary >7000) > 0 BEGIN
        RAISERROR('Trigger has been stopped, not allowed to delete a worker who earns salary over 7000.',16,1);
        ROLLBACK;
    END;
    ELSE BEGIN
        PRINT 'Staff member(s) were deleted from the database.';
    END;
END;
GO
如果你真的需要员工的名字,我们可以做点什么


请注意,这也将取消整个交易,因此,如果一名工作人员的工资为5000英镑,而另一名工作人员的工资为10000英镑,则这两项都不会被删除。因此,根据您的需要,可能需要更精确的细节。

您缺少一个
结尾。如果缩进正确,则会很明显:

CREATE TRIGGER fireStaff
ON DBO.STAFF
FOR DELETE AS
BEGIN
    SET NOCOUNT OFF;
    DECLARE @id_s INT, @sal INT;

    SELECT @id_s = STAFF_ID FROM deleted;
    SELECT @sal = salary FROM deleted;

    IF @sal>7000 BEGIN
        RAISERROR('Trigger has been stopped, not allowed to delete a worker who earns salary over 7000.',16,1); ROLLBACK;
    END;
    ELSE BEGIN
        PRINT 'Staff name "'+ Cast(@id_s as nvarchar(20))+'" was  deleted from the database.';
    END;
-- END GOES HERE
GO
根据肖恩的评论,是的,如果你删除多个员工,这个“失败”。因此,以下方法可以解决该问题:

CREATE TRIGGER fireStaff
ON DBO.STAFF
FOR DELETE AS
BEGIN
    SET NOCOUNT OFF;
    --DECLARE @id_s INT, @sal INT;

    --SELECT @id_s = STAFF_ID FROM deleted;
    --SELECT @sal = salary FROM deleted;

    IF (SELECT COUNT(*) FROM deleted WHERE salary >7000) > 0 BEGIN
        RAISERROR('Trigger has been stopped, not allowed to delete a worker who earns salary over 7000.',16,1);
        ROLLBACK;
    END;
    ELSE BEGIN
        PRINT 'Staff member(s) were deleted from the database.';
    END;
END;
GO
如果你真的需要员工的名字,我们可以做点什么


请注意,这也将取消整个交易,因此,如果一名工作人员的工资为5000英镑,而另一名工作人员的工资为10000英镑,则这两项都不会被删除。因此,您的需要可能需要更精确的细节。

您缺少了
结尾在结尾(在
开始之前
)首先,正确地索引代码会向您显示这一点。我更新了您的代码,使丢失的代码更加突出。您的触发器有一个重大缺陷。它假定在删除中只有一行。sql server中的触发器在每个操作中触发一次,而不是每行触发一次。你的触发器需要处理多行。即使是一个学校项目,你也应该避免“现在就足够好”的习惯。这种心态会跟随你进入工作场所,对it部门来说就像癌症。你可以更仔细地看一下你在else中的逻辑。我想你不想说19283号员工的名字被删除了。你肯定想知道他们的名字。:)老实说,除了调试之外,在触发器中打印是没有用的。根据@SeanLange的观察,我已经更新了我的答案。因为“一排就行”不是你应该有的态度。如果你出了车祸,有4个人死了,但是一个人没有,因为安全带坏了,另一个人没有,你不会放过汽车制造商吧?一切都在细节中。(有点极端,是的,但不管级别如何,你都应该确保你的工作在任何情况下都是正确的,而不仅仅是在某些时候)在结尾(在
开始之前
)首先,正确地索引代码会向您显示这一点。我更新了您的代码,使丢失的代码更加突出。您的触发器有一个重大缺陷。它假定在删除中只有一行。sql server中的触发器在每个操作中触发一次,而不是每行触发一次。你的触发器需要处理多行。即使是一个学校项目,你也应该避免“现在就足够好”的习惯。这种心态会跟随你进入工作场所,对it部门来说就像癌症。你可以更仔细地看一下你在else中的逻辑。我想你不想说19283号员工的名字被删除了。你肯定想知道他们的名字。:)老实说,除了调试之外,在触发器中打印是没有用的。根据@SeanLange的观察,我已经更新了我的答案。因为“一排就行”不是你应该有的态度。如果你出了车祸,有4个人死了,但是一个人没有,因为安全带坏了,另一个人没有,你不会放过汽车制造商吧?一切都在细节中。(有点极端,是的,但不管级别如何,你都应该确保你的工作在任何情况下都是正确的,不仅仅是在某些时候)。@Tanner你不能在注释中设置适当的缩进格式,这是一个要点。更大的问题是标量变量和只删除一行的假设。非常好的一点,@SeanLange,我也没注意到。“将更新。@Tanner您无法在注释中设置适当的缩进格式,这是一个主要问题。更大的问题是标量变量和假设只删除了一行。非常好的一点,@SeanLange也没有注意到。”。将更新。