在SQL Server触发器中包含If语句吗?

问题描述 投票:0回答:1

我目前正在努力学习数据库管理课程。我的任务是创建一个触发器,如果​​客户第一次进行预订,该触发器将打印一条消息。到目前为止,我的代码如下

ALTER TRIGGER [dbo].[ResNewTrigger] 
ON [dbo].[Reservation] 
AFTER INSERT, DELETE, UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    DECLARE @cid CHAR(4)   
    DECLARE @res_counts INT    
    SELECT @cid = CustomerNum FROM inserted    

    SELECT @res_counts = COUNT(*) 
    FROM dbo.Reservation 
    WHERE CustomerNum = @cid 

    IF @res_counts = 0 THEN
        PRINT  'A reservation is made for the first time from customer' + @cid;
    END IF;
END;

这将引发错误:

消息156,级别15,状态1,过程ResNewTrigger,第20行[批处理开始第7行]关键字“ THEN”附近的语法不正确。

消息102,级别15,状态1,过程ResNewTrigger,第22行[批处理开始第7行]';'附近的语法不正确。

我一定不知道正确的语法或其他内容,但是我很幸运地找到了解决这个问题的方法。

sql sql-server triggers
1个回答
1
投票

IF语句中的语法错误是与触发器有关的最少问题(请参阅docs来更正IF语句)。

您的触发器是错误的,因为您假设inserted有一行。这样的假设永远都不安全。

ALTER TRIGGER [dbo].[ResNewTrigger] 
   ON  [dbo].[Reservation] 
   AFTER INSERT
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    DECLARE @cids VARCHAR(MAX);

    -- Insert statements for trigger here
    SELECT @cids = STRING_AGG(i.cid, ', ')
    FROM inserted i JOIN
         Reservation r
         ON r.customerNum = i.customerNum
    GROUP BY i.cid
    HAVING COUNT(*) = 1;   -- this row is already in reservation
    IF @cids <> ''
    BEGIN
        PRINT  'A reservation is made for the first time from customer(s) ' + @cids;
    END;
END;

这使用string_agg()将cid连接在一起。在早期版本的SQL Server中,您需要UDF或其他某种机制来聚合字符串。

我很好地去除了触发器的UPDATEDELETE部分。您当然无法在DELETE上为客户获得新的预订。在UPDATE上,这更成问题。但是,很难(但不是不可能)区分对单个记录的更改和插入单个记录。

© www.soinside.com 2019 - 2024. All rights reserved.