我创造了触发器来将佛教泰国年改为基督教年,但插入了多于1个错误

时间:2016-09-27 09:32:14

标签: sql sql-server

我创建了这样的触发器

CREATE TRIGGER [dbo].[YearBuddhistToChristian]
    ON [dbo].[Syslogd]
    INSTEAD OF INSERT
    AS
    BEGIN
       SET NOCOUNT ON;
       if (select year(MsgDateTime) from inserted) = year(getdate()) + 543

    INSERT INTO Syslogd(MsgDateTime,MsgPriority,MsgHostname,MsgText)
    SELECT dateadd(year,-543,MsgDateTime),MsgPriority,MsgHostname,MsgText
    FROM inserted;
    else
    INSERT INTO Syslogd(MsgDateTime,MsgPriority,MsgHostname,MsgText)
    SELECT MsgDateTime,MsgPriority,MsgHostname,MsgText
    FROM inserted;


    END

但是当我插入多个错误时 Msg 512,Level 16,State 1,Procedure YearBuddhistToChristian,Line 7 [Batch Start Line 0] 子查询返回的值超过1。当子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时,不允许这样做。 声明已经终止。

我该如何解决这个问题

2 个答案:

答案 0 :(得分:1)

问题在于你的IF条件。您将一组与一个值进行比较:

if (select year(MsgDateTime) from inserted) = year(getdate()) + 543

如果您插入单个记录,这可以正常工作,因为select将评估为单个值,但在具有多个记录的插入上,您必须将多个值的列表与单个值进行比较,并且SQL Server识别不同类型的两个对象(集合和标量值)不具有可比性。

您可以重写触发器来移动“IF'以CASE语句的形式在select中的语句,其中将对每行进行评估:

    INSERT  INTO Syslogd
            (MsgDateTime,
             MsgPriority,
             MsgHostname,
             MsgText
            )
            SELECT  CASE WHEN YEAR(Inserted.MsgDateTime) = YEAR(GETDATE())
                              + 543 THEN DATEADD(YEAR, -543, MsgDateTime)
                         ELSE MsgDateTime
                    END,
                    MsgPriority,
                    MsgHostname,
                    MsgText
            FROM    inserted;

或者,您可以在发生插入的任何地方使用它,以避免需要触发器(例如在存储过程中)。

答案 1 :(得分:0)

你需要把自己的年龄放在一起。使用SELECT中的CASE语句将逻辑转换为单个INSERT语句

之类的东西
   SELECT tt.user_id, first_occurance(tt.param1), first_occurance(tt.param2) FROM ...