Oracle composite primary key / foreign key question - sql

I have a composite primary key in 1 table in oracle. I want to create a foreign key for one table entry in my second table that references the composite primary key in the first table. I am getting the error ORA-02256. Any thoughts on how I can enter this?
CREATE TABLE groupspersonx (
personid number,
groupid number,
CONSTRAINT pk_persongroupid PRIMARY KEY(personid, groupid)
);
CREATE TABLE restrictedgroups (
groupid number,
name varchar2(50),
dateadded date,
since date,
notes varchar2(1024),
CONSTRAINT pk_groupid PRIMARY KEY(groupid),
CONSTRAINT fk_persongroup FOREIGN KEY(groupid) REFERENCES groupspersonx(personid, groupid)
);

The error is because the FOREIGN KEY is one column, but you're trying to supply two columns as the parent. There's no need to tie to the composite key, because the restrictedgroups doesn't have a personid column...
You also have the relationship backwards - use:
CREATE TABLE restrictedgroups (
groupid number,
name varchar2(50),
dateadded date,
since date,
notes varchar2(1024),
CONSTRAINT pk_groupid PRIMARY KEY(groupid)
);
CREATE TABLE groupspersonx (
personid number,
groupid number,
CONSTRAINT pk_persongroupid PRIMARY KEY(personid, groupid),
CONSTRAINT fk_persongroup FOREIGN KEY(groupid) REFERENCES restrictedgroups(groupid)
);
I would add a foreign key constraint for whatever table the personid would be coming from.

CREATE TABLE groupspersonx(
personid number, groupid number,
CONSTRAINT pk_persongroupid PRIMARY KEY(personid, groupid));
CREATE TABLE restrictedgroups (
pid number,
groupid number,
name varchar2(50),
dateadded date,
since date,
notes varchar2(1024),
CONSTRAINT pk_groupid PRIMARY KEY(groupid),
CONSTRAINT fk_persongroup FOREIGN KEY(pid,groupid) REFERENCES groupspersonx(personid, groupid));
* number of references columns is equals with foreign key columns

Whenever you want to create a composite primary key or unique constraint on a column, you can't give reference in another table.
for ex.
sql>create table t1( a number,b number,c number ,primary key(a,b,c));
table created.
sql>create table g1(a number constraint con_fg references t1(a));
ERROR at line 1:
ORA-02270: no matching unique or primary key for this column-list
Here t1 is parent table and g1 is child table. The child table can contains duplicate values in one column. So oracle will not allow that table of column.
See also
SQL>select constraint_name,constraint_type from user_constraints where table_name='T1';
CONSTRAINT_NAME C
------------------------------ -
SYS_C005822 P
So, here also the only constraint for all three columns i.e a,b,c in t1 table.
That's why you can't create a foreign on composite primary key or composite unique constraint

You can't use:
CONSTRAINT fk_persongroup FOREIGN KEY(groupid) REFERENCES groupspersonx(personid, groupid)
Change that too:
CONSTRAINT fk_persongroup FOREIGN KEY(groupid) REFERENCES groupspersonx(groupid)
That should work.

Related

PostgreSQL Partition and Unique Conflict

I am attempting to set up a database with partitions, however I am running into an error when creating the activity table. The 3 Table CREATEs (without the actual data) are as follows:
CREATE TABLE collection (
id SERIAL PRIMARY KEY
);
CREATE TABLE asset (
id SERIAL,
collection_id INT,
CONSTRAINT fk_collection
FOREIGN KEY(collection_id)
REFERENCES collection(id),
CONSTRAINT asset_pkey PRIMARY KEY(id, collection_id)
)PARTITION BY LIST(collection_id);
CREATE TABLE activity(
id SERIAL,
collection_id INT,
CONSTRAINT fk_collection
FOREIGN KEY(collection_id)
REFERENCES collection(id),
CONSTRAINT activity_pkey PRIMARY KEY(id, collection_id),
asset_id INT,
CONSTRAINT fk_asset
FOREIGN KEY(asset_id)
REFERENCES asset(id)
) PARTITION BY LIST(collection_id);
ERROR: there is no unique constraint matching given keys for referenced table "asset"
SQL state: 42830
My understanding of the error is that foreign keys must be unique. Because I must add collection_id as a primary key to partition item, I cannot also designate id as unique. When I attempt to make id unique, this is what happens:
ALTER TABLE asset
ADD CONSTRAINT u_id UNIQUE (id);
ERROR: unique constraint on partitioned table must include all partitioning columns
DETAIL: UNIQUE constraint on table "asset" lacks column "collection_id" which is part of the partition key.
SQL state: 0A000
Even if I successfully add the UNIQUE constraint on id and collection_id, it continues to throw me SQL state: 42830. Do I have to restructure my data or is there a better way to go about this that I'm not thinking of?
Would it be enough to merge the foreign keys on asset into one composite key, or does that violate some other constraint of your data?
CREATE TABLE activity(
id SERIAL,
collection_id INT,
asset_id INT,
CONSTRAINT activity_pkey PRIMARY KEY(id, collection_id),
CONSTRAINT fk_asset_collection
FOREIGN KEY(asset_id, collection_id)
REFERENCES asset(id, collection_id)
) PARTITION BY LIST(collection_id);

