Announcement

Collapse
No announcement yet.

Problem mit AdoCommand und Parameters

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

  • Problem mit AdoCommand und Parameters

    Hallo zusammen,

    Kann mit bitte jemand helfen. Wenn ich folgendes mache

    procedure TForm1.Button1Click(Sender: TObject);
    var
    cmd: TAdoCommand;
    begin
    cmd := TAdoCommand.Create(Self);
    with cmd do
    begin
    try
    Connection := ADOCon;
    CommandText :=
    'INSERT INTO test2 (tst_text) VALUES (:Test) ';
    Parameters.ParseSQL(CommandText, True);
    Parameters.ParamByName('Test').Value := '';
    Execute;
    finally
    FreeAndNil(cmd);
    end;
    end;
    end;

    bekomme ich immer den Fehler:

    Ein Parameterobjekt ist nicht richtig konfiguriert. Das selbe passiert auch wenn ich Null zuweisen möchte. Das Problem liegt laut mit darin, dass es Value ein Variant ist und ich ihm den Typ irgendwie nicht zuweise. Nur wie macht man das ?

    mfg

    Klaus Astner

  • #2
    Hallo,

    hinter ADO Express (alias dbGo) stecken nur VCL-Wrapperkomponenten für die nativen ADO-Objekte von Microsoft. Daher legen die ADO-Objekte die Spielregeln fest. Im Fall des Command-Objekts muss <b>vor</b> der ersten Gebrauch die <b>Parameters</b>-Kollektion korrekt gefüllt werden. Borland sieht im Fall von ADO Express dabei den folgenden Weg vor: <br>
    1. TADOCommand als Komponente ablegen <br>
    2. TADOConnection im Objektinspektor zuweisen <br>
    3. SQL-Text im Objektinspektor zuweisen <br>
    4. Parameters-Button im Objektinspektor <b>anklicken</b>, damit die VCL die Parameters-Kollektion automatisch korrekt füllt <br>
    5. Zur Laufzeit im Programm den Parameter-Wert übergeben <br>
    6. Zur Laufzeit TADOCommand ausführen.

    Wenn man diese Reihenfolge nicht einhält, weil die SQL-Anweisung erst zur Laufzeit zugewiesen wird, muss man sich selbst um den Schritt 4 kümmern:
    <pre>
    <b>var</b>
    aCon : _Connection;
    aCommand : _Command;
    vRows : OleVariant;
    iCnt : Integer;
    <b>begin</b>
    aCon := CoConnection.Create;
    aCon.CursorLocation := adUseClient;
    aCon.Open(cCS, <font color="#9933CC">''</font>, <font color="#9933CC">''</font>, adConnectUnspecified);
    <b>try</b>
    aCommand := CoCommand.Create;
    <b>try</b>
    <b>with</b> aCommand <b>do</b> <b>begin</b>
    CommandType := adCmdText;
    CommandText := <font color="#9933CC">'INSERT INTO CommandTbl (Nr,Wert) '</font> +
    <font color="#9933CC">'VALUES (?,?)'</font>;
    Parameters.Append(CreateParameter(<font color="#9933CC">'Nr'</font>, adInteger,
    adParamInput, 4, EmptyParam));
    Parameters.Append(CreateParameter(<font color="#9933CC">'Wert'</font>, adVarChar,
    adParamInput, 10, EmptyParam));
    Set_ActiveConnection(aCon);
    <b>for</b> iCnt := 1 <b>to</b> 100 <b>do</b> <b>begin</b>
    Parameters[0].Value := iCnt;
    Parameters[1].Value := <font color="#9933CC">'Nr. '</font> + IntToStr(iCnt);
    Execute(vRows, EmptyParam, adExecuteNoRecords);
    <b>end</b>;
    <b>end</b>;
    <b>finally</b>
    aCommand := <b>nil</b>;
    <b>end</b>;
    <b>finally</b>
    aCon.Close;
    aCon := <b>nil</b>;
    <b>end</b>;
    <b>end</b>;
    </pre>
    Falls man diesen Aufwand nicht treiben möchte, den Objektinspektor nicht nutzen möchte, aber einen Performance-Einbruch in Kauf nimmt, gibt es noch die Alternative der Parameters-Methode <b>Refresh</b>. In diesem Fall fragt ADO bei jedem Aufruf die Systemtabellen der Datenbank ab, um den notwendigen Datentyp der Parameterobjekte in eigener Regie zu ermitteln.

    P.S: Delphi wurde für RAD (Rapid Application Development) ausgelegt, so dass der Entwickler auch tatsächlich von den Möglichkeiten der visuellen Anwendungsentwicklung (Objektinspektor) intensiv Gebrauch machen sollte :-

    Comment


    • #3
      Sehr geehrter Herr Kosch,

      Vorab vielen Dank für die rasche Antwort. Ich gebe ihnen Recht dass es wesentlich einfach ist die Komponenten im Objectinspector zu konfigurieren. In meinem Fall ist das Problem jenes. Da ich in verschiedenen Temporärtabellen ziemlich viele Operationen machen muss, und ich nicht für jede Operation einen AdoCommand auf die Form legen möchte (Man kennt sich dann irgendwann nicht mehr aus, wenn 50 Commands auf der Form liegen) hätte ich mir gedacht, dass ich die Parameter einfach mit ParseSQL einlese. Normalerweise ist das bisher auch gut gegangen, nur Null-Werte und leere Strings lassen sich nicht zuweisen.

      Den Aufwand über das Native-AdoObject möchte ich nicht gehen, aber auch das Refresh nützt da nichts. Wenn ich es vor dem ParseSQL starte dann ist das Resultat das selbe, wenn ich es danach starte, dann sind die Parameter nicht mehr da.

      mfg

      Klaus Astne

      Comment


      • #4
        Hallo,

        wir dürfen in Delphi beliebig viele Datenmodule nutzen, deren Instanz erst zur Laufzeit bei Bedarf erzeugt und danach sofort wieder zerstört wird. Somit lassen sich beide Probleme (Übersichtlichkeit und Ressourcenverbrauch) elegant lösen :-

        Comment

        Working...
        X