AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey

Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey

Ein Thema von Kostas · begonnen am 10. Jun 2016 · letzter Beitrag vom 14. Jun 2016
Antwort Antwort
Seite 3 von 3     123
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#21

AW: Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey

  Alt 13. Jun 2016, 22:57
@Lemmy
Die Statements in der SP unterscheiden nicht nach Tabellen und Views. Es werden also Views mit verarbeitet. (im vorigen Post korrigiert)
Der Generator nagelt doch einfach eine ID an die reinkommenden Sätze, aber die reinkommenden Sätze selbst sind ungeordnet. Zumindest sehe ich keinen Sortiermechanismus. Für die Tabellen ohne FK bzw. Index am Anfang ist es natürlich egal. Wie das Ergebnis dann bei Mehrfachabhängigkeiten aussieht, kann ich nicht sagen, ich finde es halt verdächtig.

Ich würde Dependencies nehmen
Hab ich ja oben irgendwo vorgeschlagen, aber das ist offenbar bei Firebird so nicht machbar. (Zumindest sehe ich keine passenden Einträge in meinen Firebird Testdaten)
Ob das nun Datenfehler bei mir sind, oder Firebird ausgerechnet Ref. Constraints nicht als Dependencies behandelt, weiß ich nicht. Ich hab mir auch nicht die Mühe gemacht, Tabellen mit selbstgeschriebenen Indexanweisungen auszuprobbieren. Ist natürlich die Frage, wer sowas macht für RefConstraints, aber mglw. gibt es damit dann auch ein Problem.
Gruß, Jo

Geändert von jobo (13. Jun 2016 um 23:00 Uhr)
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.058 Beiträge
 
Delphi 10 Seattle Enterprise
 
#22

AW: Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey

  Alt 13. Jun 2016, 23:04
Das mit den Views habe ich schon eingebaut.
Ein Test haben ich durchgeführt mit zirkularer Referenz, das funktioniert auch. Seine eigene Tabelle muss ich noch herausfiltern.
Die Tabellen werden zwar nicht sortiert ausgegeben aber aus Referenz sicht in der richtigen Reihenfolge.
Ich werde es noch nicht produktiv einsetzen aber bis dato konnte ich keinen Fehler feststellen.
Die Tabelle RDB$Dependencies gibt es schon.

Geändert von Kostas (13. Jun 2016 um 23:07 Uhr)
  Mit Zitat antworten Zitat
Lemmy

Registriert seit: 8. Jun 2002
Ort: Berglen
2.364 Beiträge
 
Delphi 10.3 Rio
 
#23

AW: Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey

  Alt 13. Jun 2016, 23:09
Die Statements in der SP unterscheiden nicht nach Tabellen und Views. Es werden also Views mit verarbeitet.
ahh.. jetzt, dann sag das doch gleich...


Der Generator nagelt doch einfach eine ID an die reinkommenden Sätze, aber die reinkommenden Sätze selbst sind ungeordnet. Zumindest sehe ich keinen Sortiermechanismus. Für die Tabellen ohne FK bzw. Index am Anfang ist es natürlich egal. Wie das Ergebnis dann bei Mehrfachabhängigkeiten aussieht, kann ich nicht sagen, ich finde es halt verdächtig.
hm.. zumindest lt. Kommentar werden die Tabellen ausgeschlossen deren ForeignKeys auf Tabellen verweisen die noch nicht in der Liste enthalten sind... [zitat]/*Only insert tables whose foreign key tables are inserted[/zitat]


Ich würde Dependencies nehmen
Indexanweisungen auszuprobbieren. Ist natürlich die Frage, wer sowas macht für RefConstraints, aber mglw. gibt es damit dann auch ein Problem.
also zu den INdizes: Die sind eindeutig, d.h. ein entsprechender Index auf dem Namen, sprich da gibt es keine Überschneidungen und sollte daher klappen.

Dependencies gibt es auch (RDB$DEPENDENCIES) - sollte darüber eigentlich auch funktionieren, habe mir die Einträge jetzt aber nicht genauer angeschaut. Aber definitiv eine sinnvolle Sache, da hier ja noch weitere Abhängigkeiten (zu Views, Triggers, SPs) ausgelesen werden können....

Grüße
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.058 Beiträge
 
Delphi 10 Seattle Enterprise
 
#24

AW: Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey

  Alt 13. Jun 2016, 23:20
Nur der Vollständigkeitshalber,

ich habe zu diesem Thema eine weitere Lösung gefunden die ebenfalls auf indices geht.
Beide StoredProcs gehören zusammen. Die Vorgehensweise ist die gleiche so ich das sehe.


Code:
create or alter procedure DB_TBLS_ROWS_FK (
    INCL_FKS smallint = 1)
returns (
    TBL_NAME varchar(200),
    FKS smallint,
    PK varchar(200),
    TBL_FIELDS bigint,
    TBL_ROWS bigint)
as
declare variable STMT_TO_EXEC varchar(200);
BEGIN
  for
    SELECT p.TBL_NAME, p.FKS
      FROM DB_TBLS_ROWS_FK_0 p order by p.FKS
    into :TBL_NAME, :FKS
  do begin
    TBL_ROWS = null;
    TBL_FIELDS = null;
    STMT_TO_EXEC = 'select count(*) as nr_of_rows from ' || :TBL_NAME;

    execute statement STMT_TO_EXEC INTO :TBL_ROWS;

    select count(*)
      from rdb$relation_fields flds
     where flds.RDB$RELATION_NAME = :TBL_NAME
      into :TBL_FIELDS;
    suspend;

    if(0 <> :INCL_FKS) then
    begin
      for
        SELECT r.RDB$FOREIGN_KEY
          FROM RDB$INDICES r
         WHERE r.RDB$RELATION_NAME= :TBL_NAME AND (r.RDB$FOREIGN_KEY IS NOT NULL)
         into :PK
      do begin
        /*TBL_NAME = null;*/
           FKS = null;
           suspend;
      end
      PK = null;
    end
  end
