web-dev-qa-db-fra.com

ORA-02270: pas de clé unique ou primaire correspondante pour cette liste de colonnes

J'obtiens un rapport d'erreur de:

Rapport d'erreur - 
 Erreur SQL: ORA-02270: aucune clé unique ou primaire correspondante pour cette liste de colonnes 
 02270. 00000 - "pas de clé primaire ou unique correspondante pour cette liste de colonnes" 
 * Cause: une clause REFERENCES dans une instruction CREATE/ALTER TABLE 
 Donne une liste de colonnes pour laquelle il n'y a pas d'unique correspondant ou la contrainte de clé primaire 
 dans la table référencée. 
 * Action: recherchez les noms de colonne corrects à l'aide de la vue catalogue ALL_CONS_COLUMNS 
 

Puis-je savoir pourquoi?

table parent

    CREATE TABLE STUDENTINFO
    (
      Student_ID VARCHAR2 (10) PRIMARY KEY,
      Full_Name VARCHAR2 (50) NOT NULL,
      Contact_Number NUMBER (15)NOT NULL,
      Address VARCHAR2 (50) NOT NULL,
      Nationality VARCHAR2 (15) NOT NULL,
      IC_PassportNo VARCHAR2 (15) NOT NULL,
      Programme VARCHAR (75) NOT NULL,
      Email_Address VARCHAR2 (50) NOT NULL REFERENCES                    USERNAMEPASSWORD(Username),
      Parents_Number NUMBER (15)NOT NULL,
      Fingerprint_Template clob
    );

table enfant

    create table bit_2015_sep_cit4114_fyp_G_
    ( 
      Student_ID VARCHAR2 (10) PRIMARY KEY REFERENCES STUDENTINFO(Student_ID),
      Full_Name VARCHAR2 (50) NOT NULL REFERENCES STUDENTINFO(Full_Name),
      Nationality VARCHAR2 (15) NOT NULL REFERENCES STUDENTINFO(Nationality),
      Fingerprint_Template CLOB NOT NULL REFERENCES        STUDENTINFO(Fingerprint_Template),
     "23/10/2015" VARCHAR2 (15) not null, 
   );

Je garde la nationalité et les empreintes digitales en double car cela prendra beaucoup de temps à vérifier sur la base de toutes les informations stockées dans studentinfo, donc en se divisant en classe individuelle sera plus facile et plus rapide. comme pour la table STUDENTINFO comprend 1 million d'enregistrements, dans la table bit_2015_sep_cit4114_fyp_G_ n'aura que 40 enregistrements. Je garde la colonne nationalité parce que j'ai une colonne de plus dans ma structure de tableau qui est le renouvellement de visa qui est calculé en fonction de la valeur de nationalité dans le tableau.

5
Software Engineer

L'erreur s'est produite car vous faites référence à une colonne dans une autre table qui n'est pas unique. Les bonnes réponses sont déjà données par Lennart et Balazs Papp.

Je voudrais expliquer pourquoi avons-nous besoin d'une colonne unique dans la table parent. Comme vous l'avez dit, vous souhaitez conserver les valeurs en double dans la colonne utilisée pour la clé étrangère, ce qui n'est pas possible lors de la création de la table. Mais vous pouvez créer une référence à une table existante qui contient des valeurs en double.

Si vous créez une clé primaire avec un index non unique et l'option NOVALIDATE, c'est possible. MAIS cela peut conduire à des résultats confus.

Permettez-moi d'expliquer une situation.

J'ai créé une table avec une colonne ID qui a une contrainte de clé primaire avec un index non unique.

SQL>CREATE TABLE t1(id NUMBER);
SQL>CREATE INDEX t1_index on t1(id);
SQL>INSERT INTO t1 VALUES(1);
SQL>INSERT INTO t1 VALUES(1);
SQL>COMMIT;
SQL>SELECT id FROM t1;

    ID
----------
     1
     1