Cannot create table. SQL Error 02270

This is the table I am trying to create. However, I get the error
SQL Error: ORA-02270: no matching unique or primary key for this column-list
SQL:
create table Meets_In
(
cid char(20),
rno integer,
time char(20),
CONSTRAINT PRIM_KEY PRIMARY KEY(time),
constraint meets_fk1 foreign key(cid) references COURSES(CID),
constraint meets_fk2 foreign key(rno) references ROOMS(RNO)
);
These are the parent tables:
create table Courses
(
cid char(20),
cname char(20),
credits integer,
constraint CoursesKey Primary Key (cid, cname)
);
CREATE TABLE ROOMS
(
rno INTEGER,
address CHAR(20),
capacity INTEGER,
CONSTRAINT room_key PRIMARY KEY(rno)
);
I don't understand why I am getting this error.
Cause
The ORA-2270, as the error message suggests, happens when there is no matching unique or primary key for this column-list. This could be because
the parent lacks a constraint altogether
the parent table's constraint is a compound key and we haven't referenced all the columns in the foreign key statement.
Now in your COURSES table, CID is not a primary key. It is a combination of cid,cname. So for every cid, there can be multiple rows.
Now when you reference cid as foreign key for meets_in, it will not work as it violates the second point as I mentioned above.
Workaround
Add column cname in your meets_in table as well. Then use it like below.
create table Meets_In
(
cid char(20) not null,
cname char(20),
rno integer not null,
time1 char(20) not null,
CONSTRAINT PRIM_KEY PRIMARY KEY(time1),
constraint meets_fk1 foreign key(cid,cname) references COURSES (cid,cname), /*Added cid,cname */
constraint meets_fk2 foreign key(rno) references ROOMS (RNO)
);
Meets_In is acting as an associative table. Therefore its primary key should include the foreign keys into the tables it is associating.
Try a primary key consisting of: cid, cname, rno and time.
As others have noted, your primary key for courses is (cid, cname), so you also need to include both of these in your foreign key constraint meets_fk1. Or, if possible, ensure that cid only is the primary key on courses.
(I think time may be a reserved word, so perhaps consider renaming it.)

No matching unique or primary key for this column-list in Oracle

I have created PERSON table in Oracle by this SQL syntax:
Create table person
(
p_id int not null,
personName char(5) not null );
Then I am trying to create ORDERS table with the following syntax:
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
CONSTRAINT fk_PerOrders FOREIGN KEY (P_Id)
REFERENCES person(p_id) );
But I am getting the following error .
No matching unique or primary key for this column-list.
What is the problem ? How can I solve this ?
Add primary key to person table:
CREATE TABLE person(
p_id int not null,
personName char(5) not null,
PRIMARY KEY (p_ID)
);
SqlFiddleDemo
Foreign keys enforce a one-to-many relationship. That is, however many records there are in the dependent table they can only reference a single record in the parent table. This means the referenced column(s) in the parent table must be constrained by a PRIMARY or UNIQUE key.
The error message is telling you that there is no such constraint on person(p_id). And lo! if we compare the two DDL statements you have posted we can see that you have created a primary key for ORDERS but not for PERSON.
The solution is simple: constrain P_ID by adding a primary key to PERSON. You can either drop and re-create the table, or you can use an alter table statement to add a primary key.
You should add primary key to person table.
try this:
ALTER TABLE Person
ADD CONSTRAINT p_id PRIMARY KEY (p_id);

How to use two columns in a foreign key constraint

