Fast jeder Datenbankentwickler hat bereits seine Erfahrungen mit Benutzerdefinierten Sequenzen, Künstlichen Schlüsseln (engl. Surrogate Keys) oder ähnlichen Mechanismen sammeln können. In solchen Fällen bekommt eine Spalte einen neuen Wert zugewiesen, und dieser Wert wird anschließend weiterverarbeitet. |
Dies möchte ich an folgenden Beispiel zeigen:
In einer Lagerverwaltung soll der Bestand eines Artikels verändert werden können.
Der neue Lagerbestand wird anschließend mittels Ausgabeparameter zurückgegeben.
Der klassische Lösungsansatz
Beim klassischen Lösungsansatz werden zwei SQL Befehle, die in einer expliziten Transaktion eingebettet sind, verwendet.
CREATE PROCEDURE [Lager].[ArtikelbestandAktualisieren] ( @ArtikelID INT , @Veraenderung INT , @NeuerBestand INT OUTPUT ) AS BEGIN TRY -- Starte explizite Transaktion BEGIN TRANSACTION; -- Aktualisiere den Lagerbestand UPDATE [Lager].[Lagerbestand] SET [Anzahl] = [Anzahl] + @Veraenderung WHERE [ArtikelID] = @ArtikelID; --Neuen Bestand abfragen SET @NeuerBestand = ( SELECT [Anzahl] FROM [Lager].[Lagerbestand] WHERE [ArtikelID] = @ArtikelID); COMMIT TRANSACTION; END TRY BEGIN CATCH DECLARE @ErrorMessage NVARCHAR(4000) , @ErrorSeverity INT , @ErrorState INT; SELECT @ErrorMessage = Error_message() , @ErrorSeverity = Error_severity() , @ErrorState = Error_state(); RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState); ROLLBACK TRANSACTION; END CATCH;
Die "@Variable = Column = Expression" Syntax
Die elegantere Lösung verwendet die "@Variable = Column = Expression" Syntax.
CREATE PROCEDURE [Lager].[ArtikelbestandAktualisieren] ( @ArtikelID INT , @Veraenderung INT , @NeuerBestand INT OUTPUT ) AS -- Aktualisieren und Wertrückgabe in einem Befehl -- und somit in einer impliziten Transaktion UPDATE [Lager].[Lagerbestand] SET @NeuerBestand = [Anzahl] = [Anzahl] + @Veraenderung WHERE [ArtikelID] = @ArtikelID;