Reputation: 4261
I have 2 tables:
T_CAMPAGNE_SMS_REPARTITION
and T_CAMPAGNE_SMS_EXECUTION
.
In T_CAMPAGNE_SMS_REPARTITION
there are 2 primary keys.
In T_CAMPAGNE_SMS_EXECUTION
there is 1 primary key and 4 foreign keys.
How can I add the 4th foreign key CLE_PARTITION
of T_CAMPAGNE_SMS_EXECUTION
?
I have tried this:
ALTER TABLE "T_CAMPAGNE_SMS_EXECUTION"
add constraint FK_REPARTITION foreign key("CLE_REPARTITION")
references "T_CAMPAGNE_SMS_REPARTITION"("CLE_REPARTITION");
but I got this error:
Erreur commençant à la ligne: 10 de la commande -
ALTER TABLE "T_CAMPAGNE_SMS_EXECUTION"
add constraint FK_REPARTITION foreign key("CLE_REPARTITION") references "T_CAMPAGNE_SMS_REPARTITION"("CLE_REPARTITION")
Rapport d'erreur -
Erreur SQL : ORA-02270: pas de correspondance de clé primaire ou unique pour cette liste de colonnes
02270. 00000 - "no matching unique or primary key for this column-list"
*Cause: A REFERENCES clause in a CREATE/ALTER TABLE statement
gives a column-list for which there is no matching unique or primary
key constraint in the referenced table.
*Action: Find the correct column names using the ALL_CONS_COLUMNS
catalog view
I have tried via a design like this:
but I still get the same error message.
Upvotes: 2
Views: 2982
Reputation: 15118
A table has one or more CKs (candidate keys): unique column sets that don't contain smaller unique column sets. At most one CK can be declared PK (primary key) per table by PRIMARY KEY; declare the others via UNIQUE NOT NULL.
You have one PK, with two columns. Having more than one column, it is composite.
An SQL FOREIGN KEY is list of columns whose values appear elsewhere as SQL PRIMARY KEY or UNIQUE NOT NULL. And the referenced list has to be declared unique even if it contains another declared unique column set. Your referenced list (CLE_REPARTITION) is not declared unique. So exactly as the error message says, there is no matching unique or primary key constraint in the referenced table
.
Maybe you want two one-column non-composite PKs instead of the 2-column PK. Maybe just (CLE_REPARTITION) is a CK/PK. Maybe you want a composite SQL FK instead of the 1-column one. Maybe you want T_CAMPAGNE_SMS_REPARTITION (CLE_REPARTITION) subrows to be T_CAMPAGNE_SMS_EXECUTION (CLE_REPARTITION) subrows even though they're not unique there. That's not a FK. It's an IND (inclusion dependency). It requires a trigger to enforce.
These constraints are determined by what a row says when it is in a table in a business situation and what situations/states can arise given business rules. Determine exactly what the constraints on your tables are and declare them per above.
Upvotes: 0
Reputation: 81
If you don't want to add a column in T_CAMPAGNE_SMS_EXECUTION then create a technical primary key on T_CAMPAGNE_SMS_REPARTITION. Something like T_CAMPAGNE_SMS_REPARTITION_ID which is a simple number linked to a sequence (or an IDENTITY column if you have an Oracle 12, see the doc here https://oracle-base.com/articles/12c/identity-columns-in-oracle-12cr1).
Change the Primary key contraint to a unique constraint on T_CAMPAGNE_SMS_REPARTITION to keep the behavior, and create a new column in T_CAMPAGNE_SMS_EXECUTION to link in to the newly created column.
The thing is that you can't reference only one part of the composite PK because you have no way to be sure that it's unique.
Hope this helps
Upvotes: 1
Reputation: 14169
You have a composite primary key made up of two columns, but in your FOREIGN KEY you are only referencing one of those two columns.
Put another column in your T_CAMPAGNE_SMS_EXECUTION for the second PK column with the name CLE_LOT_REPARTITION
After that, change your FOREIGN KEY constraint like so:
ALTER TABLE "T_CAMPAGNE_SMS_EXECUTION"
add constraint FK_REPARTITION foreign key("CLE_REPARTITION", "CLE_LOT_REPARTITION") references "T_CAMPAGNE_SMS_REPARTITION"("CLE_REPARTITION", "CLE_LOT_REPARTITION");
Upvotes: 0