Announcement

Collapse
No announcement yet.

Auswerten von Resultsets in SPs unter TSQL

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Auswerten von Resultsets in SPs unter TSQL

    Hallo!<br>
    <br>
    Ich versuche eine SP zu schreiben, welche das Ergebnis (das Resultset
    einer SELECT-Abfrage) zweier anderer SPs per UNION zusammenfassen sollen.
    Mein erster Ansatz sah so aus:<br>
    <br><b>
    Alter Procedure ListeAuftragPositionTyp<br>
    @PositionTyp int<br>
    As<br>
    Execute ListeAuftraegeOhnePosition<br>
    Union<br>
    Execute ListeAuftraegeMitPosition @PositionTyp<br>
    <br></b>
    So klappt das nicht, da der Union-Operator zwischen zwei Select-Anweisungen
    stehen muß. Wenn ich das Union weglasse, funktioniert die SP, aber ich
    erhalte 2 Resultsets, von denen ich nur eines angezeigt bekomme.<br>
    <br>
    Vielleicht kennt ja jemand von euch die Lösung. Temporäre Tabellen wollte
    ich allerdings hier vermeiden.<br>
    <br>
    Ulrich<br>

  • #2
    Hallo,

    ADO sieht über die Methode <b>NextRecordset</b> einen Weg vor, das zweite Recordset abzufordern

    Comment


    • #3
      Hi!<p>
      <p>
      Eigentlich suche ich nach einer Loesung, welche das Problem in <b>TSQL</b> loest,
      und nicht in VBA. Ich konnte das obige Problem vorerst beheben, indem ich die entsprechenden Selects einkopiert habe. Das Ergebnis soll in einem Listenfeld angezeigt werden koennen, wofuer ein einzelnes Recordset nach meiner Information noetig ist.<p>
      <p>
      Jetzt habe ich aber folgende Abfrage:<p>
      <p><b>
      Alter Procedure ListeLagerKontakt<p>
      @KontaktID int,<p>
      @Jahr int<p>
      As<p>
      Select<p>
      L1.ArtikelID,<p>
      L1.Datum,<p>
      Artikel.Bezeichnung as Artikel,<p>
      L1.Menge - IsNull ((<p>
      Select Sum(L2.Menge)<p>
      From Lieferung As L2<p>
      Where L2.Jahr1900 = (@Jahr-1900) And L2.LieferungStatus=1 And L2.VonLieferungID = L1.LieferungID<p>
      ),0) As Bestand<p>
      From Lieferung As L1 Inner Join Artikel On (L1.ArtikelID = Artikel.ArtikelID)<p>
      Where L1.Jahr1900 = (@Jahr-1900) And L1.LieferungStatus=1 And L1.NachKontakt = @KontaktID<p>
      Order By Artikel.Bezeichnung, L1.Datum<p>
      <p></b>
      Hierbei können Datensaetze mit Bestand 0 entstehen, welche ich aber aus dem Ergebnis loeschen will. Ich moechte
      vermeiden, dass ich die komplette Bestandberechnung mit dem Subselect in der Whereklausel wiederholen muss.<p>
      <p>
      Daher habe ich ein paar konkrete Fragen, die ich mittels meiner Doku nicht klaeren konnte:<p>
      <p>
      1. Gibt es einen Datentyp der Art "resultset", mit dem ich Ergebnisse fuer die weitere Verwendung einer<p>
      Variablen zuweisen kann (in TSQL!)?<p>
      2. Gibt es parametrisierte Views?<p>
      3. Kann ich ueberhaupt das Ergebnis (ein Resultset) von parametrierten Abfragen in TSQL weiterverwenden,<p>
      wenn ja, wie?<p>
      4. Wie kann ich einen Namen für eine temporaere Tabelle generieren lassen, der garantiert von keinem<p>
      anderen Benutzer benutzt wird.<p>
      <p>
      Vielen Dank schonmal fuer die Hilfe!<p>
      <p>
      Ulrich<p&gt

      Comment


      • #4
        Hallo,

        zu Frage 1: <br>
        Das RecordSet-Objekt von ADO speichert die Ergebnismenge (Resultset), daher hat TSQL keinen direkten Zugriff darauf.

        zu Frage 2: <br>
        Es gibt parametisierte Stored Procedures, die eine Ergebnismenge zurückliefern können. Ein View ist jedoch nur eine Sicht-Tabelle, oder anders gesagt, eine "benannte SELECT-Abfrage". Und da einem SELECT keine Parameter übergeben werden können, muss man dann auf die Stored Procedures ausweichen.

        zu Frage 3: <br>
        Ja - wenn ein CURSOR für die SELECT-Abfrage deklariert wird. Über diesen CURSOR kann man dann zeilenweise durch die Ergebnismenge gehen (d.h. ein Fetch innerhalb der Stored Procedure auslösen) und die vorgefundenen Daten auswerten.

        zu Frage 4: <br>
        Wenn das Zeichen <b>#</b> einem Tabellennamen vorangestellt wird, erhält man eine private temporäre Tabelle, die nur für die Verbindung sichtbar ist, über die diese Tabelle angelegt wurde

        Comment


        • #5
          Hallo,

          ich hätte mal ne Frage zu Punkt 2.

          Wie schaut das mit der Ergebnismenge aus und wie kann ich da dann draufzugreifen. Am besten wäre ein kurzes Code BSP.

          Danke MFG

          thomas her

          Comment


          • #6
            Hallo,

            das könnte so aussehen (das Beispiel verwendet die Microsoft-Beispieldatenbank <i>Northwind</i>:
            <pre>
            CREATE PROCEDURE SPGetCustomer
            @sID VARCHAR(20)
            AS
            SELECT * FROM Customers WHERE CustomerID = @sID
            -- Anzahl der Treffer zurückliefern
            Return @@ROWCOUNT
            </pre&gt

            Comment


            • #7
              In diesen Beispiel bekomme ich einn einzigen Wert und keine Menge zurück. Das Ergebnis soll eine Menge sein und wie kann ich auf der Menge navigieren

              Comment


              • #8
                Hallo,

                in diesem Fall muss die WHERE-Einschränkung geändert werden:
                <pre>
                CREATE PROCEDURE SPGetCustomer
                @sID VARCHAR(20)
                AS
                SELECT * FROM Customers WHERE CustomerID > @sID
                -- Anzahl der Treffer zurückliefern
                Return @@ROWCOUNT
                </pre>
                Wenn man dann mit Delphi 5 und ADO Express auf diese Stored Procedure zugreift, erhalte ich alle zutreffenden Datensätze im TDBGrid und kann mit einer TDBNavigator-Instanz durch die Datenmenge browsen:
                <pre>
                object Form1: TForm1
                Left = 192
                Top = 107
                Width = 696
                Height = 480
                Caption = 'Form1'
                Color = clBtnFace
                Font.Charset = DEFAULT_CHARSET
                Font.Color = clWindowText
                Font.Height = -11
                Font.Name = 'MS Sans Serif'
                Font.Style = []
                OldCreateOrder = False
                PixelsPerInch = 96
                TextHeight = 13
                object DBGrid1: TDBGrid
                Left = 24
                Top = 56
                Width = 320
                Height = 120
                DataSource = DataSource1
                TabOrder = 0
                TitleFont.Charset = DEFAULT_CHARSET
                TitleFont.Color = clWindowText
                TitleFont.Height = -11
                TitleFont.Name = 'MS Sans Serif'
                TitleFont.Style = []
                end
                object ADOConnection1: TADOConnection
                Connected = True
                ConnectionString =
                'Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initi' +
                'al Catalog=Northwind;Data Source=(local);Use Procedure for Prepa' +
                're=1;Auto Translate=True;Packet Size=4096;Workstation ID=G7-800;' +
                'Use Encryption for Data=False;Tag with column collation when pos' +
                'sible=False'
                LoginPrompt = False
                Provider = 'SQLOLEDB.1'
                Left = 24
                Top = 24
                end
                object ADODataSet1: TADODataSet
                Active = True
                Connection = ADOConnection1
                CursorType = ctStatic
                CommandText = 'SPGetCustomer;1'
                CommandType = cmdStoredProc
                Parameters = <
                item
                Name = '@RETURN_VALUE'
                DataType = ftInteger
                Direction = pdReturnValue
                Precision = 10
                Value = 91
                end
                item
                Name = '@sID'
                Attributes = [paNullable]
                DataType = ftString
                Size = 20
                Value = 'A'
                end>
                Left = 64
                Top = 24
                end
                object DataSource1: TDataSource
                DataSet = ADODataSet1
                Left = 96
                Top = 24
                end
                end
                </pre&gt

                Comment


                • #9
                  Schade, leider kann ich kein Delphi, kann man das auch unter VB erklähren, ich komme nämlich immer nur auf den letzten DS.

                  MFG

                  tompso

                  Comment


                  • #10
                    Hallo,

                    dank ADO ist die Sprache und die Entwicklungsumgebung völlig egal, sowohl Delphi als auch VB greifen auf das RecordSet-Objekt von ADO zurück. Ich stelle mein Delphi-Beispiel einmal so um, wie man es von der Reihenfolge und den Elementen her auch in VB schreiben würde:
                    <pre>
                    var
                    aConnection : _Connection;
                    aCommand : _Command;
                    aParam : _Parameter;
                    aRS : _RecordSet;
                    vName : OleVariant;
                    vRowsAffected: OleVariant;
                    iReturnValue : Integer;
                    swData : WideString;
                    begin
                    aConnection := CoConnection.Create;
                    aConnection.Open(cCS, '', '', adOpenForwardOnly);
                    try
                    aCommand := CoCommand.Create;
                    try
                    with aCommand do
                    begin
                    CommandType := adCmdStoredProc;
                    CommandText.....
                    ... Parameter-Objekte zuweisen

                    aRS := Execute(vRowsAffected, EmptyParam, adOptionUnspecified);
                    iReturnValue := Parameters[0].Value;
                    iRecCount := aRS.Get_RecordCount;
                    swData := aRS.GetString(adClipString, iRecCount,
                    '; ', #13#10,'(NULL)');
                    ShowMessage(swData);
                    ...
                    </pre>
                    Am Ende werden alle Datensätze in einer MessageBox angezeigt, ShowMessage sollte sich in VB durch MsgBox (?) ersetzen lassen

                    Comment

                    Working...
                    X