Announcement

Collapse
No announcement yet.

Update-Command (wurde das ausgeführt?)

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

  • Update-Command (wurde das ausgeführt?)

    Hallo,
    hab mal eine Frage zu Update-Commands (TADO-Command). Ich habe eine Delphi2006-Anwendung, die eine Menge Daten in am MSSQL-Server aktualisiert. Es handelt sich um Aufträge bzw. Lieferscheine, wo Informationen aus einer Textdatei gelesen werden, und mit Hilfe dieser Informationen die Datensätze in der Datenbank upgedatet werden. Bei mir in allen Tests geht das ganz prima, aber beim Kunden habe ich das Problem, dass teilweise Update-Commands nicht ausgeführt werden. Irgendwie sieht das so aus, als wäre das Programm zu schnell und würde teilweise Commands überspringen.

    Frage: Kann man irgendwie überprüfen bzw. das Programm so lange warten lassen, bis die Aktualisierung auf jeden Fall durchgeführt wurde ?

    Grüße
    Holger

  • #2
    Vielleicht eine dumme Möglichkeit, aber kann ich mit dem Event "OnExecuteComplete" arbeiten und dort abfragen, ob der Status des Commands OK ist ? Nach folgendem Beispiel:

    procedure TFmLSAbgleich.ADOExecuteComplete(Connection: TADOConnection;
    RecordsAffected: Integer; const Error: Error; var EventStatus: TEventStatus;
    const Command: _Command; const Recordset: _Recordset);
    begin
    if EventStatus = esOK then
    begin
    AktualisierungErfolgreich := True;
    end;
    end;

    Und dann bei der Ausführung des Commands folgendes:

    AktualisierungErfolgreich := False;
    while AktualisierungErfolgreich = False do
    begin
    try
    Command1.Execute;
    except
    end;
    end

    Comment


    • #3
      Hallo,
      das Problem hat nichts mit dem SQL Server (oder SQL) zu tun, sondern statt dessen mit den Delphi-Eigenheiten von <i>dbGo</i> (alias <i>ADO Express</i>). Da <i>TADOCommand</i> nur eine Wrapper-Komponente für das native <i>Command</i>-Objekt von ADO ist und die dbGo-Komponenten in bestimmten Situationen die Verbindung zu den darunterliegenden nativen ADO-Objektinstanzen verlieren, schlage ich in derartigen Fällen generell vor, die Implementierung auf die nativen ADO-Objekte (Connection, Command) umzustellen. Der Aufwand ist dann zwar etwas höher, aber dafür arbeiten die originalen ADO-Objekte recht zuverlässig. In meinem Buch <i>ADO und Delphi</i> sind dazu Beispiele zu finden.
      <br>
      Das TADOCommand-Ereignis <i>OnExecuteComplete</i> hilft nicht weiter, da das Problem ja darin besteht, dass TADOCommand die Verbindung zum ADO-Objekt verliert und hinter den Kulissen beim nächsten Aufruf eine neue Instanz hervorgezaubert wird

      Comment


      • #4
        Hallo Herr Kosch,
        ihr Buch habe ich natürlich auf meinem Schreibtisch parat und auch die Umsetzung auf den nativen Zugriff für das command-Objekt umgestellt. Eine Frage dazu habe ich aber noch.

        Mein Programm durchläuft mit den dbGo-Komponenten mehrere Datasets und aktualisiert dann immer mal mit dem Command einzelne Datensätze. Sollte ich die Datasets auch auf den nativen Zugriff umstellen oder ist ein Dataset zuverlässiger und kann als VCL-Komponente bestehen bleiben ?

        Viele Grüße
        Holger Löttge

        Comment


        • #5
          Hallo,
          wenn alle TADOCommand- und TADODataSet-Instanzen über den Objektinspektor visuell konfiguriert werden (d.h. die darunterliegenden SQLs zur Laufzeit niemals ausgetauscht werden), ist der Rückgriff auf TADODataSet sinnvoll (weil produktiver). Erst dann, wenn man auf Probleme stößt, führt der 1. Weg über die nativen ADO-Objekte (denn bei einem Fehlverhalten der Anwendung spielt Produktivität des Entwicklers keine Rolle mehr)

          Comment


          • #6
            Danke für die Antwort, Andreas,
            das ich bisher immer nur (aus bequemlichkeitsgründen) mit den gekappselten TADO-Komponenten gearbeitet habe, diese mir aber echt zu unzuverlässig sind, möchte ich gerne auf den nativen Zugriff umsteigen. Hast Du für mich vielleicht ein Beispiel,, wie ich ein Recordset unter zuhilfenahme von Parametern bekomme ?
            Für das Command-Objekt habe ich in Deinem Buch ein wunderbares Beispiel gefunden, aber eine "DataSet-Abfrage" mit Parametern habe ich nicht gefunden. Gibts dafür ein Beispiel ?

            Viele Grüße
            Holge

            Comment


            • #7
              Hallo,
              die Konfiguration des <i>Command</i>Objekts reicht aus, denn diese Instanz kann ja bei der Methode <b>Open</b> des <i>Recordset</i>-Objekts als Parameter übergeben werden:
              <code>
              <b>var</b>
              iRet : Integer;
              aCon : _Connection;
              aRS : _Recordset;
              aCmd : _Command;
              vRows : OleVariant;
              <br>
              <b>procedure</b> AddParamObj(<b>const</b> sName: <b>String</b>; iType,iParam,iSize: Integer);
              <b>var</b>
              aParam : _Parameter;
              <b>begin</b>
              <b>with</b> aCmd <b>do</b>
              <b>begin</b>
              aParam := CreateParameter(sName, iType, iParam,iSize, EmptyParam);
              Parameters.Append(aParam);
              <b>end</b>;
              <b>end</b>;
              <br>
              <b>begin</b>
              <b>try</b>
              aCon := CoConnection.Create;
              aCon.CursorLocation := adUseClient;
              aCon.Open(FConnStr, <font color="#9933CC">''</font>, <font color="#9933CC">''</font>, adConnectUnspecified);
              <b>try</b>
              aCmd := CoCommand.Create;
              aRS := CoRecordSet.Create;
              aRS.CursorLocation := adUseClient;
              <b>with</b> aCmd <b>do</b> <b>begin</b>
              CommandType := adCmdStoredProc;
              CommandText := <font color="#9933CC">'E_SearchZNR_RUFZ'</font>;
              AddParamObj(<font color="#9933CC">'RETURN_VALUE'</font>, adInteger, adParamReturnValue, 4);
              <font color="#003399"><i>// INPUT-Parameter</i></font>
              AddParamObj(<font color="#9933CC">'@sRUFZ'</font>, adVarChar, adParamInput, 50);
              AddParamObj(<font color="#9933CC">'@sPLZ'</font>, adVarChar, adParamInput, 5);
              AddParamObj(<font color="#9933CC">'@sORT'</font>, adVarChar, adParamInput, 39);
              Parameters[1].Value := SetSQLJoker(sRUFZ);
              Parameters[2].Value := SetSQLJoker(sPLZ);
              Parameters[3].Value := SetSQLJoker(sORT);
              Set_ActiveConnection(aCon);
              <b>end</b>;
              aRS.Open(aCmd, EmptyParam, adOpenStatic,
              adLockBatchOptimistic, adCmdUnspecified);
              aSearchRS := aRS;
              iRet := aCmd.Parameters[0].Value;
              aRS.Set_ActiveConnection(<b>nil</b>);
              <b>finally</b>
              aCon.Close;
              <b>end</b>;
              Result := iRet;
              SetComplete
              <b>except</b>
              SetAbort;
              <b>raise</b>;
              <b>end</b>;
              <b>end</b>;
              </code&gt

              Comment


              • #8
                Hallo Andreas,
                vielen Dank für den Hinweis, das hatte ich vor Deiner Antwort einfach blind ausprobiert und es hat funktioniert...
                Ich habe jetzt das gesamte Programm auf den nativen Zugriff umgestellt und hoffe jetzt mal, dass keine Anomalitäten mehr auftreten. Der erste positive Effekt ist schon mal eine deutliche Geschwindigkeitsverbesserung.

                Viele Grüße
                Holge

                Comment

                Working...
                X