Announcement

Collapse
No announcement yet.

ADO daten updaten

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

  • ADO daten updaten

    Hallo
    ich habe eine Verbindung zur einee Accessdattenbank aufgebaut
    <PRE>
    connect_db := OleDbConnection.Create;
    </PRE>
    usw

    Daten dann über DataAdapter ins dataset geladen

    die daten an die controls gebunden
    <PRE>
    ComboBox1.DataSource := item_dt;
    ComboBox1.DataBindings.Clear;
    ComboBox1.DataBindings.Add('Text', item_dt, 'I_BESCHREIBUNG');
    ComboBox1.DisplayMember := 'I_BESCHREIBUNG';

    TextBox1.DataBindings.Clear;
    TextBox1.DataBindings.Add('Text', item_dt, 'I_ID')
    </PRE>

    das funktioniert auch alles ganz gut

    wenn ich jetzt aber änderung in der Combobox oder textbox mache
    wie bekomme ich die datn zurück in die Datenbank und aktualisiere meine Anzeige

  • #2
    Hallo,

    es gibt zwei prinzipiell unterschiedliche Wege, um die Daten aus den Controls (TextBox) in die Datenbank zu schreiben:
    <br><br>
    1. Die OleDbCommand-Methode <b>ExecuteNonQuery</b> führt eine UPDATE-Anweisung aus, die Parameter-Werte werden dabei von der TextBox ausgelesen.
    <br><br>
    2. Die OleDbDataAdapter-Methode <b>Update</b> arbeitet alle Veränderungen am DataSet in die Datenbank ein, die seit dem Aufruf der Methode <b>Fill</b> vom Programm/dem Benutzer vorgenommen wurden

    Comment


    • #3
      Hallo Herr Kosch

      ich habe es über die Adapterupdate methode versucht

      connect_db.open;
      item_da.Update(dataset_ds, 'Item');
      connect_db.Close;
      nur da tut sich nix in der DB

      Die TextBox ist an der Datatable gebunden

      TextBox.DataBindings.Add('Text', item_dt, 'I_ID');

      Jetzt weiß ich nicht ob ich von der DataTable ins Dataset erst zurück schreiben (und wie) mus um dann über den Adapter in die Datenbank

      Ist irgendwie sehr umständlich

      wie bekommt den das dataset eine änderung an der Textbox überhaupt mit

      Comment


      • #4
        Hallo,

        &gt;wie bekommt den das dataset eine änderung an der Textbox überhaupt mit?

        das Prinzip der Datenbindung unterscheidet sich in .NET grundlegend von dem, was bisher bei Delphi üblich war (über die <i>DataBindings</i>-Kollektion kann prinzipiell jede Eigenschaft eines Controls an eine Eigenschaft einer Datenquelle (Instanz einer Klasse) gebunden werden). Am deutlichsten wird das bei einem kurzen Test: <br>
        1. Zwei TextBoxen im Formular ablegen <br>
        2. Die 2. TextBox an die 1. TextBox binden:
        <pre>
        textBoxOutput.DataBindings.Add('Text',textBoxInput , 'Text');
        </pre>
        Wenn man nun in der 1. TextBox ein Zeichen einträgt, wird dieses automatisch auch in der 2. TextBox sichtbar.
        <br><br>
        Das DataSet kapselt eine Ergebnismenge einer SELECT-Abfrage in der DataTable-Instanz. Und die DataTable besteht intern aus einer Sammlung von DataRow-Instanzen. Jedes DataRow-Objekt vermerkt seinen Status in der Eigenschaft <b>RowState</b>, so dass der DataAdapter erkennen kann, ob dieser Datensatz neu eingefügt, geändert oder gelöscht wurde.
        <br><br>
        Die <b>HasChanges</b>-Methode des DataSet liefert immer dann den Wert True zurück, wenn das DataSet mindestens einen geänderten Datensatz (DataRow) enthält. Über die DataSet-Methode <b>GetChanges</b> kann eine neue DataSet-Instanz abgefordert werden, die nur die Datensätze des originalen DataSets enthält, die geändert wurden.
        <br><br>
        &gt;..nur da tut sich nix in der DB .

        In diesem Fall würde ich mir die UPDATE-Anweisung (also die Eigenschaft <b>UpdateCommand</b> des OleDbDataAdapter) genauer ansehen. Welches WHERE-Kriterium wird dort verwendet, um den zu aktualisierenden Datensatz aus der Datenmenge der Datenbank auszuwählen? Wenn dort Parameter auftauchen, welchen <b>RowState</b>-Zustand (Originaler Wert oder der zur Zeit aktuelle Wert?) übergibt dabei der im WHERE-Kriterium verwendet Parameter

        &gt;Ist irgendwie sehr umständlich

        Aber nur deshalb, weil Delphi 8/2005 nur einen Bruchteil der Visual Studio .NET-Fähigkeiten unterstützt. Mit Delphi muss man sehr viele Dinge zu Fuß erledigen, die beim Konkurrenten von der IDE "nebenbei" mit erledigt werden.

        P.S: Ich kenne einige, die bei "hochnotpeinlicher" Befragung zugeben, die ersten Schritte mit VB.NET (dort geht's am bequemsten) in VS.NET 2003 abzuarbeiten, um dann die Konfiguration in das Delphi-Projekt zu übernehmen ;-

        Comment


        • #5
          Hallo Herr Kosch
          Das mit dem Bindung verstehe ich
          danke für die erste richtig erklärung :-)

          wäre es möglich mir ein simples Beispiel
          für eine Update funktion zukommen zu lassen
          da grade da beiße ich mir die Zähne aus
          welche reihenfolge mus ich da beachte

          Comment


          • #6
            Hallo
            ich habe es jetzt über ein Builder versucht auch hier keine änderung in der Accessdatenbank
            <PRE>
            builder : OleDbCommandBuilder;
            begin
            dataset_ds.AcceptChanges;

            connect_db.open;

            item_da.UpdateCommand := NIL;
            item_da.InsertCommand := NIL;
            item_da.DeleteCommand := NIL;

            builder := OleDbCommandBuilder.Create(item_da);

            item_da.Update(dataset_ds, 'Item');

            connect_db.Close;
            </PRE>
            können sie noch mal bitte helfe

            Comment


            • #7
              also wenn jedesmal vor dem Update AcceptChanges aufgerufen wird, können keine Daten in die Datenbank kommen. Durch AcceptChanges werden die Daten wieder als Originaldaten gekennzeichnet. Sprich die RowStates von added, deleteted ... entfernt. Somit kann der DataAdapter keine Veränderung im Dataset feststellen und auch keine Daten in die DB übertragen.

              AcceptChanges ist nur aufzurufen wenn die Einfüge-, Lösch- oder Updateoperationen per SQL-Befehl mit z.B. ExecuteNonQuery erfolgen. Der DataAdapter ruft nach erfolgreichen ausführen der Operationen AcceptChanges selbst auf. Herr Kosch hat es mal als Vorgang bezeichnet die Daten in ihre Jungfräulichkeit zurück zusetzen.

              Also mein Ratschlag: Lass AcceptChanges weg. Ist beim arbeiten mit dem DataAdapter nicht notwendig

              Comment


              • #8
                Wenn ich AcceptChanges weg lasse und in der Combobox was ändere und dann auf irgend ein Eintrag klick ist immer der urzustand zu sehen
                und die übernahme in die DB will auch nicht klappe

                Comment


                • #9
                  Hallo,
                  <br><br>
                  &gt; item_da.UpdateCommand := NIL; <br>
                  &gt; item_da.InsertCommand := NIL; <br>
                  &gt; item_da.DeleteCommand := NIL; <br>
                  &gt;builder := OleDbCommandBuilder.Create(item_da); <br>
                  <br>
                  das war bereits der Fehler. Das dynamische Generieren der SQLs via OleDbCommandBuilder ist nur für den Fall vorgesehen, dass die Anwendung jede beliebige ACCESS-Datenbankstruktur bearbeiten muss.
                  <br><br>
                  Im Fall von VS.NET 2003 generiert der Wizard die folgenden Anweisungen <b>automatisch</b> - dort ist am Ende das Speichern mit nur einer einzigen Programmzeile (<i>oleDbDataAdapter1.Update(dataSet12)</i>) erledigt. Bei der UPDATE-Anweisung sind für die WHERE-Einschränkung die Kennzeichnungen über <b>System.Data.DataRowVersion.Original</b> entscheidend:
                  <pre>
                  //
                  // oleDbDataAdapter1
                  //
                  this.oleDbDataAdapter1.DeleteCommand = this.oleDbDeleteCommand1;
                  this.oleDbDataAdapter1.InsertCommand = this.oleDbInsertCommand1;
                  this.oleDbDataAdapter1.SelectCommand = this.oleDbSelectCommand1;
                  this.oleDbDataAdapter1.TableMappings.AddRange(new System.Data.Common.DataTableMapping[] {
                  new System.Data.Common.DataTableMapping("Table", "TestTbl", new System.Data.Common.DataColumnMapping[] {
                  new System.Data.Common.DataColumnMapping("recid", "recid"),
                  new System.Data.Common.DataColumnMapping("wert", "wert")})});
                  this.oleDbDataAdapter1.UpdateCommand = this.oleDbUpdateCommand1;
                  //
                  // oleDbSelectCommand1
                  //
                  this.oleDbSelectCommand1.CommandText = "SELECT recid, wert FROM TestTbl";
                  this.oleDbSelectCommand1.Connection = this.oleDbConnection1;
                  //
                  // oleDbInsertCommand1
                  //
                  this.oleDbInsertCommand1.CommandText = "INSERT INTO TestTbl(recid, wert) VALUES (?, ?)";
                  this.oleDbInsertCommand1.Connection = this.oleDbConnection1;
                  this.oleDbInsertCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("recid", System.Data.OleDb.OleDbType.Integer, 0, "recid"));
                  this.oleDbInsertCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("wert", System.Data.OleDb.OleDbType.VarWChar, 20, "wert"));
                  //
                  // oleDbUpdateCommand1
                  //
                  this.oleDbUpdateCommand1.CommandText = "UPDATE TestTbl SET recid = ?, wert = ? WHERE (recid = ?) AND (wert = ? OR ? IS NU" +
                  "LL AND wert IS NULL)";
                  this.oleDbUpdateCommand1.Connection = this.oleDbConnection1;
                  this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("recid", System.Data.OleDb.OleDbType.Integer, 0, "recid"));
                  this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("wert", System.Data.OleDb.OleDbType.VarWChar, 20, "wert"));
                  this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_recid", System.Data.OleDb.OleDbType.Integer, 0, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "recid", System.Data.DataRowVersion.Original, null));
                  this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_wert", System.Data.OleDb.OleDbType.VarWChar, 20, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "wert", System.Data.DataRowVersion.Original, null));
                  this.oleDbUpdateCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_wert1", System.Data.OleDb.OleDbType.VarWChar, 20, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "wert", System.Data.DataRowVersion.Original, null));
                  //
                  // oleDbDeleteCommand1
                  //
                  this.oleDbDeleteCommand1.CommandText = "DELETE FROM TestTbl WHERE (recid = ?) AND (wert = ? OR ? IS NULL AND wert IS NULL" +
                  ")";
                  this.oleDbDeleteCommand1.Connection = this.oleDbConnection1;
                  this.oleDbDeleteCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_recid", System.Data.OleDb.OleDbType.Integer, 0, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "recid", System.Data.DataRowVersion.Original, null));
                  this.oleDbDeleteCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_wert", System.Data.OleDb.OleDbType.VarWChar, 20, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "wert", System.Data.DataRowVersion.Original, null));
                  this.oleDbDeleteCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("Original_wert1", System.Data.OleDb.OleDbType.VarWChar, 20, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "wert", System.Data.DataRowVersion.Original, null));
                  //
                  // oleDbConnection1
                  //
                  this.oleDbConnection1.ConnectionString = @"Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Registry Path=;Jet OLEDBatabase Locking Mode=1;Jet OLEDBatabase Password=;Data Source=""C:\Temp\Out\VSNET2003\ADONET_ACCESS_Updat eDemo\ADONET_ACCESS_UpdateDemo.mdb"";Password=;Jet OLEDB:Engine Type=5;Jet OLEDB:Global Bulk Transactions=1;Provider=""Microsoft.Jet.OLEDB.4.0" ";Jet OLEDB:System database=;Jet OLEDB:SFP=False;Extended Properties=;Mode=Share Deny None;Jet OLEDB:New Database Password=;Jet OLEDB:Create System Database=False;Jet OLEDBon't Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;User ID=Admin;Jet OLEDB:Encrypt Database=False";
                  //
                  // dataSet12
                  //
                  this.dataSet12.DataSetName = "DataSet1";
                  this.dataSet12.Locale
                  </pre&gt

                  Comment


                  • #10
                    Hallo
                    Ich habe es jetzt ein bisschen anderes gemacht
                    mit einen Commandbuilder und bindingManagerBase

                    <PRE>
                    item_da := OleDbDataAdapter.Create(select_s, connect_db);
                    cb := OleDbCommandBuilder.Create(item_da);

                    item_da.SelectCommand := OleDbCommand.Create(select_s , connect_db);

                    </PRE>

                    und dann das Update
                    <PRE>
                    binding_bm.EndCurrentEdit;

                    item_da.Update(dataset_ds, 'Item');
                    </PRE>

                    denn wenn ich die Doku richtig gelesen habe
                    übernimmt doch der Builder für die ganzen Update/Insert/Delete anweisungen

                    Comment


                    • #11
                      Hallo,

                      &gt;übernimmt doch der Builder für die ganzen Update/Insert/Delete anweisungen?

                      das hat aber mehrere gravierende Nachteile: <br>
                      1. Zur Laufzeit muss jedes Mal die Datenbankstruktur ausgelesen werden, um INSERT/UPDATE/DELETE zu generieren <br>
                      2. Es werden keine der Besonderheiten berücksichtigt, die ADO.NET unterstützt.

                      Es ist daher in jedem Fall besser, die verschiedenen OleDbCommand-Instanzen (und vor allem deren <b>Parameters</b>-Kollektionen) bereits zur Entwicklungszeit festzulegen

                      Comment


                      • #12
                        Hallo
                        Ich habe es jetzt mit dem OleDbCommand gemacht

                        Mit dem Update und Delete funktioniert es auch ganz gut

                        Ich habe nur schwierigkeiten mit dem Inserte

                        Ich habe ein DataGird (Readonly)
                        g_hf.Item_DataGrid1.DataSource := item_dt; <<DataTable

                        meine UpdateFunction

                        item_bm.AddNew;
                        item_bm.EndCurrentEdit;

                        //Datenbank updaten
                        try
                        connect_db.Open;
                        item_da.Update(dataset_ds, 'Item');
                        connect_db.Close;
                        except
                        on ex: Exception do
                        begin
                        MessageBox.Show(ex.Message, 'Fehler');
                        connect_db.Close;
                        end;
                        end;

                        wenn ich jetzt ein neuen Datensatz einfüge
                        Steht beim ID NULL (PK)
                        will ich diesen Datzensatzen wieder löschen löscht er den ersten
                        ich sehe den PK erst wenn ich die DB neu öffn

                        Comment

                        Working...
                        X