SQL>ALTER TABLE t1 ADD CONSTRAINT t1_pk PRIMARY KEY (id) USING INDEX t1_index NOVALIDATE;

Créons une autre table pour référencer la première table.

SQL>CREATE TABLE t2(id NUMBER, CONSTRAINT t2_fk FOREIGN KEY(id) REFERENCES t1(id));

Générez des enregistrements.

SQL>INSERT INTO t2 VALUES(1);
SQL>COMMIT;

Table t2 a une valeur 1 qui fait référence à la table parent t1 qui a une valeur en double de 1. Lequel id de la table enfant fera référence?

Dans le scénario ci-dessus, la clé étrangère fonctionne correctement mais la clé primaire dans la table t1 ne fonctionne que pour les nouvelles valeurs.

Conclusion: Une clé étrangère doit toujours faire référence à une ou plusieurs colonnes déclarées comme PRIMARY KEY ou UNIQUE dans Oracle.

5
JSapkota

Le nom complet, etc. n'est pas déclaré comme unique dans la table parent, et vous ne pouvez donc pas les référencer à partir de la table enfant.

Pourquoi avez-vous besoin de dupliquer ces colonnes dans la table enfant?

ÉDITER:

En verrouillant votre table enfant, vous dites que:

create table bit_2015_sep_cit4114_fyp_G_
( ...
, Full_Name VARCHAR2 (50) NOT NULL 
      REFERENCES STUDENTINFO(Full_Name)

Cela signifie qu'il doit y avoir une ligne unique dans STUDENTINFO avec ce nom complet. C'est à dire. vous devez déclarer cette table:

CREATE TABLE STUDENTINFO
( ...
, Full_Name VARCHAR2 (50) NOT NULL
     UNIQUE,

Je doute que full_name soit unique, ce qui signifie que vous ne pouvez pas déclarer de clé étrangère sur cette colonne.

Vous semblez supposer qu'il y aura des problèmes de performances plus tard et par conséquent, vous dénormalisez votre base de données. OMI, c'est une grosse erreur, commencez par une base de données normalisée et dénormalisez uniquement lorsqu'il y a des raisons de le faire.

Si vous insistez pour dénormaliser, vous pouvez utiliser une astuce comme:

CREATE TABLE STUDENTINFO
( Student_ID VARCHAR2 (10) PRIMARY KEY
, Full_Name VARCHAR2 (50) NOT NULL
, Contact_Number NUMBER (15)NOT NULL
, Address VARCHAR2 (50) NOT NULL
, Nationality VARCHAR2 (15) NOT NULL
...
,    constraint AK1_STUDENTINFO unique (Student_ID, Full_Name, Nationality)

Étant donné que Student_ID est unique, il s'ensuit que Student_ID, Full_Name, Nationality doivent également être uniques. J'ai exclu Fingerprint_Template car je doute que cela puisse être utilisé dans des clés étrangères (je ne sais pas si, si c'est possible, vous pouvez l'ajouter)

create table bit_2015_sep_cit4114_fyp_G_
( Student_ID VARCHAR2 (10) PRIMARY KEY
, Full_Name VARCHAR2 (50) NOT NULL 
, Nationality VARCHAR2 (15) NOT NULL
...
,    constraint fk_studentinfo foreign key (Student_ID, Full_Name, Nationality)
                references studentinfo (Student_ID, Full_Name, Nationality)

);

Mais comme mentionné, commencez par une conception normalisée et voyez si cela fonctionne

6
Lennart

Les colonnes référencées par une contrainte de clé étrangère doivent avoir un PK ou une contrainte unique dans la table référencée. Ce n'est pas vrai pour Full_Name, Nationality, Fingerprint_Template. Pour être honnête, ces contraintes FK ne sont pas nécessaires, supprimez-les et conservez la contrainte FK sur Student_ID. Aussi:

"23/10/2015" VARCHAR2 (15) not null, 

Ce n'est pas une définition de colonne valide. C'est:

column_name varchar2(15) default '23/10/2015' not null
3
Balazs Papp