Was ist UPDATE FROM?
Wenn Ihr Werte in Tabellen UPDATE
n möchtet, dann sieht ein Skript oftmals so aus, dass Ihr einer Spalte einen neuen Wert (der sich auch aus anderen Werten ableiten kann) zuweist. Doch wie funktioniert das, wenn die anderen Werte aus einer anderen Tabelle kommen? Dann braucht ihr ein UPDATE FROM
.
Wie könnt ihr mit UPDATE FROM arbeiten?
Beginnen wir mit einem einfachen Update, erhöhen wir in der Wideworld Importers Datenbank den UnitPrice
aller USB-Produkte in der Warehouse StockItems
-Tabelle um 10%:
UPDATE Warehouse.StockItems SET UnitPrice = UnitPrice*1.1 WHERE StockItemName LIKE '%USB%' SELECT @@ROWCOUNT
Damit haben wir den Preis von 14 Produkten erhöht. Nun möchten wir im Sales
-Schema die OrderLines
anpassen mit den neuen Preisen (auch wenn das natürlich kein Real-World-Szenario darstellt, da wir da keine abgeschlossenen Bestellungen ändern würden). Wir könnten jetzt natürlich ein Konstrukt machen, das wie folgt aussieht
UPDATE Sales.OrderLines SET UnitPrice = UnitPrice*1.1 WHERE StockItemID IN ( SELECT StockItemID FROM Warehouse.Stockitems WHERE StockItemName LIKE '%USB%' )
Das ist allerdings insofern etwas unschön als wir hier einerseits die Berechnung explizit anwenden müssten und dass wir andererseits den Filter auf die USB-Items wieder direkt gesetzt haben. Das können wir umgehen, indem wir einen JOIN
verwenden, um die Items mit geänderten Preisen zu finden:
SELECT ol.[OrderLineID] ,ol.[OrderID] ,ol.[StockItemID] ,ol.[Description] ,ol.[PackageTypeID] ,ol.[Quantity] ,ol.[UnitPrice] ,ol.[TaxRate] ,ol.[PickedQuantity] ,ol.[PickingCompletedWhen] ,ol.[LastEditedBy] ,ol.[LastEditedWhen] FROM Sales.OrderLines ol INNER JOIN Warehouse.StockItems si ON ol.StockItemID = si.StockItemID AND si.UnitPrice <> ol.UnitPrice
Diesen JOIN
können wir nun auch verwenden, um die Preise auf den 14.834 OrderLines zu ändern, bei denen die Preise nicht mehr zur aktualisierten StockItems-Tabelle passen:
UPDATE ol SET UnitPrice = si.UnitPrice FROM Sales.OrderLines ol INNER JOIN Warehouse.StockItems si ON ol.StockItemID = si.StockItemID AND si.UnitPrice <> ol.UnitPrice SELECT @@ROWCOUNT
Zusammen mit CTEs und allen möglichen JOIN
– und WHERE
-Bedingungen ergeben sich so die interessantesten UPDATE
-Konstrukte. Es empfiehlt sich bei einem solchen UPDATE
(wie generell bei jedem UPDATE
) allerdings, eine Runde im Dojo zu drehen und zunächst per SELECT
zu prüfen, ob denn nun auch wirklich nur die Zeilen aktualisiert werden, die auch aktualisiert werden sollen…