end



Code:
create or alter procedure DB_TBLS_ROWS_FK_0
returns (
    TBL_NAME varchar(200),
    FKS smallint)
as
BEGIN
  for SELECT DISTINCT RDB$RELATION_NAME
        FROM RDB$RELATION_FIELDS
       WHERE RDB$SYSTEM_FLAG=0
       into :TBL_NAME
  do begin
       SELECT count(RDB$INDEX_NAME)
         FROM RDB$INDICES
        WHERE RDB$RELATION_NAME= :TBL_NAME AND (RDB$FOREIGN_KEY IS NOT NULL)
       into :FKS;

       suspend;
  end
END
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#25

AW: Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey

  Alt 14. Jun 2016, 20:41
Hier noch ein Statement, das vielleicht etwas sauberer ist *, als das in der ersten Proc. Es basiert tatsächlich auf den Dictionary Infos zu Foreign Key Constraints und liefert mehr Infos, als benötigt.
Stammt von hier und ist etwas modifiziert:
http://www.alberton.info/firebird_sql_meta_info.html
Dort gibt es auch eine Variante, die auf rdb$depencies basiert, aber die geht bei mir gar nicht.

Ich finde es ja seltsam, dass diese Daten offenbar nur über die Indexinfos erreichbar sind. Das hat m.E. logisch nichts miteinander zu tun. Aber da die Indexerzeugung bei ForeignKey Erzeugunng ebenfalls automatisch läuft (und dabei auch bestehende Indices ignoriert, also zusätzlich/doppelt anlegt), muss man das wohl als pragmatischen Ansatz sehen.



Code:
   SELECT rc.RDB$RELATION_NAME as Constraint_Tablename,
          rc.RDB$CONSTRAINT_NAME,
          s.RDB$FIELD_NAME AS field_name,
          rc.RDB$CONSTRAINT_TYPE AS constraint_type,
          refc.RDB$UPDATE_RULE AS on_update,
          refc.RDB$DELETE_RULE AS on_delete,
          refc.RDB$MATCH_OPTION AS match_type,
          i2.RDB$RELATION_NAME AS references_table,
          s2.RDB$FIELD_NAME AS references_field,
          (s.RDB$FIELD_POSITION + 1) AS field_position
     FROM RDB$INDEX_SEGMENTS s
     LEFT JOIN RDB$RELATION_CONSTRAINTS rc
       ON rc.RDB$INDEX_NAME = s.RDB$INDEX_NAME
     LEFT JOIN RDB$REF_CONSTRAINTS refc
       ON rc.RDB$CONSTRAINT_NAME = refc.RDB$CONSTRAINT_NAME
     LEFT JOIN RDB$RELATION_CONSTRAINTS rc2 
       ON rc2.RDB$CONSTRAINT_NAME = refc.RDB$CONST_NAME_UQ
     LEFT JOIN RDB$INDICES i2 
       ON i2.RDB$INDEX_NAME = rc2.RDB$INDEX_NAME
     LEFT JOIN RDB$INDEX_SEGMENTS s2 
       ON i2.RDB$INDEX_NAME = s2.RDB$INDEX_NAME AND s.RDB$FIELD_POSITION = s2.RDB$FIELD_POSITION
    WHERE -- rc.RDB$RELATION_NAME='TESTTABLE'      -- table name
          -- AND rc.RDB$CONSTRAINT_NAME='FK_B'     -- constraint name
          -- AND rc.RDB$CONSTRAINT_TYPE IS NOT NULL
          rc.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY'
    ORDER BY s.RDB$FIELD_POSITION