I have two tables:
Article
Subscription
In the Article table I have two columns that make up the primary key: id, sl. In the Subscription table I have a foreign key 'idsl`.
I use this constraint :
constraint FK_idsl
foreign key (idsl) references CSS_SubscriptionGroup(id, sl)
But when I run the query, I getting this error:
Number of referencing columns in foreign key differs from number of referenced columns, table X
In Article Table I have two fields that are the primary key: id,sl. In the Subscription Table I have a foreign key 'idsl`
This design is broken - it is apparent that the composite primary key in Article(id, sl) has been mangled into a single compound foreign key in table Subscription. This isn't a good idea.
Instead, you will need to change the design of table Subscription to include separate columns for both id and sl, of the same type as the Article Table, and then create a composite foreign key consisting of both columns, referencing Article in the same order as the primary key, e.g:
CREATE TABLE Article
(
id INT NOT NULL,
sl VARCHAR(50) NOT NULL,
-- Other Columns
CONSTRAINT PK_Article PRIMARY KEY(id, sl) -- composite primary key
);
CREATE TABLE Subscription
(
-- Other columns
id INT NOT NULL, -- Same type as Article.id
sl VARCHAR(50) NOT NULL, -- Same type as Article.sl
CONSTRAINT FK_Subscription_Article FOREIGN KEY(id, sl)
REFERENCES Article(id, sl) -- Same order as Article PK
);
Edit
One thing to consider here is that by convention a column named table.id or table.tableid should be unique, and is the primary key for the table. However, since table Article requires an additional column sl in the primary key, it implies that id isn't unique.
correct syntax for relation:
CONSTRAINT FK_OtherTable_ParentTable
FOREIGN KEY(OrderId, CompanyId) REFERENCES dbo.ParentTable(OrderId, CompanyId)
You must try like this:
constraint FK_idsl foreign key (id,sl) references CSS_SubscriptionGroup(id,sl)

SQL. How to reference a composite primary key Oracle?

I have two parent tables: Treatment and Visit.
Treatment table:
create table Treatment (
TreatCode CHAR(6) constraint cTreatCodeNN not null,
Name VARCHAR2(20),
constraint cTreatCodePK primary key (TreatCode),
);
Visit table:
create table Visit (
SlotNum NUMBER(2),
DateVisit DATE,
ActualArrivalTime DATE,
constraint cVisitSlotDatePK primary key (SlotNum, DateVisit)
);
Now I try to create a child table:
create table Visit_Treat (
TreatCode constraint cTreatCodeFK references Treatment(TreatCode),
SlotNum constraint cSlotNumFK references Visit(SlotNum),
DateVisit constraint cDateFK references Visit(DateVisit),
constraint cVisitTreatPK primary key (SlotNum, TreatCode, DateVisit)
);
Everything executes fine till the 3 line. Starting from the 3rd line, i.e. SlotNum constraint ... there is a message: no matching unique or primary key. There was already a similar question, but i did not quite get the logic to apply in my case. I reference each column one by one, and it works for the Treatment table parent. How should i correct reference Visit table parent?
CONSTRAINT fk_column
FOREIGN KEY (column1, column2, ... column_n)
REFERENCES parent_table (column1, column2, ... column_n)
in your case
create table Visit_Treat (
TreatCode CHAR(6) constraint cTreatCodeFK references Treatment(TreatCode),
SlotNum NUMBER(2),
DateVisit DATE,
constraint cVisitTreatPK primary key (SlotNum, TreatCode, DateVisit),
constraint fk_slotnumDatevisit FOREIGN KEY(SlotNum,DateVisit)
references Visit(SlotNum,DateVisit)
);
A foreign key must reference the primary key of the parent table - the entire primary key. In your case, the Visit table's primary key is SlotNum, DateVisit but the foreign key from Visit_Treat only references SlotNum.
You have two good options:
Add a DateVisit column to Visit_Treat and have the foreign key be SlotNum, DateVisit, referencing SlotNum, DateVisit in Visit.
Create a non-business primary key on Visit (for example a column named VisitID of type NUMBER, fed by a sequence), add a VisitID column to Visit_Treat, and make that the foreign key.
And two bad options:
Change the Visit primary key to be only SlotNum so your Visit_Treat foreign key will work. This probably isn't what you want.
Don't use a foreign key. I don't recommend this option. If you're having trouble setting up a foreign key that you know should exist, it generally means a design problem.