Not able to add a new column to the existing primary key - oracle

I have a primary key PK1 for the table TABLE1. Need to add one more column to the existing primary key.
I was tying the following alter script
ALTER TABLE TABLE1
ADD CONSTRAINT "PRIMARYKEYS" PRIMARY KEY
("PK1",
"PK2");
Error report:
SQL Error: ORA-02260: table can have only one primary key
02260. 00000 - "table can have only one primary key"
*Cause: Self-evident.
*Action: Remove the extra primary key.
How can I add one more column to the primary key, without affecting the data(data has been verified , there are no duplication.)

If you have concern about new data that violates PK can be added during the time interval when the old PK dropped, but the new one is not created, you can create a unique index first :
CREATE UNIQUE INDEX IDXU_TABLE1_PK ON TABLE1(PK1,PK2);
ALTER TABLE TABLE1 DROP CONSTRAINT [old_pk_constraint_name] ;
ALTER TABLE TABLE1 ADD CONSTRAINT "PRIMARYKEYS" PRIMARY KEY
(PK1,PK2) USING INDEX IDXU_TABLE1_PK;
Another option is to keep index associated with the old PK constraint until new PK is created :
ALTER TABLE TABLE1 DROP CONSTRAINT [old_pk_constraint_name] KEEP INDEX;
ALTER TABLE TABLE1 ADD CONSTRAINT "PRIMARYKEYS" PRIMARY KEY
(PK1,PK2) ;
DROP INDEX [name of unique index associated with the old PK constraint];

You need to drop old primary key first.

Related

In which order should we apply primary key, foreign key constraints and create index if the Oracle table has data?

1.In which order should we apply primary key, foreign key constraints and create index if the Oracle table has millions of data and does not have prior constraints?
2.Can we use 'NOLOGGING PARALLEL' while applying primary key and foreign key constraints like we do while applying(creating) indexes? Or any other method so that primary key and foreign key constraints could be applied faster?
Note: I'll use bullets so that it is easier to read, as it is easy to get lost in long sentences.
My thoughts on the subject; see if anything of this helps.
Well,
as you can't create a foreign key constraint if column(s) it references aren't part of primary or unique key
you'll obviously first have to create primary key constraints
and then foreign key constraints
When you
create a primary key constraint,
Oracle automatically creates index that supports it, unless there's already an index you can use (with the USING INDEX clause)
which means that you can "skip" some indexes (those for primary key constraints as they'll already exist) and virtually save some time
and create "other" indexes
On the other hand,
if you first create unique index on future primary key columns and
later add primary key constraint with the USING INDEX clause, Oracle will "skip" check for possible duplicate values because unique index won't allow them
The same goes for
NOT NULL constraint on future primary key columns; primary key doesn't allow NULLs so - if a column already is NOT NULL, enforcing primary key constraint can skip NULL check as well
I don't know
which columns you'll additionally index, but - as you're on Oracle 11g -
don't forget to index all foreign key constraint columns
because you might encounter unexpected table locks if you
update primary key column in parent table, or
delete parent record
Can you do it with no logging and in parallel? Yes:
SQL> create table test (id number, name varchar2(20));
Table created.
SQL> create unique index ui1_test_id on test (id) nologging parallel 20;
Index created.
SQL> alter table test add constraint pk_test primary key (id) using index ui1_test_id nologging parallel 20;
Table altered.
SQL>
But you'll probably want to change the index and table back to NOPARALLEL and LOGGING when the initial creation is done.
SQL> alter index ui1_test_id noparallel;
Index altered.
SQL> alter table test logging noparallel;
Table altered.

Still Getting Errors After Applying All I've Read About the Error 02270

I'm creating a couple of Tables for an assignment.
So I created a Gardener Table and an Offering Table, with all the appropriate data types and NULL statuses, as well as the Primary Key constraint for each. In the Gardener table I've included offeringID, and vice versa.
When I try to add Foreign Key constraint offeringID to the Gardener Table I get an error.
After checking online, I realized I had forgotten to make offeringID and gardenerID in each other's tables UNIQUE, hence I altered table to add uniqueness.
Tried adding Foreign Key constraint and I get the same error. I reckon I may be understanding something wrongly, but I can't seem to put my finger on it.
Create Table Gardener
(gardenerID NUMBER(10) NOT NULL,
offeringID NUMBER(10) NOT NULL,
CONSTRAINT gardener_pk PRIMARY KEY(gardenerID)
);
Create Table Offering
(offeringID NUMBER(10) NOT NULL,
gardenerID NUMBER(10) NOT NULL,
CONSTRAINT offering_pk PRIMARY KEY(offeringID)
);
Alter Table Gardener
add CONSTRAINT offering_fk FOREIGN KEY(offeringID)
REFERENCES Offering(offeringID);
Alter Table Gardener
add Unique(offeringID);
Alter Table Offering
add Unique(gardenerID);
This is the error:
ORA-02270: no matching unique or primary key for this column-list
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.
Like, I still don't get it. Isn't offeringID a Primary Key hence pointing to it from Gardener shouldn't be an issue still?
Since you're trying to add a a foreign key constraint for offering.offeringID column within the Gardener table, whereas that column has no unique/primary key key when you try to add a foreign key. i.e. operation stops at the 3rd command.
So, just exchange the order of commands as :
Alter Table Gardener
add Unique(offeringID); -- should be prior to the below command
Alter Table Gardener
add CONSTRAINT offering_fk FOREIGN KEY(offeringID)
REFERENCES Offering(offeringID);
Demo

how to add sequence to primary key in plSQL

I'm using pl sql developer 12.what i want is to add the make the primary key sequential using oracle 12' windows and forms , not by scripting. I can't find out how?.
aslo, how can i make one to one relation between 2 tables (user,role), in user table i added role_id as foreign key; but the relation seem one to many!!!
In Oracle 12c and above, you define that column as identity columns:
CREATE TABLE mytable (
id NUMBER GENERATED ALWAYS AS IDENTITY,
-- other columns ...
);
A #Mureinik already said, in Oracle 12 and higher versions you can define your primary key column as NUMBER GENERATED ALWAYS AS IDENTITY to get a unique sequential value.
To enforce a one-to-one relationship in the database you'd want to have your ROLE_ID column defined as a primary key on one table, and as either a UNIQUE or PRIMARY key on the second table, with a foreign key relationship between the tables. In other words:
CREATE TABLE T1 (ROLE_ID NUMBER
CONSTRAINT PK_T1
PRIMARY KEY
...);
CREATE TABLE T2 (ID_T2 NUMBER
PRIMARY KEY,
ROLE_ID NUMBER
CONSTRAINT T2_U1
UNIQUE
CONSTRAINT T2_FK1
REFERENCES T1(ROLE_ID)
ON DELETE CASCADE,
...);
After the above ROLE_ID will be the primary key on T1, a unique key on T2, and T2.ROLE_ID will be a foreign key to T1.
Best of luck.
what I have done lastly is that i downloaded sql developer 64 w, and from it; I connected with the database then I made the column sequential

Why dropping a primary key is not dropping its unique index?

I have a table with Col1 and Col2 as a composite primary key pk_composit_key and a unique index that was automatically created for the constraint.
I then altered the table to add new column Col3.
I dropped the pk_composit_key constraint:
ALTER TABLE table_name DROP CONSTRAINT pk_composit_key;
Now, When I tried to insert records I got ORA-00001: unique constraint pk_composit_key violated.
Why am I getting that error?
When the key was dropped why wasn't the unique index dropped automatically?
You mentioned exporting and importing the schema, and if that happened in the environment that showed this behaviour it would explain what you're seeing; at least if you used legacy imp rather than the data pump impdp.
The original import documentation states the order objects are imported:
Table objects are imported as they are read from the export dump file. The dump file contains objects in the following order:
Type definitions
Table definitions
Table data
Table indexes
Integrity constraints, views, procedures, and triggers
Bitmap, function-based, and domain indexes
So the unique index would have been imported, then the constraint would have been created.
When you drop a primary key constraint:
If the primary key was created using an existing index, then the index is not dropped.
If the primary key was created using a system-generated index, then the index is dropped.
Because of the import order, the constraint is using an existing index,so the first bullet applies; and the index is retained when the constraint is dropped.
You can use the drop index clause to drop the index even if it wasn't created automatically:
ALTER TABLE table_name DROP CONSTRAINT pk_composit_key DROP INDEX;
See also My Oracle Support note 370633.1; and 1455492.1 suggests similar behaviour will occur with data pump import as well. I'm not aware of any way to check if an index is associated with a constraint at this level; there is no difference in the dba_constraints or dba_indexes views when you create the index manually or automatically. Including drop index will make it consistent though.
It depends on how unique index was created...below are the various ways and behaviour
1) first create unique index (on the column for which primary key to be defined) and then add the primary key constraint. In this situation your DDL to add the primary key will utilize the existing unique index. So when you drop the primary key it will not drop the index but only primary key. ==> this is your situation I guess...
2) While creating the table you define the primary key OR when you add the primary key when there was no existing unique index for the column(s) on which primary key to be defined, so system will create a unique index and use it for primary key. So in this case when you drop the primary key the unique index will also get dropped.

