Dienstag , 21 Mai 2019

SQL Syntax: @variable = column = expression

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.
SQL Server 2008

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;