Announcement

Collapse
No announcement yet.

SQL-Abfrage: mal funktioniert sie und mal nicht

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

  • SQL-Abfrage: mal funktioniert sie und mal nicht

    Ich greife mit Delphi über die nativen ADO-Objekte auf den SQL-Server (MSDE - lokal) zu und habe mir zu diesem Zweck eine Klasse u.a. mit folgender Methode für SQL-Abfragen geschrieben:

    <PRE>
    procedure TJMAdoExeQySp.ExecQry;
    {Führt eine Abfrage auf dem SQL-Server aus
    Setzt ggf. Parameter (wenn FWithPara = true)
    Gibt ggf. Datenmenge zurück (wenn FResSet = true)
    Property Done wird entsprechend gesetzt}
    var i: smallint;
    aCon: _Connection;
    aCommand: _Command;
    aRS: _Recordset;
    vRows: OLEVariant;
    begin
    // ======
    // Prolog
    // ======
    if not FDone then Exit;
    gs_AdoErrorList.Clear; // Eigene Fehlerliste leeren
    // =================================
    // Verbindung vorbereiten und öffnen
    // =================================
    aCon := coConnection.Create; // Connection-Objekt
    aCon.CursorLocation := adUseClient;
    try
    aCon.Open(FConstr,'','',adConnectUnspecified);
    except
    FDone := JMAdo_GetErrorsFromConObject(aCon);
    end; // try except
    if FDone then begin
    // ==========================
    // Command-Objekt vorbereiten
    // ==========================
    aCommand := CoCommand.Create;
    with aCommand do begin
    CommandType := adCmdText;
    CommandText := FCommandText; // Abfragetext
    // ====================
    // Parameter einrichten
    // ====================
    if FWithPara then
    // Input-Parameter erzeugen und mit Daten besetzen
    for i := 0 to High(FParProps) do begin
    Parameters.Append
    (CreateParameter(FParProps[i].PN,FParProps[i].DT,
    adParamInput,FParProps[i].FL,
    EmptyParam));
    // Ggf Precision und NumericScale setzen
    if (FParProps[i].DT = adNumeric) or
    (FParProps[i].DT = adDecimal) then begin
    Parameters[i].Precision :=
    FParProps[i].PR;
    Parameters[i].NumericScale :=
    FParProps[i].NS;
    end; // if (FParProps[i].DT
    end; // for i
    // =========================================
    // Command- mit Connenction-Objekt verbinden
    // =========================================
    try
    Set_ActiveConnection(aCon);
    except
    FDone := JMAdo_GetErrorsFromConObject(aCon);
    end; // try except
    end; // with aCommand
    if FDone then begin
    // ============================
    // Ggf. Parameterwerte zuweisen
    // ============================
    if FWithPara then
    for i := 0 to High(FParValues) do
    aCommand.Parameters[i].Value := FParValues[i];
    // =========================================
    // Ggf Recordset erzeugen und Daten versehen
    // =========================================
    if FResSet then begin
    aRS := CoRecordset.Create;
    aRS.CursorLocation := adUseClient;
    end; // if aeprRes in FExeKindParaRes
    // ==================
    // Kommando ausführen
    // ==================
    try
    if FResSet then
    // wenn Datenmenge geliefert wird
    // im Recordset-Objekt Datenmenge öffnen
    aRS.Open(aCommand,EmptyParam,adOpenStatic,
    adLockBatchOptimistic,adCmdUnspecified)
    else // wenn keine Datenmenge geliefert wird
    // Abfrage im Command-Objekt ausführen
    aCommand.Execute(vRows,EmptyParam,
    adExecuteNoRecords);
    except
    FDone := JMAdo_GetErrorsFromConObject(aCon);
    end; // try except
    // ==========================
    // Ggf. Datenmenge übernehmen
    // ==========================
    if FDone and FResSet then GetAdoDataSet(aRS);
    end; // if FDone
    end; // if FDone
    // ======
    // Epilog
    // ======
    // Aufräumen
    if FResSet then begin
    if FDone then aRs.Close;
    if aRS <> nil then aRS := nil;
    end; // if aeprRes in FExeKindParaRes
    if aCommand <> nil then aCommand := nil;
    if FDone then aCon.Close;
    aCon := nil;
    end; // ExecQry
    </PRE>
    Die Routine baut die Verbindung zum Server mit einem Connenction-Objekt auf und erzeugt ggf. ein Command- und ein Recordset-Objekt. Flag-gesteuert werden ggf. Parameter zugewiesen und ggf. wird mit Recordset die Datenmenge abgeholt. Zuletzt wird alles wieder geschlossen und die Verbindung abgebaut.

    Wird mit dieser Methode eine SQL-Afrage ausgeführt, erhalte ich meistens zunächst die Fehlermeldung
    "Falsche Syntax in der Nähe von 1"
    Native Error: 170
    ADO-Fehler: -2147217900
    SQL-Fehlercode: 42000
    Die SQL-Abfragen waren bisher parameterlos.

    Das merkwürdige ist: Wird die Abfrage unmittelbar wiederholt, ist alles ok. Das Verhalten ist reproduzierbar. Interessant ist auch, dass auch alles ok ist, wenn ich das Programm in Delphi starte und die Routine mit dem Debugger durchtackere. Liegt da evtl. ein Zeitproblem vor ????

    Ich weiss mir jetzt keinen Rat mehr und wäre dankbar um einen solchen.

    Mein PC: AMD-Prozessor, WindowsXp Prof, kein SP2, MSDE, Delphi7

    Mit freundlichem Gruss

    Hans Grigull

  • #2
    Eine Eränzung. Die Fehlermedung muss vollständig heißen: "Zeile 2: Falsche Syntax in der Nähe von 1".

    Außerdem kommt es auch vor, dass die Meldung selbst dann ausgegeben wird, wenn die SQL-Abfrage richtig ausgeführt wurde.

    Das ganze wird ziemlich mysteriös

    Comment


    • #3
      Hallo,

      &gt;..dass die Meldung selbst dann ausgegeben wird, <br>
      &gt;wenn die SQL-Abfrage richtig ausgeführt wurde.

      auf der Hilfeseite zum Fehler 170 ist unter anderem der folgende Satz zu lesen: "<i>Die Transact-SQL-Syntax kann sehr komplex sein, weshalb Microsoft SQL Server den Syntaxfehler möglicherweise <b>später</b> in der Transact-SQL-Anweisungssyntax meldet, als er tatsächlich aufgetreten ist.</i>". Wie sehen die ersten beiden Zeilen der betroffenen SQL-Anweisung aus

      Comment


      • #4
        Es handelte sich um normale SELECT-Anweisungen. Das beschriebene Verhalten zeigte sich jedoch nicht nur in einer bestimmten sondern in mehreren unterschiedlichen Abfragen in dem ersten Projekt, das ich auf die MSDE umstelle.

        Darüber hinaus habe ich derzeit Grund zu der Annahme, die Ursache gefunden zu haben: Ich hatte die MSDE mit DISABLENETWORKPROTOCOLS = 0 installiert. Nachdem ich die MSDE deinstaliert und neu per Default mit DISABLENETWORKPROTOCOLS = 1 installiert habe, tritt das beschriebene Verhalten nicht mehr auf. Sollte das mit den von MS vorgenommenen Einschränkungen der MSDE zusammenhängen? Wenn ja, wäre die MSDE offenbar nur local verwendbar

        Comment

        Working...
        X