AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Teildatenbank aus großer Datenbank erzeugen
Thema durchsuchen
Ansicht
Themen-Optionen

Teildatenbank aus großer Datenbank erzeugen

Ein Thema von Tyrael Y. · begonnen am 7. Dez 2009 · letzter Beitrag vom 9. Dez 2009
Antwort Antwort
Seite 1 von 2  1 2      
Tyrael Y.

Registriert seit: 28. Jul 2003
Ort: Stuttgart
1.093 Beiträge
 
Delphi 2007 Professional
 
#1

Teildatenbank aus großer Datenbank erzeugen

  Alt 7. Dez 2009, 10:41
Datenbank: Access • Zugriff über: ADO
Hallo zusammen,

ich habe eine Datenbank in der sehr viele Tabellen mit sehr vielen Daten sind.
In jeder Tabelle gibt es ein Feld "ID" über die ein Datensatz identifiziert wird.

Mein Ziel ist es für eine Liste von ID´s eine neue Datenbank zu erzeugen.
Im Prinzip sollen alle Daten zu einer ID aus einer Datenbank abgefragt und in eine andere Datenbank vollständig hinzugefügt werden.

1. Ich würde jetzt eine Abfrage über alle Tabellen ausführen
Zitat:
SELECT * FROM Tabelle_1, Tabelle_2, Tabelle_3, ... WHERE ID = 123
2. Alle Felder des Abfrageergebnisses auswerten
Delphi-Quellcode:
  ...
  myObject.Data_1 := query.FieldByName('Data_1').AsInteger;
  myObject.Data_2 := query.FieldByName('Data_2').AsString;
  myObject.Data_3 := query.FieldByName('Data_3').AsInteger;
  ...
3. Diese in neue SQL-Anweisungen hinzufügen und der Datenbank hinzufügen
Zitat:
INSERT INTO Tabelle_1 (Data_1, Data_2, Data_3, ...) VALUES (myObject.Data_1, myObject.Data_2, myObject.Data_3, ...)
INSERT INTO Tabelle_2 (Blub_1, Blub_2, Blub_3, ...) VALUES (myObject.Data_123, myObject.Data_345, myObject.Data_379, ...)

Ist das die einzige Möglichkeit, die ich habe oder gibt es genau für dieses Vorhaben günstigere/bessere Wege?
Levent Yildirim
Erzeugung von Icons aus Bildern:IconLev
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#2

Re: Teildatenbank aus großer Datenbank erzeugen

  Alt 7. Dez 2009, 14:37
Zitat von Tyrael Y.:
ich habe eine Datenbank in der sehr viele Tabellen mit sehr vielen Daten sind.
In jeder Tabelle gibt es ein Feld "ID" über die ein Datensatz identifiziert wird.
....
Also wenn das so ist, warum nutzt Du Access??

Lästern beiseite, bei einer "richtigen" DB hättest Du natürlich die Möglichkeit einen View einzusetzen aber unter ACCESS bleibt Dir wohl nichts anderes, auch weil Du die Daten auch auswerten willst.

Allerdings, zwei Datenbestände zum gleichen Thema?
Am besten wird Datenpflege auch in beiden betrieben?

Das ist nicht so empfehlenswert!

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Tyrael Y.

Registriert seit: 28. Jul 2003
Ort: Stuttgart
1.093 Beiträge
 
Delphi 2007 Professional
 
#3

Re: Teildatenbank aus großer Datenbank erzeugen

  Alt 7. Dez 2009, 15:11
Hallo p80286,
ich schreibe nichts von Auswerten.

Das Ziel ist ganz einfach.
Ich habe eine Datenbank, in der viele Tabellen mit vielen Daten sind.

Ich möchte in eine neue Datenbank bestimmte Datensätze haben. Diese neue Datenbank ist leer und besitzt alle Tabellen mit allen Feldern. Soll heißen, ich habe eine Liste mit ID´s. Alle Daten aus allen Tabellen die zu diesen ID´s passen, sollen von der einen Datenbank in die andere kopiert werden. Sonst nichts.

Wieso weshalb warum spielt doch keine Rolle. Das ist das Problem und ich möchte es gerne lösen.

Ich hab die umständliche Lösung schon fertig und es funktioniert.

Ich denke aber es sollte eine einfachere Möglichkeit auch möglich sein, da mich der Inhalt der Daten im Grunde nicht interressiert. Ich versuche mich gerade mit TADODataset.

Ich denke es sollte vielleicht möglich sein über TADODataset die Datensätze von einer Datenbank in die andere zu kopieren.
Da ich mich mit der Datenbankgeschichte nicht super gut auskenne, frage ich halt in die Runde, ob jemand weiss wie ich das einfach realisieren kann.
Levent Yildirim
Erzeugung von Icons aus Bildern:IconLev
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#4