*
Einen Schönheitspreis gibt's bei dem Thema offenbar nicht zu gewinnen.
Gruß, Jo
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.058 Beiträge
 
Delphi 10 Seattle Enterprise
 
#26

AW: Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey

  Alt 14. Jun 2016, 21:03
Hallo Jobo,

dieser Select alleine liefert leider nicht die richtige Reihenfolge, zudem auch die Tabellen mehrfach wenn sie mehrere Foreign Key haben.
Ich habe auch soeben versucht in WHERE rc.RDB$RELATION_NAME den Tabellenname zu übergeben, leider auch ohne Erfolg.

Code:
SELECT rc.RDB$RELATION_NAME as Constraint_Tablename,
          rc.RDB$CONSTRAINT_NAME,
          s.RDB$FIELD_NAME AS field_name,
          rc.RDB$CONSTRAINT_TYPE AS constraint_type,
          refc.RDB$UPDATE_RULE AS on_update,
          refc.RDB$DELETE_RULE AS on_delete,
          refc.RDB$MATCH_OPTION AS match_type,
          i2.RDB$RELATION_NAME AS references_table,
          s2.RDB$FIELD_NAME AS references_field,
          (s.RDB$FIELD_POSITION + 1) AS field_position
     FROM RDB$INDEX_SEGMENTS s
     LEFT JOIN RDB$RELATION_CONSTRAINTS rc
       ON rc.RDB$INDEX_NAME = s.RDB$INDEX_NAME
     LEFT JOIN RDB$REF_CONSTRAINTS refc
       ON rc.RDB$CONSTRAINT_NAME = refc.RDB$CONSTRAINT_NAME
     LEFT JOIN RDB$RELATION_CONSTRAINTS rc2 
       ON rc2.RDB$CONSTRAINT_NAME = refc.RDB$CONST_NAME_UQ
     LEFT JOIN RDB$INDICES i2 
       ON i2.RDB$INDEX_NAME = rc2.RDB$INDEX_NAME
     LEFT JOIN RDB$INDEX_SEGMENTS s2 
       ON i2.RDB$INDEX_NAME = s2.RDB$INDEX_NAME AND s.RDB$FIELD_POSITION = s2.RDB$FIELD_POSITION
    WHERE -- rc.RDB$RELATION_NAME='TESTTABLE'     -- table name
          -- AND rc.RDB$CONSTRAINT_NAME='FK_B'    -- constraint name
          -- AND rc.RDB$CONSTRAINT_TYPE IS NOT NULL
          rc.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY'

      and   rc.RDB$RELATION_NAME in (SELECT RDB$RELATION_NAME
                                     FROM RDB$RELATIONS r
                                    WHERE RDB$SYSTEM_FLAG=0
                                      AND RDB$RELATION_TYPE = 0 /* nur Tabellen */
                                      AND RDB$RELATION_NAME <> 'TABLES_ORDERED')



    ORDER BY s.RDB$FIELD_POSITION
Gruß Kostas
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#27

AW: Firebird Reihenfolge der Tabellen bei Insert mit Foreignkey

  Alt 14. Jun 2016, 21:38
dieser Select alleine liefert leider nicht die richtige Reihenfolge, zudem auch die Tabellen mehrfach wenn sie mehrere Foreign Key haben.
Ich habe auch soeben versucht in WHERE rc.RDB$RELATION_NAME den Tabellenname zu übergeben, leider auch ohne Erfolg.
Sorry, ich hätte vielleicht mehr dazu schreiben sollen. Das Statement ist zum "Spielen" gedacht, es liefert nicht primär einfach nur die Ziel-Tabellen. Es soll bspw. bei den Constraints mehrere Spalten berücksichtigen-was bei Deinem Problem erstmal nicht hilft, wie Du festgestellt hast- usw. usw.

Wenn es richtig aufbereitet ist, wäre es Ersatz für das 2. Insert/Select Statement aus der SP von Dir.

Ich finde das spannend, aber ich hab leider kein Material/ Zeit, das zu testen. Deine SP hat z.B. bei meinem "Datenbestand" ursprünglich nicht funktioniert. Erst nachdem ich einige Male mit Flamerobin Constraints entfernt und hinzugefügt hatte, wurden die abhängigen Tabellen richtig ausgegeben.

P.S. Die Einschränkung, die Du angehängt hast, sollte eigentlich unnötig sein (bis auf die "ordered" Tabelle selbst), da per se nur Tabellen rauskommen können, die einen definierten Ref.Constraint führen. Views fallen automatisch raus. Das z.B. meinte ich mit "sauberer". Falls bei Dir nicht das richtige angezeigt wird, hat Dein Dictionary vielleicht das gleiche Problem wie meins und ist irgendwie durcheinander.
Gruß, Jo

Geändert von jobo (14. Jun 2016 um 21:44 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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:22 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