【发布时间】:2022-01-17 01:16:30
【问题描述】:
我使用触发器尝试使用以下语句更新另一个表中的记录,但出现错误
子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。声明已终止。
这是我使用的代码
ALTER TRIGGER [dbo].[WO-A]
ON [dbo].[WORKORDERS]
AFTER UPDATE, INSERT,
AS
IF ((SELECT ROUTING FROM INSERTED) LIKE 'Assy'
or (SELECT ROUTING FROM INSERTED) LIKE 'L&P'
or (SELECT ROUTING FROM INSERTED) LIKE 'ASSY FD'
or (SELECT ROUTING FROM INSERTED) LIKE 'ASSY BD'
or (SELECT ROUTING FROM INSERTED) LIKE 'RGA'
)
BEGIN
set nocount on
IF TRIGGER_NESTLEVEL() > 1
RETURN
UPDATE T1
SET
[Assembly Notes]=T2.[Assembly Notes],
[Assy SO Confirm]=T2.[ASSEMBLY LOOKUP C],
[CALC COLOR]=T2.[COLOR],
[PILOT SIZE]=T2.[PILOT SIZE2],
[NO OF HOLES]=T2.[BOLT HOLES2],
[C/S OD]=T2.[C/S OD2],
[DISC OD]=T2.[DISC OD],
[C/S ANGLE2]=T2.[C/S ANGLE2],
[BH SIZE2]=T2.[BH SIZE2],
[SHORT WO PN]=t2.[CALC STOCK NO],
[CALC OFF-SET]=T2.[CALC OFF-SET],
[RUN OUT LAT]=T2.[RUN OUT LAT],
[RUN OUT RAD]=T2.[RUN OUT RAD],
[BOM SECONDRY DISC]=T2.[BOM - SECONDARY DISC],
[BH SPEC]=T2.[BH SPEC],
[BH CIRCLE2]=T2.[BH CIRCLE2],
[DISC THICKNESS2]=T2.[DISC THICKNESS],
[MRP BOM PARTS 1]=T2.[WHL BOM PART 1 PN],
[MRP BOM PARTS 2]=T2.[WHL BOM PART 2 PN],
[MRP BOM PARTS 3]=T2.[WHL BOM PART 3 PN],
[MRP BOM PARTS 4]=T2.[WHL BOM PART 4 PN],
--[ASSY PN-S]=T2.[CALC STOCK NO],
[SHORT WO PN2]=T2.[CALC STOCK NO],
[WO SALES DESCRIPTION] = T2.[Description for Sales],
--[Assy SO Confirm]=T2.[Assembly Lookup C],
[CUSTOMER PN]=T2.[CUSTOMER PN],
[MRP Wheel]=T2.[BOM WHEEL PN],
[TIRE PN]=T2.[BOM tire],
[TIRE SIZE]=T2.[TIRE SIZE],
[TIRE SUPPLIER]=T22.[Manufacturer],
[TIRE QUANTITY]=CASE WHEN T1.[TIRE PN]!='' THEN T1.[QUANTITY]
WHEN T1.[TIRE PN] IS NOT NULL THEN T1.[QUANTITY]
ELSE ''
END,
[RIM PN (MRP)]=t2.[BOM - RIM PN],
[WO Popularity]=t2.[POPULARITY],
--[RIM QUANTITY]=t2.[q
[WEIGHT]=T2.[unitWeight],--?? CHECK WETHER RIGHT COLUMN
--[ASSY DESC FOR LABEL]
SIZE=T21.[SIZE],
[MRP BLK DISC]=T21.[BLK DISC PN],
[WHEEL PN 1]=NULL,
[WHEEL PN 1-S]=NULL,
[ASSY PN-S]=NULL,
[MO ASSY PN]=null
FROM WORKORDERS T1
INNER JOIN inserted i ON T1.[WORK ORDER #] = i.[WORK ORDER #]
CROSS APPLY (SELECT TOP 1 *
FROM [ASSEMBLIES] T2
WHERE t1.[ASSY PN] = T2.[ASSEMBLY LOOKUP V 1]) T2
CROSS APPLY (SELECT TOP 1 *
FROM [TIRES] T22
WHERE T22.[Tire Lookup H] = T2.[BOM Tire] ) T22
CROSS APPLY (SELECT TOP 1 *
FROM [WHEELS] T21
WHERE T2.[BOM WHEEL] = T21.[WHEEL LOOKUP V] ) T21
END
【问题讨论】:
-
如果您一次更新/插入多于 1 行,您将从第一次 IF 检查中得到该错误((SELECT ROUTING FROM INSERTED) LIKE 'Assy' .. etc)。始终以适用于多行的方式编写触发器。
-
如果插入了两行或多行,您的 If 类将获得不止一行并且会失败(我相信)
-
您的触发器有 MAJOR 缺陷,因为您似乎认为它会每行调用一次 - 那是不是 b> 情况。触发器将每条语句触发一次,因此如果您的
INSERT语句导致此触发器触发插入 25 行,您将触发触发器一次,但随后Inserted伪表将包含 25 行。您的代码将在这 25 行中选择哪一行?SELECT ROUTING FROM INSERTED- 它是不确定的,您将获得任意行,您将忽略所有其他行。您需要重写触发器以考虑到这一点! -
谢谢大家!@marc_s 我该如何更新?
标签: sql-server tsql