Re: Teildatenbank aus großer Datenbank erzeugen

  Alt 7. Dez 2009, 18:37
Zitat von p80286:
Also wenn das so ist, warum nutzt Du Access??
Lästern beiseite, bei einer "richtigen" DB hättest Du natürlich die Möglichkeit einen View einzusetzen...
Natürlich kann man auch unter MS Access Views erstellen und benützen! Sooo schlecht ist Access nun auch wieder nicht.
Zitat von Tyrael Y.:
Wieso weshalb warum spielt doch keine Rolle. Das ist das Problem und ich möchte es gerne lösen.
Ich hab die umständliche Lösung schon fertig und es funktioniert.
Das ist eine ganz schlechte Einstellung; sie verhindert, dass du dazulernen kannst.
Es ist immer das Gleiche in den Programmiererforen.
Die Fragesteller wollen eine Lösung für ein konkretes Problem aber sie formulieren es auf abstrakte Art und Weise und lassen manchmal das Wichtigste weg.
Dabei liegt das Problem doch viel tiefer.
Sehr häufig läuft der Fragesteller auf einem Holzweg und merkt es gar nicht.

In deinem Fall würde ich wetten, dass deine Datenbankstruktur ungeeignet ist.
Hast du viele Tabellen mit gleicher Struktur?
Falls ja, dann ist die Wurzel der Probleme schon gefunden.
Andreas
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#5

Re: Teildatenbank aus großer Datenbank erzeugen

  Alt 7. Dez 2009, 19:19
Ich kann mir zwei Gründe vorstellen, wieso man soetwas machen will:
1. Ich möchte Alle Informationen zu einer ID in einer eigenen Datei zentral ablegen. Das könnte z.B. ein elektronisches Datenblatt sein. Zu einem Produkt sind alle Informationen gespeichert. Ich extrahiere aus der Zentraldanenbank die Informationen zu diesem Produkt und lege sie in einer Access-DB ab. Dann dazu noch einen Reportgenerator und -wupps- habe ich eine 'gebrandete' Anwendung. Gar nicht so doof.

2. Die Anwendung wird zu lahm, weil eben sehr viele Datensätze schon in der Datenbank sind. Ich extrahiere die aktuellen (oder alten) Sätze, um die DB schlank und performant zu halten. Möööp Möööp Möööp! Blödsinnsalarm!

Es gibt bestimmt noch mehr Gründe, aber die würde imho alle in die letzte Kategorie fallen.

Unabhängig davon, ob es nun sinnvoll ist, oder nicht: ADO bietet Dir die Möglichkeiten um dein Problem zu lösen, und zwar auch dann, wenn sich die Tabellenstruktur ändert oder neue Tabellen hinzukommen.

Mit einer TADOConnection bekommst du eine Liste aller Tabellen deiner Quelldatenbank.
Dann gehst Du alle Tabellen durch und kopierst alle Datensätze mit der entsprechenden ID:
Delphi-Quellcode:
Procedure CopyRecords (aSrcConnection, aDstConnection : TADOConnect; aTableName : String; aID : Integer);
Var
  qSource, qDest : TADOQuery;
  i : Integer;

Begin
  qSource := TADOQuery.Create;
  qSource.Connection := aSrcConnection;
  qDest := TADOQuery.Create;
  qDest.Connection := aDstConnection;
  Try
     qSource.SQL.Text := Format ('select * from [%s] where ID = :ID',[aTableName]);
     qDest.SQL.text := qSource.SQL.text;
     qSource.Parameters.ParamValues['ID'] := ID;
     qSource.Open;
     While not qSource.Eof do Begin
       qDest.Append;
       For i:=0 to qSource.FieldCount - 1 do
         qDest[qSource.Fields[i].FieldName] := qSource.Fields[i}.Value;
       qDest.Post;
       qSource.Next;
     End;
  Finally
     qSource.Free;
     qDest.Free;
  End;
End;
Getippt und nicht getestet. Funktioniert aber im Prinzip.

Du musst nur noch den kleinen Code schreiben, der dir alle Tabellennamen auflistet und dann für jede Tabelle o.g. Routine aufrufen. Fertig.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
khh

Registriert seit: 18. Apr 2008
Ort: Südbaden
1.929 Beiträge
 
FreePascal / Lazarus
 
#6

Re: Teildatenbank aus großer Datenbank erzeugen

  Alt 7. Dez 2009, 19:49
was sind eigentlich sehr viele Tabellen mit sehr vielen Daten?

100.000
100.000.000 ?


ich nehme mal an du hast schon mal was von Normalisierung gehört

