![]() |
Datenbank: Firebird • Version: 2.5 • Zugriff über: Firedac
Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey
Hallo Zusammen,
wenn eine Firebird Datenbank ForeignKeys verwendet, muss bei Inserts auf die richtige Reihenfolge geachtet werden. Gibt es eine Möglichkeit über die Systemtabellen die richtige Reihenfolge der Tabellen für die Inserts herauszufinden? Gruß Kostas |
AW: Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey
Hallo,
ich glaube, wenn du alle Inserts in eine einzige Transaktion packst, spielt die Reihenfolge keine Rolle. Heiko |
AW: Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey
Du kennst doch das Datenbanklayout oder nicht und daher die richtige Reihenfolge in der gespeichert werden muss.
Was ist das Problem daran die Reihenfolge im Code zu ändern? Klar kannst du die Systemtabellen durchlaufen und dir ne Reihenfolge zusammenbauen, aber du kennst die Reihenfolge doch. |
AW: Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey
Zitat:
Und da die zugrundeliegende Software eine Fremdsoftware ist, kennen wir das Datenmodell nicht 100%tig und analysieren die Constraints-Auflistung von Oracle dafür. |
AW: Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey
Hallo Zusammen,
danke für die Antworten. Sicherlich kennen ich das Datenmodel und ich kann auch die richtige Reihenfolge zu Fuß angeben. Ich hatte gehofft das es eine Möglichkeit gibt die richtige Reihenfolge über die Systemtabellen abzufragen. Tools wie IBExpert machen das ja auch automatisch mit jeder Datenbank. Könnte natürlich sein dass das nicht automatisch geht. Über die Systemtabellen kann ich abfragen welche Tabellen keine ForeignKey haben. Die können in beliebiger Reihenfolge bei Inserts verwendet werden. Tabellen die FKs haben, (können auch mehrere FKs sein) müssen in einer Sortierliste. Die Tabellen die selbst nicht referenziert werden können für die Inserts verwendet werden. Alle anderen müssen zuerst dessen Master-Tabelle zuerst importieren u.s.w. Das ist ein gewisser Auffand aber machbar. Ich möchte nicht die Reihenfolge zu Fuß setzen müssen sondern ein Liste abrufen mit der Reihenfolge für Inserts. Für Deletes ist es wieder umgekehrt. Die Records der letzte Tabelle müssen zuerst gelöscht werden. Gruß Kostas |
AW: Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey
Auf Basis von Firedac:
hatte ich mal für ein ähnliches InHouse Problem bei uns so gelöst:
Delphi-Quellcode:
Fritz
procedure TdbMoveOld.Execute_copy_Work;
var lTables: Tstringlist; lTablesnoReference: Tstringlist; lTablesWithReference: Tstringlist; lTablesDummy: Tstringlist; lTablename: string; lfkey: string; lFinishedTables: Tstringlist; aindex: integer; function getIndexforinsert: integer; var dummy: Tstringlist; i, temp: integer; s: string; found: boolean; begin result := -1; for i := 0 to lTablesWithReference.count - 1 do begin dummy := pointer(lTablesWithReference.Objects[i]); if dummy <> nil then begin found := true; for s in dummy do if not lFinishedTables.find(s, temp) then begin found := false; end; if found then exit(i); end; end; end; begin lTables := Tstringlist.create; lTablesnoReference := Tstringlist.create; lTablesWithReference := Tstringlist.create; lFinishedTables := Tstringlist.create; lFinishedTables.Sorted := true; try // Get All Tables FileDestConnection.GetTableNames('', '', '', lTables, [osMy], [tkTable]); for lTablename in lTables do begin // CwLogSave.send(lTablename); metaQuery.MetaInfoKind := mkForeignKeys; metaQuery.ObjectName := lTablename; metaQuery.Open; if metaQuery.RecordCount > 0 then begin lTablesDummy := Tstringlist.create; lTablesDummy.Sorted := true; lTables.Duplicates := dupIgnore; while not metaQuery.eof do begin lfkey := metaQuery.FieldValues['PKEY_TABLE_NAME']; if lfkey <> lTablename then lTablesDummy.add(lfkey); metaQuery.Next; end; lTablesWithReference.AddObject(lTablename, lTablesDummy); end else begin // There is no reference so put in in the list lTablesnoReference.add(lTablename); end; metaQuery.Close; end; // Now try the loop // First all Tables without any references for lTablename in lTablesnoReference do begin lFinishedTables.add(lTablename); CopyData(lTablename); // Die must Du Dir selber bauen end; while lTablesWithReference.count > 0 do begin aindex := getIndexforinsert; if aindex > -1 then begin // CwLogSave.send('Insert now ' + lTablesWithReference[aindex]); lFinishedTables.add(lTablesWithReference[aindex]); if (lTablesWithReference.Objects[aindex] <> nil) then Tstringlist(lTablesWithReference.Objects[aindex]).free; lTablename := lTablesWithReference[aindex]; lTablesWithReference.delete(aindex); CopyData(lTablename); // Die must Du Dir selber bauen end else break; // Ther is a error end; if lTablesWithReference.count > 0 then begin CwLogSave.senderror('Not all found'); CwLogSave.entermethod('Tables with references'); for lTablename in lTablesWithReference do CwLogSave.send(lTablename); CwLogSave.ExitMethod('Tables with references'); end; finally lTables.free; lTablesnoReference.free; lTablesWithReference.free; lFinishedTables.free; end; end; |
AW: Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey
Hallo Fitz,
danke für die Antwort. Ich suche eine Möglichkeit über die Systemtabellen an die Reihenfolge zu kommen da ich die Abfrage innerhalb einer StorredProc benötige. Gruß Kostas |
AW: Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey
Rdb$dependencies
|
AW: Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey
Hallo Zusammen,
ich habe den Artikel gefunden ![]() und daraus die StoredProc erzeugt. Aus meiner Datenbank hat er alle Tabellen komplett richtig ausgelesen.
Code:
Schöne Grüße
create or alter procedure ORDER_ALLTABLES
as declare variable COUNTNEWINSERTS integer; declare variable NEWINSERTS integer; begin /* http://firebird-support.yahoogroups.narkive.com/XPYLG1la/odp-firebird-support-listing-table-of-database-in-order-of-dependency */ delete from tables_ordered; INSERT INTO TABLES_ORDERED(RDB$RELATION_NAME) SELECT RDB$RELATION_NAME FROM RDB$RELATIONS r WHERE RDB$SYSTEM_FLAG=0 AND NOT EXISTS(SELECT * FROM RDB$INDICES i WHERE r.RDB$RELATION_NAME=i.RDB$RELATION_NAME AND i.RDB$FOREIGN_KEY IS NOT NULL); select count(*) from tables_ordered into :countNewInserts; newInserts = 0; while (1=1) do begin INSERT INTO TABLES_ORDERED(RDB$RELATION_NAME) SELECT RDB$RELATION_NAME FROM RDB$RELATIONS r WHERE RDB$SYSTEM_FLAG=0 AND NOT EXISTS(SELECT * FROM TABLES_ORDERED o /*Ignore tables already inserted*/ WHERE r.RDB$RELATION_NAME = o.RDB$RELATION_NAME) AND NOT EXISTS(SELECT * FROM RDB$INDICES i /*Only insert tables whose foreign key tables are inserted already*/ JOIN RDB$INDICES i2 ON i.RDB$FOREIGN_KEY = i2.RDB$INDEX_NAME AND r.RDB$RELATION_NAME <> i2.RDB$RELATION_NAME /*Omit this line if you don't want to include tables pointing to themselves*/ LEFT JOIN TABLES_ORDERED o ON i2.RDB$RELATION_NAME = o.RDB$RELATION_NAME WHERE r.RDB$RELATION_NAME=i.RDB$RELATION_NAME AND i.RDB$FOREIGN_KEY IS NOT NULL AND o.ID IS NULL); select count(*) from tables_ordered into :newInserts; if (countNewInserts <> newInserts)then begin countNewInserts = newInserts; end else break; end end Kostas |
AW: Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:40 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz