Announcement

Collapse
No announcement yet.

ADO und Clone

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

  • ADO und Clone

    Hallo,

    also entweder bin ich zu dumm zum Suchen oder ich habs einfach nicht gefunden, deshalb bitte nochmal für mich zum mitschreiben. Ich habe zwei Connection. An der einen hängt eine Table die Daten enthält. An der anderen hängt auch eine Table. In die zweite sollen jetzt die Daten aus der ersten. Mit Clone bekomme ich diese Daten auch in das zweite Table rein, aber wie kann ich denn nun das zweite Table updaten damit die Daten dann auch in die andere Tabelle eingefügt werden? Bisherige Versuche waren ergebnislos.

    Danke.

  • #2
    Nachtrag.

    Die Tabellen sind in unterschiedlichen Datenbanken und diese auf unterschiedlichen Servern. Die Daten sollen von einem 6.5 auf einen 2000er kopiert werden. Im Profiler vom 2000er ist allerdings nichts davon zu sehen das irgendein Update/Insert angeschoben wird

    Comment


    • #3
      Hallo,

      für diese Aufgabe ist ein geklontes Recordset nicht geeeignet, da dieses ja nur eine 2. (unabhängige) Sichtweise (Cursor-Position) auf die Ergebnismenge einer SELECT-Abfrage bereitstellt.

      Da erst in ADO.NET - aber nicht in ADO - der interne Status eines Datensatzes geändert werden kann, kann erst ADO.NET die Datenmenge einer SELECT-Abfrage einer Tabelle in eine andere Tabelle einer beliebigen Datenbank als <B>neue</b> Datensätze einfügen, wenn auf die Eigenschaft <i>AcceptChangesDuringFill</i> zurückgegriffen wird.

      Im Fall von ADO muss der Client die Ergebnismenge aus der Quelltabelle in einer Schleife in das Recordset für die Zieltabelle selbst einfügen, indem jeder einzelne Datensatz über <b>AddNew</b> hinzugefügt wird, um dann am Stück über den <b>UpdateBatch</b>-Aufruf in die Zieltabelle zurückschreiben zu lassen

      Comment


      • #4
        Hallo Herr Kosch,

        danke für die Erklärung, ich hab mich das ganze Wochenende bald tod gemacht mit dem Clone. Die 'manuelle' Version hatte ich dann auch schon probiert. Funktioniert auch, allerdings ist das bei Tabellen (Report und Archiv) mit ca. 500.000 Datensätzen eine ganz schön zeitaufwendige Prozedur.

        Gruss Ronn

        Comment


        • #5
          Hallo,

          es spricht doch nichts dagegen, nur diese eine Funktion in ADO.NET zu implementieren (Assembly-DLL ), die von Delphi 5/6/7 dann eingebunden und aufgerufen wird.

          Das folgende C#-Beispiel demonstriert das Prinzip, wobei bei Bedarf die Zieltabelle zuerst angelegt wird. Der <b>SqlCommandBuilder</b> generiert dann basierend auf einer SELECT-Abfrage die INSERT-/UPDATE-/DELETE-Anweisungen für die Zieltabelle:
          <pre>
          <b>using</b> System.Data.SqlClient;
          ...
          <b>private</b> <b>string</b> sCREATETBL = <font color="#9933CC">&quot;CREATE TABLE Customers (CustomerID nchar(5) NOT NULL, &quot;</font> +
          <font color="#9933CC">&quot;CompanyName nvarchar(40) NOT NULL,ContactName nvarchar(30) NULL, &quot;</font> +
          <font color="#9933CC">&quot;ContactTitle nvarchar(30) NULL,Address nvarchar(60) NULL,City nvarchar(15) NULL,&quot;</font> +
          <font color="#9933CC">&quot;Region nvarchar(15) NULL,PostalCode nvarchar(10) NULL,Country nvarchar(15) NULL,&quot;</font> +
          <font color="#9933CC">&quot;Phone nvarchar(24) NULL,Fax nvarchar(24) NULL,&quot;</font> +
          <font color="#9933CC">&quot;CONSTRAINT PK_Customers PRIMARY KEY CLUSTERED (CustomerID))&quot;</font>;
          <pre>
          <b>private</b> <b>string</b> sTABLENAME = <font color="#9933CC">&quot;Customers&quot;</font>;
          <pre>
          <b>private</b> <b>bool</b> ExistsTableInDatabase(<b>string</b> sDatabasename, <b>string</b> sTableName)
          {
          <b>string</b> sCS = <b>string</b>.Format(<font color="#9933CC">&quot;data source=localhost;initial catalog={0};integrated security=SSPI&quot;</font>,
          sDatabasename);
          <b>string</b> sSQL = <b>string</b>.Format(<font color="#9933CC">&quot;SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_CATALOG = '{0}' AND TABLE_NAME = '{1}'&quot;</font>,
          sDatabasename, sTableName);
          <b>bool</b> bExists = <b>false</b>;
          SqlConnection aCon = <b>new</b> SqlConnection(sCS);
          aCon.Open();
          SqlCommand aCmd = <b>new</b> SqlCommand(sSQL, aCon);
          <b>try</b>
          {
          bExists = (aCmd.ExecuteScalar().ToString() == sTableName) ? <b>true</b> : <b>false</b>;
          }
          <b>catch</b> (System.Exception ex)
          {
          MessageBox.Show(ex.Message);
          }
          <b>finally</b>
          {
          aCon.Close();
          }
          <b>return</b> bExists;
          }
          <pre>
          <b>private</b> <b>void</b> ButtonTransfer_Click(<b>object</b> sender, System.EventArgs e)
          {
          <b>string</b> sCSFrom = <b>string</b>.Format(<font color="#9933CC">&quot;data source=localhost;initial catalog={0};integrated security=SSPI&quot;</font>,
          TextBoxFrom.Text);
          <b>string</b> sCSTo = <b>string</b>.Format(<font color="#9933CC">&quot;data source=localhost;initial catalog={0};integrated security=SSPI&quot;</font>,
          TextBoxTo.Text);
          <pre>
          SqlConnection aConFrom = <b>new</b> SqlConnection(sCSFrom);
          SqlCommand aCmdFrom = <b>new</b> SqlCommand(<font color="#9933CC">&quot;SELECT * FROM &quot;</font> + sTABLENAME, aConFrom);
          SqlDataAdapter aAdpFrom = <b>new</b> SqlDataAdapter(aCmdFrom);
          DataSet aDS = <b>new</b> DataSet();
          <b>int</b> iRowsAffected;
          aAdpFrom.AcceptChangesDuringFill = <b>false</b>;
          <pre>
          ListBox1.Items.Add(<font color="#9933CC">&quot;Start...&quot;</font>);
          iRowsAffected = aAdpFrom.Fill(aDS);
          ListBox1.Items.Add(<b>String</b>.Format(<font color="#9933CC">&quot;... {0} Datensätze aus {1} geladen.&quot;</font>,
          iRowsAffected.ToString(), sTABLENAME));
          <pre>
          SqlConnection aConTo = <b>new</b> SqlConnection(sCSTo);
          <b>if</b> (ExistsTableInDatabase(TextBoxTo.Text, sTABLENAME) == <b>false</b>)
          {
          SqlCommand aDDLCmd = aConTo.CreateCommand();
          aDDLCmd.CommandText = sCREATETBL;
          aConTo.Open();
          aDDLCmd.ExecuteNonQuery();
          aConTo.Close();
          ListBox1.Items.Add(<font color="#9933CC">&quot;... Tabelle wurde neu angelegt&quot;</font>);
          }
          <b>else</b>
          {
          SqlCommand aDDLCmd = aConTo.CreateCommand();
          aDDLCmd.CommandText = <font color="#9933CC">&quot;TRUNCATE TABLE &quot;</font> + sTABLENAME;
          aConTo.Open();
          aDDLCmd.ExecuteNonQuery();
          aConTo.Close();
          ListBox1.Items.Add(<font color="#9933CC">&quot;... Tabelle wurde neu geleert&quot;</font>);
          }
          <pre>
          SqlCommand aCmdTo = <b>new</b> SqlCommand(<font color="#9933CC">&quot;SELECT * FROM &quot;</font> + sTABLENAME, aConTo);
          SqlDataAdapter aAdpTo = <b>new</b> SqlDataAdapter(aCmdTo);
          SqlCommandBuilder aCmdBldTo = <b>new</b> SqlCommandBuilder(aAdpTo);
          aAdpTo = aCmdBldTo.DataAdapter;
          ListBox1.Items.Add(<font color="#9933CC">&quot;... Verbindung zur 2. Datenbank hergestellt&quot;</font>);
          iRowsAffected = aAdpTo.Update(aDS);
          ListBox1.Items.Add(<b>String</b>.Format(<font color="#9933CC">&quot;... {0} Datensätze nach {1} kopiert.&quot;</font>,
          iRowsAffected.ToString(), sTABLENAME));
          ListBox1.Items.Add(<font color="#9933CC">&quot;Fertig.&quot;</font>);
          StatusBar1.Text = <b>String</b>.Format(<font color="#9933CC">&quot;Es wurden {0} Datensätze transferiert.&quot;</font>, iRowsAffected);
          }
          </pre&gt

          Comment


          • #6
            Hallo,

            vielen Dank für die Hilfe. Ich habe heute noch eine andere Methode gefunden, die vom Zeitverhalten sehr sehr gut ist. Mein Problem bisher war ja die Tatsache das sich die Zieldatenbank auf einem anderen Server befand. Mittels der Systemprozedur <sp_addlinkedserver> war es mir nun möglich den Transfer direkt über das SQL-Select durchzuführen, sodaß die Daten erst gar nicht über ein Dataset laufen sondern direkt vom Server bearbeitet werden, wodurch sich die Transferzeit von ehemals >mdt.20 min zu ca. 1 min gesenkt hat.

            Trotzdem vielen Dank für Ihre Hilfe

            Comment

            Working...
            X