2017-05-05 93 views
-1

我用來觸發試圖更新使用下面的語句從另一個表中的記錄,但我得到一個錯誤SQL Server的觸發器:子查詢返回多個值

子查詢返回多個值。當子查詢遵循=,!=,<,< =,>,> =或當子查詢用作表達式時,這是不允許的。該語句已終止。

下面是我用

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

如果更新/一次插入1個多行,你會得到這個錯誤從第一IF檢查((選擇路由爲由插入)LIKE「總成」 ..等)。始終以適用於多行的方式編寫觸發器。 –

+0

如果插入了兩行或多行,你的If語句會讓你多行,並且會失敗(我相信) –

+5

你的觸發器有** MAJOR **缺陷,因爲你似乎認爲它會被稱爲**一次每行** - 這是**不是**的情況。觸發器將在每個語句**觸發一次**,所以如果你的引發這個觸發器觸發的INSERT語句插入了25行,你將觸發**觸發**一次,但是隨後插入的僞表將會包含25行。您的代碼在這25行中選擇哪一個? '選擇路由從插入' - 這是非確定性的,你會得到**任意一行**,你將**忽略所有其他行**。你需要重寫你的觸發器來考慮這個問題! –

回答

0

這種方式應該適用於多行插入/更新,而限制在那些ROUTING值。

請注意您的交叉應用確實需要在其中有一個order by子句,否則您會抓取一個隨機行並可能會得到意想不到的結果(也可能值得將每個*中的*更改爲您需要的列的列表,可以使用正確的索引)。

ALTER TRIGGER [dbo].[WO-A] 
    ON [dbo].[WORKORDERS] 
    AFTER UPDATE, INSERT, 
    AS 
BEGIN 
    SET NOCOUNT ON; 
      IF TRIGGER_NESTLEVEL() > 1 
      RETURN 
    ELSE 
     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 
    WHERE i.ROUTING IN ('Assy', 'L&P', 'ASSY FD', 'ASSY BD', 'RGA') 
END 
+0

謝謝,但我仍然得到同樣的錯誤 – Joe

0

代碼如果您使用來自INSERTEDDELETED表子查詢中的觸發器,你最好使用支持多行操作的語法。

例如在這裏你使用IF ((SELECT ROUTING FROM INSERTED) LIKE 'Assy'...

如果此子查詢(SELECT ROUTING FROM INSERTED LIKE 'Assy')返回多行,那麼if操作將失敗。在這種情況下,您一次只能插入或更新一行。所以你不能使用這個查詢,例如:

UPDATE [dbo].[WORKORDERS] 
SET ROUTING='L' 
WHERE ... --Queries that return more than one row