Announcement

Collapse
No announcement yet.

Wozu ist die Methode "Clone" da ?

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

  • Wozu ist die Methode "Clone" da ?

    Hallo,

    Wie ich in der online Hilfe gelesen habe:
    Thema:

    <b>ADO-Datenbanktabellen erstellen und umstrukturieren
    </b>

    Das Erstellen und Löschen von Metadaten in einer ADO-Datenbank durch eine Delphi-Anwendung erfolgt mit Hilfe von SQL. Auch das Umstrukturieren von Tabellen wird mit SQL-Anweisungen durchgeführt. Das Ändern anderer Metadatenobjekte ist nicht immer direkt möglich. Sie müssen vielmehr das Metadatenobjekt löschen und dann durch ein neues mit anderen Attributen ersetzen.......

    Das bedeutet, wenn man mit "SELECT * FROM ..." eine unbekannte Feldstruktur erhält und diese in eine neue Tabelle schreiben will,
    muß man bei "CRAETE TABLE ...." sich die neue Feldstruktur als STring aus der alten Struktur zusammenbasteln ! ?

    Da muss es doch noch eine andere Möglichkeit geben ?

    Ich habe es mit der Methode "Clone" und der folgenden Kopierroutine Probiert Basiert auf Herrn Koschs Kopierroutine )

    Try
    // Schritt 1: Feldstruktur kopieren
    with Dest do
    begin
    Close;
    FieldDefs.Clear;
    for i := 0 to Source.FieldDefs.Count - 1 do
    begin
    with FieldDefs.AddFieldDef do
    begin
    Name := Source.FieldDefs[i].DisplayName;
    DisplayName := Source.FieldDefs[i].DisplayName;
    Attributes := Source.FieldDefs[i].Attributes;
    DataType := Source.FieldDefs[i].DataType;
    Precision := Source.FieldDefs[i].Precision;
    Required := Source.FieldDefs[i].Required;
    Size := Source.FieldDefs[i].Size;
    end;
    end;

    // Schritt 2: RecordSet anlegen
    CreateDataSet; // geht nur mit ADODataset
    end;

    // Schritt 3: Daten kopieren
    Dest.open;
    with Source do
    begin
    Open;
    First;
    while not Eof do
    begin
    Dest.Append;
    for i := 0 to Dest.FieldCount - 1 do
    begin
    Dest.Fields[i].Value := Fields[i].Value;
    end;
    try
    Dest.Post;
    Except
    Dest.Cancel;
    end;
    Next;
    end;
    end;

    // Schritt 4: Kopierte Daten anzeigen
    Dest.Active := True;
    Except
    Result:=False;
    end;

    In beiden fällen wurden die Daten zwar kopiert, aber nicht in die Datenbank geschrieben !

    Bei "CREATEDATASET" geht die Verbindung zur DB verloren.

    Hat jemand eine Idee, wie es einfacher geht ?

    Vielen Dank

  • #2
    Hallo,<br>
    1.<br>
    Das Recordset kann direkt in die Datenbank durch folgenden Aufruf geschrieben werden:
    <pre>
    RS.Updatebatch
    </pre>
    Die Methode UpdateBatch trägt ausstehende Batch-Aktualisierungen in die Datenbank ein.
    <br>
    2.<br>
    Die Methode Clone macht das, was in der Hilfe eigentlich schon ganz gut beschrieben wird:<br>
    <i>
    Mit Clone können Sie dem Recordset-Objekt der aufrufenden ADO-Datenmenge eine exakte Kopie des Recordset einer anderen TCustomADODataSet-Komponente zuweisen. Verläuft die Operation erfolgreich, sind beide Recordsets identisch. Tritt ein Fehler auf, wird das Recordset-Objekt auf nil gesetzt und eine EADOError-Exception ausgelöst.

    LockType gibt an, welche Art von Sperre beim Öffnen der Kopie gesetzt wird. Der Standardwert ist ltUnspecified.</i><br>
    Dieses Clonen hat allerdings nicht unbedingt etwas mit dem direkten Kopieren von Daten in eine Datenbank zu tun, da diese auf 'Recordsetebene' kopiert werden, d.h. das Recordset wird einfach dupliziert

    Comment


    • #3
      Hallo,

      ich wiederspreche ja nur ungern, aber das Clonen kopiert die Daten <b>nicht</b>, sondern nach dem Clonen arbeiten 2 Recordset-Objektinstanzen mit den <b>gleichen</b> Originaldaten. Der Vorteil des Clonens besteht darin, dass man unterschiedlich Navigieren, Filtern und "Bookmarken" kann, ohne die Datenmenge für den Clone erneut vom Server abzufordern oder den Speicherbedarf für diese auf dem Client verwaltete Datenmenge zu verdoppeln.

      Diese enge Kopplung kann im praktischen Versuch nachgewiesen werden: <br>
      1. Original-Recordset ändert einen Datensatz <br>
      2. Clone ruft <b>Resync</B> auf - die Änderung ist auch beim Clone sichtbar.

      Die Verbindung zwischen der Original- und der Clone-Datenmenge wird erst dann getrennt, wenn einer der beiden die Methode <b>Requery</b> aufruft. Die Methode Requery sorgt dafür, dass die Daten im jeweils betroffenen RecordSet-Objekt durch das Ausführen der Abfrage neu zusammengestellt werden, wenn der Clone eine Verbindung zur Datenbank hat

      Comment


      • #4
        Hallo,
        ich hatte auch schon den Verdacht das "Clone" nur "am Zeiger biegt" und nicht kopiert, da es verdächtig schnell geht.
        Ist ja auch egal woher (original/kopie) die Daten kommen, wenn man nur ein Recordset auf die Platte bannen will.

        Ich habe also folgendes gemacht:
        // Daten einlesen
        // ADOQuery1: Select * FROM BlaBla
        // Vebindung einrichten
        With ADOConnection2 do begin
        Close;
        Properties['Data Source'].Value :='E:\TEMP\TEST.XLS';
        Properties['Extended Properties'].Value :='EXCEL 5.0';
        LoginPrompt:= False;
        Mode:= cmReadWrite;
        Provider:= 'Microsoft.Jet.OLEDB.4.0';
        end;
        //Dataset ranhängen
        With ADODataSet1 do Begin
        Connection:=ADOConnection2;
        CommandType:=cmdTabledirect;
        CommandText:='TEST';
        CursorType:=ctstatic;
        LockType:=ltBatchOptimistic;
        end;
        // OPEN geht hier nur, wenn Tabelle existiert

        // Klonen - schwubs Daten sind da
        ADODataSet1.Clone(AdoQuery1);
        // Trennen - Aha es tut sich was (kopieren ins Dataset)
        ADODataSet1.Requery([]);
        // Schreiben - null nix nada sch...ade
        ADODataSet1.Updatebatch(arAll);

        Ergebnis: Keine Tabelle erzeugt, keine Daten geschrieben !!!

        Es geht auch nicht, wenn man eine Tabelle mit der gleichen Fielddefs wie die Quelle voher erstellt. Es werden ebenso keine Daten geschrieben.

        Da kopieren geht nur, wenn man die Daten ein einer Schleife mit "Append/Post" kopiert.
        Und das ist indiskutabel laaangsam.

        Eine Verbindung zur Ziel- Datenbank ist doch vohanden, wenn es per "Append" geht ?

        Wer weiß Rat ?

        Vielen Dank
        Christia

        Comment


        • #5
          Hallo,

          die RecordSet-Methode Updatebatch kann nicht zaubern. Wenn der Microsoft SQL Server 7/2000 zur Verfügung steht, sollte man sich unbedingt den Updatebatch-Output (SQL) im <i>Profiler</i> anschauen. Dann wird klar, dass der Updatebatch-Aufruf nur dann erfolgreich sein kann, wenn die in der WHERE-Klausel verwendeten Spalten/Werte auch wirklich in der Zieltabelle enthalten sind.

          Was soll überhaupt erreicht werden? Wenn es nur darum geht, Daten in eine andere Tabelle bzw. ein anderes Format zu kopieren, sind die Export-Fähigkeiten der JetEngine doch besser geeignet

          Comment


          • #6
            Der SQL Befehl <br>
            SELECT * INTO NeueTabelle FROM AlteTabelle; <br>
            erzeugt problemlos eine neue Tablle mit allen Feldern und Daten. Nur beispielsweise ein Primary Key wird nicht leider gesetzt

            Comment

            Working...
            X