2016-09-27 2 views
2

Wenn ich die SQL-Anweisung mit der normalen Abfrage versuchen, es gut funktioniert wie folgt:Debug mein SQL Server-Trigger-Update

UPDATE TraineeMonthlyShopItemListRecord 
SET Data01 = 1 
WHERE TraineeID = '553' 
    AND ShopItemListID = '17' 
    AND RecordID IN (SELECT a.recordid 
        FROM TraineeMonthlyHourRecord a 
        JOIN MonthlyHourRecord b ON a.RecordID = b.RecordID 
        WHERE b.Month = '201609' 
        AND a.TraineeID = '553' 
        GROUP BY a.RecordID 
        HAVING COUNT(*) = 1) 

jedoch nicht in einem Trigger funktioniert. Ich kann erfolgreich den Trigger speichern, aber wenn ich es testen mit manuell einen Datensatz in der Tabelle einfügen, halte ich erhalte eine Fehlermeldung:

Incorrect syntax near 'MonthlyHourRecord'

Hier ist meine Trigger-Code, haben Sie einen Blick und sehen, was Unrecht sein könnte, Vielen Dank!

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER TRIGGER [dbo].[t2] 
ON [dbo].[TraineeShopItemListRecord] 
AFTER INSERT  
AS  
BEGIN 
    declare @TraineeID varchar(10) 
    declare @MM varchar(10) 
    declare @YYYY varchar(10) 
    declare @ShopItemListID varchar(20) 
    declare @RecordID varchar(10) 
    declare @YYYYMM varchar(10) 
    declare @RecordTime datetime 
    declare @DD varchar(10) declare @test varchar(10) 
    declare @DataDD varchar(10) 
    declare @Quantity varchar(10) 
    declare @SQL nvarchar(200) 

    SELECT @ShopItemListID = ShopItemListID from inserted 
    SELECT @RecordTime = RecordTime from inserted 
    SELECT @Quantity = Quantity from inserted 

    SET @MM = substring(CONVERT(varchar,@RecordTime, 112),5,2) 
    SET @YYYY = substring(CONVERT(varchar,@RecordTime, 112),1,4) 
    SET @DD = substring(CONVERT(varchar,@RecordTime, 112),7,2) 

    SELECT @TraineeID = TraineeID from inserted 

    SET @YYYYMM = @[email protected] 
    SET @DataDD = 'Data'[email protected] 

    SET @SQL = 'UPDATE TraineeMonthlyShopItemListRecord SET  '[email protected]+'='[email protected]+' WHERE TraineeID ='''[email protected]+''' and ShopItemListID='''[email protected]+''' and RecordID IN (SELECT DISTINCT a.RecordID from TraineeMonthlyHourRecord a JOIN MonthlyHourRecord b on a.RecordID = b.RecordID WHERE b.Month ='''[email protected]+''' and a.TraineeID ='''[email protected]+''' GROUP BY a.RecordID HAVING COUNT(*) = 1)' 

    EXEC sp_executesql @SQL 
END 
+1

Ihre Trigger hat ** MAJOR ** Fehler, dass Sie scheinen es zu übernehmen werde ** einmal pro Zeile aufgerufen werden ** - das ist ** nicht ** der Fall. Der Trigger wird ** einmal pro Anweisung ** ausgelöst. Wenn also Ihre INSERT-Anweisung, die diesen Auslöser auslöst, 25 Zeilen einfügt, erhalten Sie den Trigger einmal ** ausgelöst, dann aber die "Eingefügte" Pseudo-Tabelle enthalten 25 Zeilen. Welche dieser 25 Zeilen wird Ihr Code hier auswählen? 'SELECT @Quantity = Quantity from inserted' - es ist nicht deterministisch, Sie erhalten ** eine beliebige Zeile ** und Sie werden ** ignorieren alle anderen Zeilen **. Sie müssen Ihren Trigger neu schreiben, um dies zu berücksichtigen! –

+0

Danke für den Vorschlag. In welche Richtung sollte ich es umschreiben? – autopenta

+0

Sie müssen berücksichtigen, dass "Eingeschaltet" (und "Gelöscht") ** mehrere Zeilen ** enthält und Sie daher ** Set-basierte ** Operationen verwenden müssen, anstatt einzelne Spaltenwerte abzurufen. –

Antwort

0

Zu groß für den Kommentar, so schreibe ich es in einer Antwort.

können Sie diese mit Tabellen, die Sie aktualisieren müssen, um beitreten

SELECT TraineeID, 
     ShopItemListID, 
     RecordTime, 
     Quantity, 
     substring(CONVERT(varchar,@RecordTime, 112),1,4)+substring(CONVERT(varchar,@RecordTime, 112),5,2) as YYYYMM 
     'Data'+substring(CONVERT(varchar,@RecordTime, 112),7,2) as DataDD 
FROM inserted 

verwenden.

Geben Sie diesem einen Versuch:

;WITH cte AS (
SELECT TraineeID, 
     ShopItemListID, 
     RecordTime, 
     Quantity, 
     substring(CONVERT(varchar,@RecordTime, 112),1,4)+substring(CONVERT(varchar,@RecordTime, 112),5,2) as YYYYMM 
     'Data'+substring(CONVERT(varchar,@RecordTime, 112),7,2) as DataDD 
FROM inserted 
) 

UPDATE tm 
SET Data01 = c.Quantity 
FROM TraineeMonthlyShopItemListRecord tm 
INNER JOIN cte c 
    ON c.TraineeID = tm.TraineeID 
     AND tm.ShopItemListID = c.ShopItemListID 
CROSS APPLY (
    SELECT a.RecordID 
    FROM TraineeMonthlyHourRecord a 
    INNER JOIN MonthlyHourRecord b 
     ON a.RecordID = b.RecordID 
    WHERE b.Month = c.YYYYMM 
     AND a.TraineeID = c.TraineeID 
    GROUP BY a.RecordID 
    HAVING COUNT(*) = 1 
) a 
WHERE a.RecordID = tm.RecordID 
+0

Vielen Dank für die Erklärung. – autopenta

+0

Mein Vergnügen! Hoffe, das wird dir helfen :) – gofr1