Sieh dein Vorhaben mal unter diesem Aspekt.

Eine DB sollte keine wahllose Sammlung von Datenmengen sein.


Gruss KH
Karl-Heinz
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#7

Re: Teildatenbank aus großer Datenbank erzeugen

  Alt 7. Dez 2009, 20:42
Zitat von khh:
was sind eigentlich sehr viele Tabellen mit sehr vielen Daten? ... ich nehme mal an du hast schon mal was von Normalisierung gehört
Je höher der Normalisierungsgrad, desto weniger Spalten, aber desto mehr Datensätze haben die Tabellen. Auch der Hinweis, das alle Tabellen mit einer Spalte 'ID' miteinander verknüpft sind, sollte eine niedrigen Normalisierungsgrad ausschließen.

Und weil das so ist, ist die Frage nach der Anzahl der Datensätze sowie der irrigerweise hergestellte Zusammenhang mit er NF und -last but not least- der daraus vermeidlich abgeleiteten Unwissenheit des Fragestellers eine vielsagende Antwort auf die Frage nach deinem Kenntnisstand und mit Abstrichen auch deines Wesens.

Der Fragesteller will nur wissen, wie man performant und einfach Daten aus einer Datenbank extrahiert. Er hat explizit erwähnt, keine Fragen nach dem "wieso weshalb warum" zu stellen. Da wir jedoch die Fortsetzung dieses Zitates kennen (jedenfalls die älteren unter uns aus ihrer Kindheit), schmunzeln wir still und lassen es wirken (das Zitat). Vielleicht kommt die Message an.

Ich glaube, er ist nicht so weit, als das er selbstkritisch Fragen nach der Qualität seiner Lösung bzw. der zugrundeliegenden Datenbank stellt. Also respektieren wir das und halten uns doch bitte zurück.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Tyrael Y.

Registriert seit: 28. Jul 2003
Ort: Stuttgart
1.093 Beiträge
 
Delphi 2007 Professional
 
#8

Re: Teildatenbank aus großer Datenbank erzeugen

  Alt 8. Dez 2009, 08:51
OMG,
ok damit ihr zufrieden seit.

Nur weil ich geschrieben habe, daß ich mich mit Datenbanken nicht so gut auskenne, soll das nicht heißen ich wäre ein Volldepp in dieser Hinsicht. Diese Aussage sollte heißen, daß ich mich in anderen Bereichen deutlich besser auskenne.

Die Datenbank ist in der 3. Normalform und es herschen nur noch 1:1 Beziehungen.
Sehr viele Tabellen war übertrieben. Es gibt 35 Tabellen für 35 verschiedene Sprachen mit vier Feldern.
Dazu noch 17 weitere Tabellen mit Zusatzinformationen. Es gibt keine Tabelle, die mehr als 10 Felder hat, die auch
sinnigerweise zusammengehören und nicht mehr normalisiert werden sollten.

Die Datenbank ist eine Übersetzungs-/ Sprachdatenbank mit zusätzlichen Projektdaten.

Es gibt eine zentrale Datenbank, in der viele Übersetzungen mit Zusatzdaten stehen.
Projektbearbeiter synchronisieren ihre Projekte mit dieser Datenbank und erhalten auotmatisch Übersetzungen und Daten in ihren Projekten.

Ziel: Projektbearbeiter sollen, wenn sie möchten eine lokale Projektbezogene Datenbank erstellen, in der sie nur die Daten aus ihrem Projekt haben.

Ja das ganze Vorhaben macht Sinn.
Alle nun zufrieden?


Was meine Frage eher war, wie kann man das am Besten performant realisieren?

Lösungsmöglichkeiten:
1.
Die von mir bereits realisierte Lösung, bei der ich TADOQuery.
Dabei gehe ich jede Tabelle durch.
Hole alle Daten aus aleln Tabellen, sichere die Daten in Datenhalter-Klassen.
Und schreibe diese Daten mittels einer "INSERT INTO..." Query wieder in die andere Dtaenbank.

2. alzaimer´s Lösung - vielen Dank dafür, da du der Einzige warst, der sich überhaupt mit der Fragestellung beschäftigt hat.

Mittels TADOQuery alle Daten aller Felder aus der Datenbank holen.
Und mittels einer weiteren TADOQuery(TDataSet) die Daten in die zweite Datenbank schreiben.
Das schöne an dieser Lösung, man muss sich nicht mit den Feldern auskennen.
Es läuft für jede Datenbank.
(Genau solch eine Lösung habe ich gesucht. Die Perormance teste ich noch)

3.
Mittels - SELECT INTO ..IN
Delphi-Quellcode:
const

  SQL_Mask = 'SELECT %s INTO [%s] IN "%s" %s FROM %s WHERE ID = %s';

  // | | | | |

  // fields | | | |

  // dest table | | |

  // dest database | |

  // database format |

  // source dataset

