Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Ermitteln von foreign keys per SQL Abfrage auf Systemtabellen (https://www.delphipraxis.net/170623-ermitteln-von-foreign-keys-per-sql-abfrage-auf-systemtabellen.html)

ZOD 26. Sep 2012 08:51

Datenbank: Interbase • Version: 7.1 • Zugriff über: SQL

Ermitteln von foreign keys per SQL Abfrage auf Systemtabellen
 
Hallo,

ich habe folgende Datenbanksysteme

Interbase 7.1
Firebird 2.0 (kann ich leider in "Ergänzende Angaben" nicht zusätzlich angeben)

Auf beiden läuft "dieselbe" Datenbank.
Die Datenbank arbeitet in allen Tabellen durchgehend mit PK (integer).

Ich möchte nun über eine SQL Abfrage herausfinden, mit welchen Tabellen
eine bestimmte Tabelle über foreign keys verknüpft ist.
Dabei habe ich mich etwas verhakelt. Bisher habe ich dies:


Code:
select
relcz.rdb$relation_name as quelltabelle,
relcq.rdb$relation_name as zieltabelle,
refc.rdb$constraint_name as keyname
from rdb$relation_constraints relcq
left outer join rdb$ref_constraints refc on (refc.rdb$const_name_uq = relcq.rdb$constraint_name)
left outer join rdb$relation_constraints relcz on (relcz.rdb$constraint_name = refc.rdb$const_name_uq)
where
relcq.rdb$relation_name = 'T_QUELLTABELLE'
and
relcq.rdb$constraint_type = 'PRIMARY KEY'
Als Quelltabelle bezeichne ich die Tabelle, in der der foreign key angelegt ist.
Meine Abfrage liefert mir aber als Quelltabelle die Zieltabelle. Was mache ich falsch?

dataspider 26. Sep 2012 09:28

AW: Ermitteln von foreign keys per SQL Abfrage auf Systemtabellen
 
Hi,

dieses Statement liefert die Tabellen mit Feldnamen:

Code:
select
    A.RDB$RELATION_NAME -- Tabellenname
  , E.RDB$FIELD_NAME as OnField -- FK
    from RDB$REF_CONSTRAINTS B, RDB$RELATION_CONSTRAINTS A, RDB$RELATION_CONSTRAINTS C,
         RDB$INDEX_SEGMENTS D, RDB$INDEX_SEGMENTS E
    where (A.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY') and
          (A.RDB$CONSTRAINT_NAME = B.RDB$CONSTRAINT_NAME) and
          (B.RDB$CONST_NAME_UQ=C.RDB$CONSTRAINT_NAME) and
          (C.RDB$INDEX_NAME=D.RDB$INDEX_NAME) and
          (A.RDB$INDEX_NAME=E.RDB$INDEX_NAME) and
          (C.RDB$RELATION_NAME = :table_name) and
          (B.RDB$DELETE_RULE = 'CASCADE')
Frank

jobo 26. Sep 2012 09:29

AW: Ermitteln von foreign keys per SQL Abfrage auf Systemtabellen
 
Hilft Dir das weiter?

aus http://de.wikibooks.org/wiki/Einf%C3...pps_und_Tricks
Code:
-- listet die Fremdschlüssel einer Tabelle auf (i.d.R. nur zwischen je einer Spalte)
SELECT rel.RDB$Constraint_Name AS ForeignKey,
       co1.RDB$Relation_Name  AS DetailTable,
       CASE idx.RDB$Segment_Count
           WHEN 1 THEN fl1.RDB$Field_Name
           ELSE idx.RDB$Segment_Count
       END AS FIELDS,
       rel.RDB$Const_Name_UQ  AS PrimaryKey,
       co2.RDB$Relation_Name  AS MasterTable,
       fl2.RDB$Field_Name     AS MasterField
  FROM RDB$Ref_Constraints rel
/*  RDB$Relation_Constraints wird 2x benötigt:
    als co1 für den Tabellennamen des ForeignKey
    als co2 für den Tabellennamen des PrimaryKey, auf den sich der ForeignKey bezieht */
/*  ebenso RDB$Index_Segments
    als fl1 für den Spaltennamen des FK
    als fl2 für den Spaltennamen des PK */
       JOIN RDB$Relation_Constraints co1
         ON rel.RDB$Constraint_Name = co1.RDB$Constraint_Name
       JOIN RDB$Indices idx
         ON rel.RDB$Constraint_Name = idx.RDB$Index_Name
       JOIN RDB$Relation_Constraints co2
         ON rel.RDB$Const_Name_UQ = co2.RDB$Constraint_Name
       JOIN RDB$Index_Segments fl1
         ON rel.RDB$Constraint_Name = fl1.RDB$Index_Name
       JOIN RDB$Index_Segments fl2
         ON rel.RDB$Const_Name_UQ = fl2.RDB$Index_Name
 WHERE (NOT rel.RDB$Constraint_Name LIKE 'RDB$')
 ORDER BY  rel.RDB$Constraint_Name

ZOD 26. Sep 2012 10:17

AW: Ermitteln von foreign keys per SQL Abfrage auf Systemtabellen
 
@jobo
Danke, das wirkt (derzeit ohne Nebenwirkungen ;-)). Ich musste nur ein paar kleine Änderungen vornehmen, da IB7.1 bzw. FB2.0 das "case" im select nicht mag und ich per Parameter
die Tabelle auswähle, die mich interessiert.

Das also hat bei mir funktioniert:

Code:
select
rel.rdb$constraint_name as foreignkey,
co1.rdb$relation_name as detailtable,
/*
case idx.rdb$segment_count
  when 1 then fl1.rdb$field_name
  else idx.rdb$segment_count
end as fields,
*/
fl1.rdb$field_name,
idx.rdb$segment_count,
rel.rdb$const_name_uq as primarykey,
co2.rdb$relation_name as mastertable,
fl2.rdb$field_name as masterfield
from rdb$ref_constraints rel
/*  RDB$Relation_Constraints wird 2x benötigt:
    als co1 für den Tabellennamen des ForeignKey
    als co2 für den Tabellennamen des PrimaryKey, auf den sich der ForeignKey bezieht */
/*  ebenso RDB$Index_Segments
    als fl1 für den Spaltennamen des FK
    als fl2 für den Spaltennamen des PK */
left outer join rdb$relation_constraints co1 on rel.rdb$constraint_name = co1.rdb$constraint_name
left outer join rdb$indices idx on rel.rdb$constraint_name = idx.rdb$index_name
left outer join rdb$relation_constraints co2 on rel.rdb$const_name_uq = co2.rdb$constraint_name
left outer join rdb$index_segments fl1 on rel.rdb$constraint_name = fl1.rdb$index_name
left outer join rdb$index_segments fl2 on rel.rdb$const_name_uq = fl2.rdb$index_name
where
(not rel.rdb$constraint_name like 'RDB$')
and
co2.rdb$relation_name = :master_table
order by rel.rdb$constraint_name


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:42 Uhr.

Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf