2017-07-19 3 views
0

Könnten Sie mir bitte helfen, meinen Auslöser zu beenden. Was ich bisher bekommen habe:SQL Insert-Trigger-Bedingung Anweisung und mehrere Zeilen

CREATE TRIGGER [dbo].[atbl_Sales_OrdersLines_ITrigGG] 
ON [dbo].[atbl_Sales_OrdersLines] 
FOR INSERT 
AS 
BEGIN 

DECLARE @ID INT = (SELECT ProductID 
FROM INSERTED) 

DECLARE @OrderedQ INT = (SELECT SUM(Amount) 
FROM atbl_Sales_OrdersLines 
WHERE ProductID = @ID) 

DECLARE @CurrentQ INT = (SELECT Quantity 
FROM atbl_Sales_Products 
WHERE ProductID = @ID) 

DECLARE @PossibleQ INT = (SELECT Amount 
FROM INSERTED 
WHERE ProductID = @ID) 

IF (@CurrentQ - @OrderedQ >= @PossibleQ) 

ELSE 

END 

Ich muss den Code vervollständigen. Ich kann nicht herausfinden, wie es geht. Ich brauche das, wenn Bedingung erfüllt ist - Auslöser würde den Einsatz erlauben. Anderenfalls würde der Trigger das Einfügen/Zurücksetzen stoppen und eine Meldung anzeigen, dass die Menge nicht ausreicht.

Funktioniert dieser Code auch, wenn mehrere Zeilen mit verschiedenen Produkt-IDs eingefügt werden?

Danke.

+0

Die Antwort auf Ihre letzte Frage ist ** nein **, es wird nicht funktionieren, wenn die Einfügung mehrere Zeilen mit verschiedenen Produkt-IDs ist. Die ersten zwei Zeilen, in denen Sie '@ id' festlegen, können nur eine Produkt-ID aus allen productIds in 'eingefügten' Zeilen erfassen. Also, alles danach arbeitet mit einer Teilmenge der Wahrheit. – hatchet

+0

Nein, das ist ein sehr schlechter Code. Wenn mehrere Zeilen eingefügt werden, wählt es zum Beispiel eine ID aus (die letzte von SELECT). Es ignoriert alle anderen. Alle Trigger müssen in einer Satzschreibweise geschrieben werden, die annimmt, dass in den eingefügten (und/oder gelöschten) Sammlungen mehrere Zeilen vorhanden sind. Jedes Mal, wenn Sie eine skalare Variable wie hier deklarieren, ist es eine rote Flagge. Dies wird nie funktionieren für das, was Sie versuchen zu tun. – pmbAustin

+0

Irgendwelche Vorschläge? Ich mache eine Übung für Lernzwecke, es ist kein wirkliches Projekt. Darüber hinaus wird die gesamte Bestellung zurückgewiesen, wenn einem oder mehreren Produkten die Menge fehlt. – Benua

Antwort

1

So etwas wie dies funktionieren könnte. Dieser Trigger prüft die Produkte, die sich in der Beilage befinden, summiert die Summe, die bestellt wurde (jetzt und in der Vergangenheit), und wenn eine von ihnen die verfügbare Menge überschreitet, wird die gesamte Transaktion zurückgesetzt. Beim Schreiben von Triggern möchten Sie vermeiden, dass eine einzelne Zeile eingefügt/aktualisiert/gelöscht wird und Cursor vermieden werden. Sie möchten nur grundlegende Set-basierte Operationen verwenden.

CREATE TRIGGER [dbo].[atbl_Sales_OrdersLines_ITrigGG] 
    ON [dbo].[atbl_Sales_OrdersLines] 
    FOR INSERT 
    AS 
    BEGIN 
     IF (exists (select 1 from (
      select x.ProductId, totalOrdersQty, ISNULL(asp.Quantity, 0) PossibleQty from (
       select i.ProductId, sum(aso.Amount) totalOrdersQty 
       from (select distinct ProductId from inserted) i 
       join atbl_Sales_OrdersLines aso on aso.ProductId = i.ProductId 
       group by productId) x 
      left join atbl_Sales_Product asp on asp.ProductId = x.ProductId 
      ) x 
      where PossibleQty < totalOrdersQty)) 
     BEGIN  
      RAISERROR ('Quantity is not sufficient' ,10,1) 
      ROLLBACK TRANSACTION 
     END 
    END 

Ich denke immer noch, dass dies eine schreckliche Idee ist.

+0

Danke, aber ich bekomme Syntaxfehler, wo THEN und END verwendet werden. – Benua

+0

Ich tippte das in meinem Kopf ein. Ich habe den Anfang vergessen. Siehe Bearbeiten. – hatchet

+0

Noch kann es nicht auf SQL-Server laufen, aber danke - jetzt weiß ich das Konzept, wie dies getan werden könnte. – Benua

0

die Sie interessieren,

CREATE TRIGGER [dbo].[atbl_Sales_OrdersLines_ITrigGG] 
ON [dbo].[atbl_Sales_OrdersLines] 
INSTEAD OF INSERT --FOR INSERT 
AS 
BEGIN 

DECLARE @ID INT = (SELECT ProductID 
FROM INSERTED) 

DECLARE @OrderedQ INT = (SELECT SUM(Amount) 
FROM atbl_Sales_OrdersLines 
WHERE ProductID = @ID) 

DECLARE @CurrentQ INT = (SELECT Quantity 
FROM atbl_Sales_Products 
WHERE ProductID = @ID) 

DECLARE @PossibleQ INT = (SELECT Amount 
FROM INSERTED 
WHERE ProductID = @ID) 

IF (@CurrentQ - @OrderedQ >= @PossibleQ) 
BEGIN 
     INSERT INTO YOURTABLE (COLUMN1, COLUMN2, COLUMN3, ..) 
     SELECT COLUMN1, COLUMN2, COLUMN3, .. 
     FROM inserted 
END 
ELSE 
BEGIN 
    RAISERROR ('Quantity is not sufficient' ,10,1) 
     ROLLBACK TRANSACTION 

END 
+0

Dies ist immer noch falsch, wenn mehr als eine Zeile in 'inserted' ist. – hatchet

+0

Vielleicht könnten wir hier eine Schleife machen? Überprüfen Sie jede Zeile (mit der Neudeklaration der ID bei jeder Prüfung) Wenn eine der Zeilen fehlschlägt - Rollback. – Benua

+0

Es ist komplizierter als das. Sie müssten die eingefügten Zeilen nach productId und rollback gruppieren, wenn die Summe für eine productId den verfügbaren Betrag überschreitet. – hatchet

Verwandte Themen