Announcement

Collapse
No announcement yet.

SQL-Stapelanweisung mit Command Objekt an Access DB

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

  • SQL-Stapelanweisung mit Command Objekt an Access DB

    Hallo,

    ich aktualisiere den Datenbestand einer Access 2000 DB mit mehreren SQL Anweisungen über ADO. Ich habe bereits versucht die SQL Syntax als Stapel an die Jet Engine zu übergeben um zu sehn ob die Jet Engine mit Stapel-SQL-Anweisungen etwas anfangen kann (wie z.B. der MSSQL Server). Scheinbar kann die Jet Engine das nicht. Auch die Eingabe von mehreren SQL Anweisungen direkt im Access Abfrage Editor war negativ.

    Jetzt schicke ich die SQL Anweisungen mit einem nativen Command Objekt nacheinander ab. Dazu hätt ich noch 2 Fragen.

    1.
    Muß ich dazu den Parameter immer wieder neu deklarieren (mit CreateParameter....) oder genügt das einmal solange der ParameterTyp usw. sich nicht ändert? Es funktioniert zwar so wie im Beispiel unten, ich wüßte aber gern ob's auch richtig so ist.

    2.
    Wie würde die Parameterliste wieder gelöscht außer über "Refresh"? Mit "aCommand.Parameters.Clear" gehts leider nicht obwohl es doch auch nur um eine Collection handelt.

    Viele Grüße
    Walter

    <PRE>
    begin
    SQLTxT := 'DELETE FROM MyTab WHERE ID = :MIDx
    SQLTxT1 := 'DELETE FROM MyTab1 WHERE ID = :MIDx
    SQLTxT2 := 'DELETE FROM MyTab2 WHERE ID = :MIDx
    SQLTxT3 := 'DELETE FROM MyTab3 WHERE ID = :MIDx

    try
    aCommand := CoCommand.Create;
    try
    with aCommand do
    begin
    Set_ActiveConnection(DataModule1.ADOConnection1.Co nnectionObject);

    CommandType := adCmdText;
    Set_CommandText(SQLTxT);
    Parameters.Append(CreateParameter('0', adInteger, adParamInput, 10, EmptyParam));
    Parameters[0].Value := DSatzID;//ParamterWert (ID) für die Abfrage

    DataModule1.ADOConnection1.BeginTrans;
    Execute(vRows, EmptyParam, adExecuteNoRecords);

    CommandType := adCmdText;
    Set_CommandText(SQLTxT1);
    Execute(vRows, EmptyParam, adExecuteNoRecords);

    CommandType := adCmdText;
    Set_CommandText(SQLTxT2);
    Execute(vRows, EmptyParam, adExecuteNoRecords);

    CommandType := adCmdText;
    Set_CommandText(SQLTxT3);
    Execute(vRows, EmptyParam, adExecuteNoRecords);

    DataModule1.ADOConnection1.CommitTrans;
    end;
    except
    DataModule1.ADOConnection1.RollbackTrans;
    aCommand := nil;
    end;
    finally
    aCommand := nil;
    end;
    end;

    </PRE>

  • #2
    Hallo,

    in diesem Fall (DELETE-Anweisung wird je Tabelle nur einmal genutzt und verwendet nur einen Parameter) würde ich sogar auf das Command-Objekt verzichten, und statt dessen die Zeichenkette der vollständigen DELETE-Anweisung direkt über die <b>Execute</b>-Methode von <b>Connection</b> ausführen lassen:
    <pre>
    var
    aCon : _Connection;
    vRows : OleVariant;
    iCnt : Integer;
    begin
    aCon := CoConnection.Create;
    aCon.CursorLocation := adUseClient;
    aCon.Open(cCS, '', '', adConnectUnspecified);
    try
    aCon.Execute(SQLTxT, vRows, adExecuteNoRecords);
    aCon.Execute(SQLTxT1, vRows, adExecuteNoRecords);
    ...
    finally
    aCon.Close;
    end;
    end;
    </pre>
    Das Command-Objekt ist zwar der "richtigere" Weg, aber man sollte an dieser Stelle pragmatisch herangehen. Immer dann, wenn die parametisierte Anweisung nicht mehrmals ausgeführt werden muss und auch die Typprüfung bei den Parametern nicht unbedingt benötigt wird (Beispiel: Ein einziger INTEGER-Parameter), führt die Abkürzung über das Connection-Objekt schneller zum Ziel.

    &gt;Wie würde die Parameterliste wieder gelöscht außer über "Refresh"?

    Der saubere Weg besteht darin, den Interface-Zeiger auf die Command-Objektinstanz wieder freizugeben bzw. neu zu belegen, so dass man auf eine frisch initialisierte Objektinstanz zurückgreifen kann

    Comment


    • #3
      Hallo Herr Kosch,

      vielen Dank für erneute Hilfe. Ich hbae die Anweisungen jetzt gleich über das Connection Objekt (in diesem Fall über die TADOConnection Komponente) ausgeführt.

      <PRE>
      SQLTxT := 'DELETE FROM MyTab WHERE FahrzeugID = ' + inttostr(DSatzID);
      SQLTxT1 := 'DELETE FROM MyTab1 WHERE FahrzeugID = ' + inttostr(DSatzID);
      SQLTxT2 := 'DELETE FROM MyTab2 WHERE FahrzeugID = ' + inttostr(DSatzID);
      SQLTxT3 := 'DELETE FROM MyTab2 WHERE FahrzeugID = ' + inttostr(DSatzID);

      DataModule1.ADOConnection1.Execute(SQLTxT, vRows, [eoExecuteNoRecords]);
      DataModule1.ADOConnection1.Execute(SQLTxT1, vRows, [eoExecuteNoRecords]);
      DataModule1.ADOConnection1.Execute(SQLTxT2, vRows, [eoExecuteNoRecords]);
      DataModule1.ADOConnection1.Execute(SQLTxT3, vRows, [eoExecuteNoRecords]);
      </PRE>

      Funktioniert prima. Der Aufwand ein Command Objekt zu verwenden ist wirklich in diesem Fall nicht notwendig. Vielen Dank nochmal für den schnellen Rat.

      Viele Grüße
      Walte

      Comment

      Working...
      X