...
Man holt mittels TADOConnection alle Tabellen. Itteriert darüber.
Per TADOConnection werden die Fields der aktuellen Tabelle geholt und in einem Komma getrennten String zusammengehängt.
"dest database" ist der Dateipfad zur Tabelle. Database Format habe ich bei meinen Tests leer gelassen, könnte mir vorstellen, daß dies der Fehler ist. Ich weiss aber auch nicht, was ich da hinschreiben soll.

Leider krieg ich diese Lösung nicht hin. Es kommt die Fehlermeldung, daß mindestens ein Parameter der notwendig ist fehlen würde.

4.
Eventuell mit TADODataSet und der Funktion Clone.
Noch weiss ich nicht, ob das überhaupt möglich wäre.



Off Topic:
"Hallo, könne sie mir sagen wo ich Äpfel kaufen kann?"
"Äpfel? Um diese Jahreszeit?"
"Ich glaube er will eher Birnen kaufen."
"Kommt drauf an was er machen will, wenn er einen Schanps brauen will, könnte beides gemeint sein."
"Ich denk er will eher einen Kuchen backen, da wären Kirschen viel netter."
"Da könnten sie Recht haben."
"Wie kann man nur eine Apfelkuchen backen wollen? Leute gibts. das macht doch in dieser Jahreszeit keinen Sinn."
"...aber, ich wollte doch nur wissen, wo es Äpfel zu kaufen gibt..."
Levent Yildirim
Erzeugung von Icons aus Bildern:IconLev
  Mit Zitat antworten Zitat
Tyrael Y.

Registriert seit: 28. Jul 2003
Ort: Stuttgart
1.093 Beiträge
 
Delphi 2007 Professional
 
#9

Re: Teildatenbank aus großer Datenbank erzeugen

  Alt 8. Dez 2009, 11:18
Ich versuche mich gerade mit der Version mit SELECT INTO, da dies für mich sehr elegant erscheint.
Die Zieldatei ist passwortgeschützt. Es will nicht klappen, daß ich das Passwort mit übergebe.

Kennt sich jemand mit diesem Statement so gut aus, daß er/sie mir sagen kann wie die Syntax genau aussehn müsste?

Delphi-Quellcode:
function TForm1.GetDBConnection(var ADatabaseFile: string): TADOConnection;
var
  LDBFile: String;
  LConnString: string;
begin
  LDBFile := ADatabaseFile;

  result := TADOConnection.Create(nil);
  LConnString := C_CONNECTION_STRING + C_DB_PWD_CONN_STR;
  result.ConnectionString := Format(LConnString, [LDBFile, C_DB_PASSWORD]);

  ADataBaseFile := LDbFile;
  result.LoginPrompt := false;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  sql,
  pathToSource,
  pathToDest: string;
  adoquery: TADOQuery;
  adoconnection: TADOConnection;
begin
  pathToSource := 'D:\DatenbankCopyTest\testDB.mdb';
  pathToDest := 'D:\DatenbankCopyTest\neu.mdb';

  adoconnection := GetDBConnection(pathToSource);
  sql := 'SELECT * INTO [testTabelle_1] IN %s FROM [testTabelle_1]';

  adoquery := TADOQuery.Create(nil);
  adoquery.Connection := adoconnection;
  adoquery.SQL.Text := format(sql, [quotedstr(pathToDest)]);
  //adoquery.SQL.Text := format(sql, [quotedstr(pathToDest + ';pwd=' + C_DB_PASSWORD')]); //Fehler: Datei nicht gefunden

  adoquery.ExecSQL(); //<- Fehlermeldung: Kein zulässiges Passwort
end;
Wie muss ich in dieser Syntax das Passwort angeben?
Levent Yildirim
Erzeugung von Icons aus Bildern:IconLev
  Mit Zitat antworten Zitat
Tyrael Y.

Registriert seit: 28. Jul 2003
Ort: Stuttgart
1.093 Beiträge
 
Delphi 2007 Professional
 
#10

Re: Teildatenbank aus großer Datenbank erzeugen

  Alt 8. Dez 2009, 13:11
Die richtige Syntax lautet...

Delphi-Quellcode:
...
  sql := 'SELECT * INTO [%s].[testTabelle_1] FROM [testTabelle_1] WHERE ID = %s';
...
  adoquery.SQL.Text := format(sql, [quotedstr(';Database=' + pathToDest + ';pwd=' + C_DB_PASSWORD, ID)]);
...
...und funktioniert gut.
Levent Yildirim
Erzeugung von Icons aus Bildern:IconLev
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:30 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz