head.WriteLine()

Montag, September 25, 2006

Austausch von Daten zwischen Stored Procedures

Daten über eine Stored Procedure zu ermitteln und auszugeben ist ja relativ einfach. Schwieriger wird es jedoch, wenn Daten zwischen verschiedenen Prozeduren ausgetauscht werden sollen.

Hierfür gibt es zwei Lösungswege:

  • Austausch über einen Cursor
  • Verwendung einer TABLE-Variable

Austausch über einen Cursor

Hierbei deklariert die aufgerufene Prozedur einen Cursor als OUTPUT-Parameter.

Das folgende Beispiel demonstriert die Vorgehensweise:

CREATE PROCEDURE CursorPublisher
    @Cursor CURSOR VARYING OUTPUT
AS
    SET @Cursor = CURSOR STATIC FOR
    SELECT FirstName, LastName FROM Person.Contact

    OPEN @Cursor
GO

Hierbei wird der Cursor durch die Prozedur befüllt und geöffnet.

Der Aufrufer definiert nun einen Cursor gleichen Aufbaus übergibt ihn der Prozedur als Parameter. Im Anschluß kann das Ergebnis in einer Schleife durchlaufen und die Werte ausgegeben werden.

CREATE PROCEDURE CursorConsumer AS
    DECLARE @Cursor CURSOR
    DECLARE @FirstName nvarchar(50),
            @LastName nvarchar(50)

    SET NOCOUNT ON

    EXEC CursorPublisher @Cursor OUTPUT

    WHILE (@@FETCH_STATUS = 0)
    BEGIN
        FETCH NEXT FROM @Cursor INTO @FirstName, @LastName
        PRINT 'FirstName=' + @FirstName
        PRINT 'LastName=' + @LastName
    END

    DEALLOCATE @Cursor
GO

Verwendung einer TABLE-Variable

Es gibt jedoch eine wesentlich einfachere und effizientere Methode das gleiche zu erreichen. Hierbei gibt die aufgerufene Prozedur die Ergebnisse in Form eines normalen Resultsets zurück:

CREATE PROCEDURE ResultsetPublisher
AS
    SELECT FirstName, LastName FROM Person.Contact
GO

Der Aufrufer definiert nun anstelle eines Cursors eine TABLE-Variable, die das Ergebnis aufnimmt.

CREATE PROCEDURE ResultsetConsumer
AS
    DECLARE @Resultset TABLE
    (
        FirstName nvarchar(50),
        LastName nvarchar(50)
    )

    SET NOCOUNT ON

    INSERT INTO @Resultset
    EXEC ResultsetPublisher

    SELECT * FROM @Resultset
GO

Das Befüllen der Variable wird hierbei über INSERT INTO in Kombination mit EXEC vollzogen.

Neben der leichteren Implementierung, hat diese Variante noch weitere Vorteile:

  • Das Ergebnis kann mit anderen Tabellen, Views, Funktionen oder TABLE-Variablen verknüpft werden
  • Der Zugriff ist schneller, da hierbei mengen- und nicht zeilenorientiert gearbeitet wird
  • Die Prozedur kann auch ohne weiteres von Client-Anwendungen aufgerufen werden

Aber entscheiden Sie selbst!