Announcement

Collapse
No announcement yet.

stored proc - Insert + Selcet Rückgabe Null

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

  • stored proc - Insert + Selcet Rückgabe Null

    Wenn ich über Delphi 6.0 Upd 1, ADO 2.6 über eine ADOStoredProc die folgende SP auf MS SQL 2000 ausführe bekomme ich keinen Datensatz zurückgeliefert.
    Schließe ich das Programm starte es neu, so Erhalte ich den vorher eingetragenen Datensatz. Im Query Analyzer erhalte ich direkt wie erwartet den Datensatz nach dem Einfügen.
    Woran könnte das liegen?
    ***
    CREATE PROCEDURE SetNEWArtikel @MandantID int, @FilialID int, @Artnr nvarCHAR (40), @ARTID int OUTPUT AS
    Select * from artikel where MANDANTID = @MandantID and FilialID = @FilialID and Artnr = @Artnr
    if @@rowcount = 0
    BEGIN
    Insert into Artikel (mandantid,filialid,artnr) values (@Mandantid,@filialID,@artnr)
    END
    Select * from artikel where MANDANTID = @MandantID and FilialID = @FilialID and Artnr = @Artnr
    GO
    ****

  • #2
    Hallo,

    die Ursache für diese Probleme liegt darin, dass die Stored Procedure verschiedene Operationen (SELECT, INSERT, SELECT) ausführt und somit auch verschiedene Recordsets im Spiel sind. Um das Problem zu lösen, ist der Rückgriff auf <b>NextRecordset</b> notwendig - wie das folgende Beispiel demonstriert:

    a) Beispieldatenbank
    <pre>
    USE tempdb
    GO
    CREATE TABLE SPTEST (
    RecNo INTEGER NOT NULL PRIMARY KEY,
    Wert VARCHAR(40) NOT NULL)
    GO

    CREATE PROCEDURE spSPTEST
    @iRecNo INTEGER,
    @sWert VARCHAR(40)
    AS
    DECLARE @iMode INTEGER
    SET NOCOUNT ON
    SELECT * FROM SPTEST WHERE RecNo = @iRecNo
    IF @@rowcount = 0
    BEGIN
    INSERT INTO SPTEST (RecNo,Wert) VALUES (@iRecNo,@sWert)
    SET @iMode = 1
    END
    SELECT * FROM SPTEST WHERE RecNo = @iRecNo
    SET NOCOUNT OFF
    RETURN @iMode
    GO

    EXEC spSPTEST 1, 'Test 1a'
    EXEC spSPTEST 2, 'Test 1a'
    EXEC spSPTEST 1, 'Test 1b'
    SELECT * FROM SPTEST
    GO
    </pre>
    b) Beispielaufruf: Immer dann, wenn zuerst ein INSERT und erst danach das SELECT von der Stored Procedure abgearbeitet wird, muss der Client seinen Interface-Zeiger auf das 2. Recordset umhängen (Recordset-Methode <b>NextRecordset</b>), um an die Ergebnismenge der letzten SELECT-Abfrage zu kommen:
    <pre>
    uses ADOInt;

    procedure TForm1.Button1Click(Sender: TObject);
    var
    vAffected : OleVariant;
    iReturn : Integer;
    aRS : _Recordset;
    begin
    ADODataSet1.Active := False;
    ADODataSet1.Connection := ADOConnection1;
    ADODataSet1.Parameters[1].Value := StrToInt(Edit1.Text);
    ADODataSet1.Parameters[2].Value := Edit2.Text;
    ADODataSet1.Active := True;
    iReturn := ADODataSet1.Parameters[0].Value;
    if iReturn = 1 then
    begin
    aRS := ADODataSet1.Recordset;
    ADODataSet1.Active := False;
    ADODataSet1.Connection := nil;
    ADODataSet1.Recordset := aRS.NextRecordset(vAffected);
    ADODataSet1.Active := True;
    end;
    end;
    </pre>
    c) Konfiguration im Objektinspektor
    <pre>
    object ADOConnection1: TADOConnection
    Connected = True
    ConnectionString =
    'Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security In' +
    'fo=False;Initial Catalog=tempdb;Data Source=.'
    LoginPrompt = False
    Provider = 'SQLOLEDB.1'
    Left = 16
    Top = 8
    end
    object ADODataSet1: TADODataSet
    Connection = ADOConnection1
    CommandText = 'spSPTEST;1'
    CommandType = cmdStoredProc
    Parameters = <
    item
    Name = '@RETURN_VALUE'
    DataType = ftInteger
    Direction = pdReturnValue
    Precision = 10
    end
    item
    Name = '@iRecNo'
    Attributes = [paNullable]
    DataType = ftInteger
    Precision = 10
    end
    item
    Name = '@sWert'
    Attributes = [paNullable]
    DataType = ftString
    Size = 40
    end>
    Left = 56
    Top = 8
    end
    </pre&gt

    Comment


    • #3
      Hallo Jan,<BR><BR>
      das Verhalten liegt darin begründet, dass immer nur das erste <B>Select</B> innerhalb einer <B>Stored Procedure</B> an das <B>ADODataSet</B> zurück geliefert wird, nicht das letzte. Teste es einmal aus, indem du eine <B>Procedure</B> schreibst, die nichts anderes macht, als zwei unterschiedliche Ergebnismengen der gleichen Tabelle zurück zu liefern. Nach dem öffnen wirst du sehen, dass es immer die erste ist.<BR>
      Im obigen Beispiel könntest du dir helfen, indem du nicht zuerst das <B>Select</B> ausführst und dann <B>@@RowCount</B> auswertest, sondern die Funktion <B>if exists(select ...)</B> benutzt.
      Ich hoffe, das hilft dir.<BR><BR>Ola

      Comment

      Working...
      X