does foreign key always reference to a unique key in another table?

Is it not possible that foreign key(single column) in a child table references to a parent key which has some duplicate values?
By the SQL standard, a foreign key must reference either the primary key or a unique key of the parent table. If the primary key has multiple columns, the foreign key must have the same number and order of columns. Therefore the foreign key references a unique row in the parent table; there can be no duplicates.
Re your comment:
If T.A is a primary key, then no you can't have any duplicates. Any primary key must be unique and non-null. Therefore if the child table has a foreign key referencing the parent's primary key, it must match a non-null, unique value, and therefore references exactly one row in the parent table. In this case you can't make a child row that references multiple parent rows.
You can create a child row whose foreign key column is NULL, in which case it references no row in the parent table.
No, it is not possible.
When you define a foreign key constraint on a table, it means there is only one corresponding key on the foreign table. If multiples existed on the foreign table which one would be meant?
Wikipedia has this definition on the Foreign key entry:
A foreign key is a field in a relational table that matches a candidate key of another table
Candidate keys are unique within a table.
Yes, it is possible for a foreign key to reference a column with duplicate values.
This can happen if the primary key uses a non-unique index and is not validated when it is created. (But I have never seen a situation like this in real life. As #Bill Karwin pointed out, it would be very confusing. So this may not be a situation you really need to worry about.)
--Create a table with two duplicate rows
create table test1(a number);
insert into test1 values(1);
insert into test1 values(1);
commit;
--Create a non-unique index
create index test1_index on test1(a);
--Use the non-unique index for the primary key, do not validate
alter table test1 add constraint test1_pk primary key (a)
using index test1_index novalidate;
--Build another table with a foreign key to TABLE1
create table test2(a number,
constraint test2_fk foreign key (a) references test1(a));
--Inserting a value that refers to the duplicate value still works.
insert into test2 values(1);
commit;
--The foreign key still works:
--ORA-02291: integrity constraint (TEST2_FK) violated - parent key not found
insert into test2 values(2);
--The primary key works as expected, but only for new values:
--ORA-00001: unique constraint (TEST1_PK) violated
insert into test1 values(1);

Resources