Announcement

Collapse
No announcement yet.

Problem mit TSQLClientDataSet

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

  • Problem mit TSQLClientDataSet

    Hallo,

    ich stelle meine Anwendung gerade von BDE nach dbExpress um. Nun stellt sich mir die Frage welche BDE Komponenten ersetze ich mit welchen dbExpress Komponenten, da ich im u.g. Beispiel das Problem habe: Parameter ':msta' not found.

    Grüsse
    Andreas W.

    DataModule_main.mcib4.Close;
    DataModule_main.mcib4.CommandText:='select * from PMT_MAIL where mstatus= :msta and from_adr = :arg order by mdate,mtime';
    DataModule_main.mcib4.Params.ParamByName('arg').As String := From.Text;
    DataModule_main.mcib4.Params.ParamByName('msta').A sInteger := ComboBox1.ItemIndex;
    DataModule_main.mcib4.Open;

  • #2
    Hallo,

    bevor hier noch ein größeres Unglück geschieht, zitiere ich lieber gleich aus dem folgenden Borland-Statement vom 20.02.2002 (<i>[email protected]</i>): <b><i>Don't use SQLClientDataset for real apps. Its only for prototyping. Use a Unidirectional Dataset(like TSQLQuery), DatasetProvider, ClientDataset.</b></i> Die TSQLClientDataSet-Komponente soll nur für kleine Versuche, aber niemals für eine richtige Anwendung verwendet werden!

    Die Delphi 6-Fassung von dbExpress ist reichlich mit Bugs gesegnet, wobei es im Einzelfall auch noch vom verwendeten Treiber (Datenbank) ankommt. In Delphi 7 wurde TSQLClientDataSet komplett gestrichen und durch TSimpleDataSet ersetzt - aber viele der Treiberprobleme bestehen auch weiterhin. Generell ist es sinnvoll, <b>vorher</b> alle Beiträge zu dbExpress in der <i>Quality Central</i>-Datenbank von Borland (http://qc.borland.com/) durchzuarbeiten.

    P.S: Falls eine neugierige Frage gestattet ist, welche Datenbank wird genutzt

    Comment


    • #3
      Hallo Hr. Kosch,

      danke für die interessante Antwort. Ich benutze für die Anwendung ( ablösung MS-Produktpalette - Mail,Terminkalender usw.) Interbase. Auch mit ADO TADOCommand und MS-SQL bekomme ich den gleichen Fehler, schreibe gerade ein DataPump (Problem mit PK und insert in die neue Tablle soll nicht mehr vorkommen). Die TADOQuery sagt mir das ExecSql nicht benutzt werden kann. Schade, da hat es mit den Parametern funktioniert.

      Grüsse Andreas

      ADOCommand1.CommandText := Memo2.Lines.GetText;

      while not ADOQuery2.EOF do
      begin

      for i := 0 to ListBox1.Count - 1 do

      begin

      ADOCommand1.Parameters.ParamByName(ListBox1.Items. Strings[i]).Value:= ADOQuery2.FieldByName(ListBox1.Items.Strings[i]).AsString;
      ADOCommand1.Execute;
      end;

      end

      Comment


      • #4
        Hallo,

        &gt;Auch mit ADO TADOCommand und MS-SQL bekomme ich den gleichen Fehler...

        das liegt nicht an ADO und an der Datenbank, sondern an der verwendeten Implementierung. Die ADO Express-Komponenten (alias dbGo) sind nur VCL-Wrapperkomponenten für die nativen ADO-Objekte (COM-Objekte) von Microsoft. Somit muss sich das eigene Programm an die Regeln der nativen ADO-Objekte halten. Das erwartete Prinzip verdeutlicht das folgende Beispiel für den Zugriff auf die nativen ADO-Objekte:
        <pre>
        var
        aCon : _Connection;
        aCommand : _Command;
        vRows : OleVariant;
        iCnt : Integer;
        begin
        aCon := CoConnection.Create;
        aCon.CursorLocation := adUseClient;
        aCon.Open(cCS, '', '', adConnectUnspecified);
        try
        aCommand := CoCommand.Create;
        try
        with aCommand do begin
        CommandType := adCmdText;
        CommandText := 'INSERT INTO CommandTbl (Nr,Wert) ' +
        'VALUES (?,?)';
        Parameters.Append(CreateParameter('Nr', adInteger,
        adParamInput, 4, EmptyParam));
        Parameters.Append(CreateParameter('Wert', adVarChar,
        adParamInput, 10, EmptyParam));
        Set_ActiveConnection(aCon);
        for iCnt := 1 to 100 do begin
        Parameters[0].Value := iCnt;
        Parameters[1].Value := 'Nr. ' + IntToStr(iCnt);
        Execute(vRows, EmptyParam, adExecuteNoRecords);
        end;
        end;
        finally
        aCommand := nil;
        end;
        finally
        aCon.Close;
        aCon := nil;
        end;
        end;
        </pre>
        Beim Command-Objekt muss die Parameters-Kollektion mit der exakten Beschreibung der Parameter gefüllt werden. Im Fall von ADO Express passiert dies <b>nur dann</b>, wenn die SQL fest über den Objektinspektor zugewiesen wird und dort auch der Parameters-Eintrag einmal aufgerufen wird. Nur dann ist man auf der sicheren Seite - alles andere wird zum <i>russischen Roulette</i>, da TADOCommand und das dahinterliegende native Command-Objekt unsynchron werden kann. Falls die festen SQLs nicht in Frage kommen, kann man sein Glück über den Aufruf der Methode <b>Refresh</b> versuchen, wenn via TADOCommand-Eigenschaft <b>CommandObject</b> direkt auf das native Command-Objekt zugegriffen wird

        Comment


        • #5
          Guten Morgen,

          im wahrsten Sinne, das werde ich gleich mal testen.

          Für dbexpress habe ich mich zwecks zukünftige Kylix-Kompatibilität entschieden, war bis jetzt auch sehr angetan.

          Danke
          Andrea

          Comment


          • #6
            1. Woran liegt das: TSQLClientDataSet (die man lieber nicht verwenden sollte...) ist von TClientDataSet abgeleitet, nicht von TSQLDataSet.

            (Die Nachfolgekomponente TSimpleDataSet ist ein Schritt in die richtige Richtung, aber halt nur ein Schritt. Die Sache also lieber mit einer "Datenmengenkette" aufbauen, also TSQLDataSet -> TDataSetProvider -> TClientDataSet, aber ich komme vom Thema ab...)

            Wenn ich CommandText setze, dann lösche ich bestehende Params-Eigenschaften, wenn ich die Parameter setzen, dann setze ich die von TClientDataSet -> und dort gibt es keine.

            2. Was man tun kann:

            a) Auf TSQLClientDataSet verzichten.

            b) Oder die Parameter manuell erstellen (das Beispiel wurde jetzt mit employee.gdb erstellt):

            <pre>
            with SQLClientDataSet1 do
            begin
            CommandText := 'SELECT * FROM employee '
            + 'WHERE LAST_NAME = :name AND DEPT_NO = :no';
            Params.Clear;
            Params.CreateParam(ftString, 'name', ptInput);
            Params.CreateParam(ftInteger, 'no', ptInput);
            Params.ParamByName('name').AsString := 'Young';
            Params.ParamByName('no').AsInteger := 621;
            Open;
            end;

            </pre&gt

            Comment


            • #7
              Guten Morgen,
              das Beispiel von Hr. Kosch hat mir sehr geholfen. Was kann ich tun!
              Ich werde erst Plan B ausführen ( BDE und IBX ablösen) und dann auf A
              umsteigen.
              Danke für das Beispie

              Comment


              • #8
                Hallo Hr. Ebner,

                danke, funktioniert :-) Aber warum sollte man TSQLClientDataSet nicht verwenden (abgesehen von den Bugs)? Ist das nicht ein Rückschritt, wieder alles von Hand aufzubauen

                Comment


                • #9
                  Hallo,

                  &gt;..Aber warum sollte man TSQLClientDataSet nicht verwenden ..

                  weil diese Komponente zum Beispiel nicht mehr "offiziell" in Delphi 7 vorhanden ist und somit auch zukünftig nicht mehr auftauchen wird. Die Macken sind so gravierend, dass sich Borland zu diesem radikalen Schritt entschlossen hat - der Delphi 7-Nachfolger hat nun den Namen <i>TSimpleDataSet</i&gt

                  Comment


                  • #10
                    > Ist das nicht ein Rückschritt, wieder alles von Hand aufzubauen.

                    Nun, genau betrachtet sind es acht Mausklicks mehr, und wenn Sie dafür eine Komponentenvorlage verwenden..

                    Comment


                    • #11
                      Hallo Hr. Kosch,

                      TSimpleDataSet muss noch bis nächstes Jahr warten, bis ich mir D7 hole. Ich hab mir nochmal das Kaptitel dbExpress aus Ihren Buch Interbase Date.. durchgelesen. Dort schreiben Sie das dbExpress keine Multigenerationen-Architektur unterstützt. Funktioniert ein Motor ohne Kolben ?? Ist die Multigenerationen-Architektur kein ein Teil von IB/FB und dessen Transaktionen ?

                      Grüsse
                      Andreas W

                      Comment


                      • #12
                        Hallo,

                        &gt;..das dbExpress keine Multigenerationen-Architektur unterstützt.

                        die Betonung liegt auf <b>unterstützt</b>, d.h. ein dbExpress-Programm kann die Vorteile nicht nutzen. Selbstverständlich ändert der Interbase/Firebird sein Verhalten durch den Zugriff über dbExpress nicht, aber im Gegensatz zu IBX kann man die Vorteile der Multigenerationen-Architektur durch dbExpress nicht ausnutzen.

                        Da hinter dbExpress eine von der Datenbank unabhängig Zugriffsschicht liegt, greift zum einen das Prinzip des kleinsten gemeinsamen Nenners aller Datenbanken. Und zum anderen ist dbExpress "Offline", d.h. da die Anwendung nach dem mehrschichtigen Prinzip (Three-Tier) arbeitet, finden alle Änderungen nur an der TClientDataSet-Datenmenge statt. Beim Zurückschreiben generiert dbExpress die entsprechenden INSERT-, UPDATE- oder DELETE-Anweisungen, die im Kontext einer neuen Transaktionen zur Datenbank geschickt werden

                        Comment


                        • #13
                          Hallo,

                          nun habe ich wieder ein Problem: Timestamp und Datetime!
                          beim inserten bekomme ich den Fehler unassigned Code.
                          IB6 kennt kein Datetime, was kann ich da machen ??
                          mit AsTime geht's, schraibt dann aber immer das aktuelle Datum :-(

                          TSQLQery: und IB 6 Dialect 3 mit TIMESTAMP

                          TABLE "PMT_PLAN"
                          (
                          "STARTTIME" TIMESTAMP,
                          "ENDTIME" TIMESTAMP,
                          ..........
                          )

                          stmt :=' insert into pmt_plan (id, STARTTIME,ENDTIME,SUBJECT,IMAGE,COLOR,PRIO) values(:id,:STARTTIME,:ENDTIME,:SUBJECT,:IMAGE,:CO LOR,:PRIO)';
                          DataModule_main.q_default.Close;
                          DataModule_main.q_default.SQL.Clear;
                          DataModule_main.q_default.SQL.Add(stmt);

                          DataModule_main.q_default.ParamByName('STARTTIME') .AsDateTime := Strtodatetime('02.12.2002 20:00:00');
                          .......

                          DataModule_main.q_default.ExecSQL

                          Comment

                          Working...
                          X