0

En utilisant "List of foreign keys and the tables they reference", je peux obtenir le nom de la table de jointure et une table avec laquelle elle se joint, mais pas le nom de la troisième table. Comment puis-je obtenir les trois tables/champs impliqués dans un plusieurs-à-plusieurs?Comment faire pour que les noms de tables et de colonnes soient impliqués dans une jointure plusieurs-à-plusieurs?

Par exemple, comment puis-je obtenir les éléments suivants (notez le r2_ * sur la deuxième ligne):

TableName Field  r_TableName r_Field r2_TableName r2_Field 
Users  VehicleId Vehicles Id  NULL   NULL 
UserGroups UserId  Groups  Id  Users   Id 
Cats  UserId  Users  Id  NULL   NULL 

Étant donné les tableaux suivants:

CREATE TABLE Users(
    Id NUMBER(10,0), 
    UserName NVARCHAR2(20), 
    VehicleId NUMBER(10,0), 
    CONSTRAINT user_pk PRIMARY KEY(ID) 
); 
ALTER TABLE Users ADD CONSTRAINT 
    users__vehicle_fk FOREIGN KEY(VehicleId) REFERENCES Vehicles(Id) ENABLE; 
CREATE TABLE Vehicles(
    ID NUMBER(10,0), 
    VehicleName NVARCHAR2(20), 
    CONSTRAINT vehicle_pk PRIMARY KEY(ID) 
); 
CREATE TABLE Cats(
    ID NUMBER(10,0), 
    CatName NVARCHAR2(20), 
    UserId NUMBER(10,0), 
    CONSTRAINT cat_pk PRIMARY KEY(ID) 
); 
ALTER TABLE Cats ADD CONSTRAINT 
    cat__user_fk FOREIGN KEY(UserId) REFERENCES Users(ID) ENABLE; 
CREATE TABLE Groups(
    Id NUMBER(10,0), 
    GroupName NVARCHAR2(20), 
    CONSTRAINT group_pk PRIMARY KEY(ID) 
); 
CREATE TABLE UserGroups (
    UserId NUMBER(10,0), 
    GroupId NUMBER(10,0), 
    CONSTRAINT user__groups_pk PRIMARY KEY(UserId, GroupId) 
); 
ALTER TABLE UserGroups ADD CONSTRAINT 
    userGroups__user_fk FOREIGN KEY(UserId) REFERENCES Users(Id) ENABLE; 
ALTER TABLE UserGroups ADD CONSTRAINT 
    userGroups__group_fk FOREIGN KEY(GroupId) REFERENCES GROUPS(ID) ENABLE; 

je travaille avec des variations de:

SELECT ac1.OWNER, ac1.CONSTRAINT_NAME, ac1.CONSTRAINT_TYPE, ac1.TABLE_NAME, 
    ac1.R_OWNER, ac1.R_CONSTRAINT_NAME, '@@@@@@@@@@' 
    , ac2.OWNER, ac2.CONSTRAINT_NAME, ac2.CONSTRAINT_TYPE, ac2.TABLE_NAME, 
    ac2.R_OWNER, ac2.R_CONSTRAINT_NAME, '@@@@@@@@@@' 
    ,conscols.*, '@@@@@@@@@@' 
    ,r_conscols.* 
FROM all_constraints ac1 
JOIN all_constraints ac2 
    ON ac1.r_constraint_name = ac2.constraint_name 
    AND ac1.owner = ac2.owner 
JOIN all_cons_columns conscols 
    ON ac1.owner = conscols.owner 
    AND ac1.CONSTRAINT_NAME = conscols.constraint_name 
JOIN all_cons_columns r_conscols 
    ON ac2.owner = r_conscols.owner 
    AND ac2.CONSTRAINT_NAME = r_conscols.constraint_name 
    AND r_conscols.POSITION = conscols.POSITION 

Je peux voir les données brutes pour les relations indirectes (comme la deuxième de trois lignes dans mon échantillon sortie), mais je ne vois pas de moyen clair de joindre ces données avec des relations directes de sorte que je sais qu'ils impliquent tous la même M: M rejoindre.

Remarque: Les relations qui vont plus loin que beaucoup: beaucoup d'entre elles utilisant une seule table de jointure n'ont pas besoin d'être prises en compte.

Comment puis-je obtenir ces données ensemble?

Répondre

0

Je ne suis pas sûr à 100% que c'est ce que vous voulez, mais aviez-vous l'intention d'utiliser des jointures externes plutôt que des jointures internes?

SELECT ac1.owner 
    , ac1.constraint_name 
    , ac1.constraint_type 
    , ac1.table_name 
    , ac1.r_owner 
    , ac1.r_constraint_name 
    , '@@@@@@@@@@' 
    , ac2.owner 
    , ac2.constraint_name 
    , ac2.constraint_type 
    , ac2.table_name 
    , ac2.r_owner 
    , ac2.r_constraint_name 
    , '@@@@@@@@@@' 
    , conscols.* 
    , '@@@@@@@@@@' 
    , r_conscols.* 
    FROM user_constraints ac1 
     LEFT OUTER JOIN user_constraints ac2 
      ON ac1.r_constraint_name = ac2.constraint_name 
      AND ac1.owner = ac2.owner 
     LEFT OUTER JOIN user_cons_columns conscols 
      ON ac1.owner = conscols.owner 
      AND ac1.constraint_name = conscols.constraint_name 
     LEFT OUTER JOIN user_cons_columns r_conscols 
      ON ac2.owner = r_conscols.owner 
      AND ac2.constraint_name = r_conscols.constraint_name 
      AND r_conscols.position = conscols.position 
+0

Merci pour la réponse, mais ce n'est pas tout à fait ce que je cherchais. –