2017-12-31 55 views
0

Ich bin ziemlich neu in SQL Server und ich habe Probleme bei der Implementierung einer WHERE-Anweisung in einem CASE, speziell für einen Trigger, an dem ich arbeite.SQL Server - WO in CASE?

Ich habe 2 Tabellen mit den folgenden Feldern:

Receipt(ItemID,Quantity) 

und

Warehouses(WarehouseID,Stock) 

|WarehouseID|Stock| 
------------------- 
|ARM01  |100 | 
|ARM02  |100 | 

Die Triggerüberprüft, ob eine Zeile mit einer bestimmten Menge an einem bestimmten Punkt eingeführt wurde, verändert oder auf einen Empfang entfernt und subtrahiert oder addiert dann zum Bestand der Warehouses-Tabelle.

Wenn ich also eine Zeile mit 200 Quantity in Receipt hinzufüge, wird 100 vom Bestand von WarehouseID 'ARM01' subtrahiert, und wenn es keinen Rest in 'ARM01' gibt (was nicht ist, weil es nur gibt 100), werden die anderen 100 von 'ARM02' subtrahiert. Natürlich, wenn 'ARM02' einen Vorrat von 0 hat, wird ein Fehler ausgegeben, aber darüber mache ich mir später Gedanken.

Die Sache ist, SQL Server akzeptiert kein WHERE in einem CASE, weil natürlich der gesamte CASE bereits Teil der SET-Anweisung ist und WHERE nur nach einer SET kommen. Es ist seltsam, aber ich konnte noch keine Antwort online für so eine einfache Sache finden.

Mein Ziel:

CASE 1 
UPDATE 'Stock of Table' where 'WarehouseID of Same Table' = 'ARM01' 
CASE 2 
UPDATE 'Stock of Table' where 'WarehouseID of Same Table' = 'ARM02' 

Ich habe auch bewusst das Kalkül für Lager -/+ Menge und umgekehrt könnten jetzt falsch sein, und ich habe auch 2 Aussagen in Klammern nach einem DANN, getrennt durch ein UND, weil ich versuchte, die ersten 100 zu ARM01 und den Rest zu ARM02 zu verteilen. Das ist wahrscheinlich sehr, sehr fehlgeleitet und entschuldigt mich für den falschen Code, aber im Moment möchte ich nur herausfinden, wo ich eine WHERE-Anweisung verwenden soll.

CREATE TRIGGER SubtractStock ON Receipt 
FOR INSERT, UPDATE, DELETE 
AS 
[snipped UPDATE for deleted because it only exchanges '+' for '-' in the operation] 
UPDATE Warehouses 
SET Stock = 
    (CASE 
     WHEN inserted.Quantity <= Stock THEN Stock - Quantity WHERE WarehouseID = 'ARM01' 
     WHEN inserted.Quantity > Stock THEN (Stock - Quantity WHERE WarehouseID = 'ARM01') 
     AND (Quantity - Stock WHERE WarehouseID = 'ARM02') 
     END) 
    FROM inserted JOIN Warehouses ON inserted.ItemID = Warehouses.ItemID 

Vielen Dank!

Antwort

1

Ich hasse Auslöser, und das ist eine schlechte Idee für einen. Mit dem aus dem Weg.

Für ARM01, die WHERE auf die bewegen, wenn sie mit einer UND:

SET Stock = 
    (CASE 
     WHEN inserted.Quantity <= Stock AND WarehouseID = 'ARM01' 
      THEN Stock - Quantity 
... 

Das nächste Problem ist, müssen zwei Zeilen zu sehen, die Lager für ARM02 zu setzen, was die Aktie in ARM02 ist, wenn zu sehen Sie müssen von ARM02 subtrahieren und den Bestand in ARM02 von subtrahieren. So bewegt sich der Zustand in dem wo woanders nicht helfen wird. Wahrscheinlich zwei update-Anweisungen, update ARM01, mit einer output-Klausel in eine temporäre Tabelle oder eine Tabellenwertvariable, um vor den Bestandswerten für ARM01 zu geben, und benutze diese, um die Werte für ARM02 zu aktualisieren.

Wieder ist diese Art von komplizierter Logik selten in einem Trigger geeignet.

+0

ich sehe. Ich machte dies als Übung für ein persönliches Projekt, nachdem ich gelernt hatte, wie man Auslöser erzeugt, daher ist der komplizierte Ansatz vielleicht nicht die beste Idee. Ihre Erklärung, was ich als nächstes tun müsste, fällt ein bisschen mit dem zusammen, was ich erwartet hatte. Vielen Dank! – NinjaBaseballBatMan

0

Bitte versuchen Sie es so ... Geeignetes Aliase ..

CREATE TRIGGER SubtractStock ON Receipt 
FOR INSERT, UPDATE, DELETE 
AS 
UPDATE W 
SET Stock = CASE 
      WHEN WarehouseID = 'ARM01' AND I.Quantity <= Stock THEN Stock - Quantity 
      WHEN WarehouseID = 'ARM01' AND I.Quantity > Stock THEN Stock - Quantity 
      WHEN WarehouseID = 'ARM02' THEN I.Quantity - Stock 
     END 
FROM inserted I JOIN Warehouses W ON I.ItemID = W.ItemID