我创建了这样的触发器
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。当子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时,不允许这样做。 声明已经终止。
我该如何解决这个问题
答案 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 ...