How to remove/Delete the effect of UNIQUE KEY from TABLE - sql

I have UNIQUE KEY attribute on my Table. For my project I deleted that UNIQUE KEY from table , but when try to enter data it still giving the error of UNIQUE KEY VIOLATION.
Already done
to check to commit the database .
to refreshed the entire database.
to find that CONSTRAINT on schema.
SELECT DISTINCT table_name
FROM all_indexes
WHERE index_name = 'CONSTRAINT_NAME';
The above query returns no data (Constraint not found).
I want my data duplicate for one employee without UNIQUE KEY VIOLATION ERROR

Below are some of the queries you can run and check if there is specified index, constraints exist on the table and once you find you can simply drop it. Maybe your unique index was created before the constraint was created:
SELECT * FROM user_cons_columns WHERE table_name = '<your table name>';
select column_name from user_ind_columns where index_name = '<index_name>';
select column_name from user_cons_columns where constraint_name = '<index_name>';
Use below command for dropping index:
DROP INDEX index_name;
Use below command for dropping constraints:
ALTER TABLE <table_name>
DROP CONSTRAINT <constraint_name>

[TL;DR] If you have a UNIQUE INDEX without a UNIQUE CONSTRAINT then you will get the same error message. You need to make sure you have dropped both the index and the constraint.
CREATE TABLE test_data ( id NUMBER );
CREATE UNIQUE INDEX test_data__id__u ON test_data ( id );
ALTER TABLE test_data ADD CONSTRAINT test_data__id__u UNIQUE ( id );
INSERT INTO test_data ( id ) VALUES ( 1 );
INSERT INTO test_data ( id ) VALUES ( 1 );
Will insert one row and will give ORA-00001: unique constraint (FIDDLE_ALGCPMTPWFJZCXIPXNLR.TEST_DATA__ID__U) violated for the second.
If you do:
SELECT * FROM user_constraints WHERE table_name = 'TEST_DATA';
SELECT * FROM user_indexes WHERE table_name = 'TEST_DATA';
Then it will show there is an index and a constraint on the table.
Then if you drop the constraint:
ALTER TABLE test_data DROP CONSTRAINT test_data__id__u;
and try to do:
INSERT INTO test_data ( id ) VALUES ( 1 );
Then you will get:
ORA-00001: unique constraint (FIDDLE_ALGCPMTPWFJZCXIPXNLR.TEST_DATA__ID__U) violated
If you look at the indexes and constraints again:
SELECT * FROM user_constraints WHERE table_name = 'TEST_DATA';
SELECT * FROM user_indexes WHERE table_name = 'TEST_DATA';
Then it will show no constraints but the index is still there. You need to make sure the unique index has been dropped too.
DROP INDEX test_data__id__u;
INSERT INTO test_data ( id ) VALUES ( 1 );
Will then insert the row.
db<>fiddle here

Related

Show SQL constraints in multiple tables

Let say I have these 3 constraint given:
ALTER TABLE actor ADD CONSTRAINT PK_ACTORID PRIMARY KEY (actor_id);
ALTER TABLE film ADD CONSTRAINT PK_FILMID PRIMARY KEY (film_id);
ALTER TABLE film_actor ADD CONSTRAINT FK_FILMID1 FOREIGN KEY (film_id) REFERENCES film;
I need to write sql to show these table constraints:
-- Check which constraints added in ACTOR table
SELECT OWNER, CONSTRAINT_NAME, TABLE_NAME, SEARCH_CONDITION, INDEX_NAME
FROM USER_CONSTRAINTS
WHERE TABLE_NAME = 'ACTOR';
-- Check which constraints added in FILM_ACTOR table
SELECT OWNER, CONSTRAINT_NAME, TABLE_NAME, SEARCH_CONDITION, INDEX_NAME
FROM USER_CONSTRAINTS
WHERE TABLE_NAME = 'FILM_ACTOR';
And the result end up like:
and
My question is, how can I combine two sql statements I wrote as 1 sql and also formatting the result displayed.
Would changing your where statement work?
Something like this:
SELECT OWNER, CONSTRAINT_NAME, TABLE_NAME, SEARCH_CONDITION, INDEX_NAME
FROM USER_CONSTRAINTS
WHERE TABLE_NAME = 'ACTOR' or table_name = 'film' or table_name ='film_actor';

MERGE Constraint Error on self referenced table

MERGE is raising an Error
ORA-02291: integrity constraint violated-parent key not found
on inserting into a self referenced table.
If I change query a little bit with no matter, it will work.
Am I do something wrong.
Execution order:
Preparement stuff
First MERGE query (will not work)
Second MERGE query (will work)
The order of the columns in the MERGE query does not matter. You also can run the second MERGE before first.
If you would like to restart your test, start at DROP TABLE TGR.
First some preparement:
DROP TABLE SRC;
CREATE TABLE SRC (
ID VARCHAR(20) PRIMARY KEY,
PARENT VARCHAR(20)
);
INSERT INTO SRC SELECT '1', null FROM DUAL;
INSERT INTO SRC SELECT '2', '1' FROM DUAL;
DROP TABLE TRG;
CREATE TABLE TRG (
ID VARCHAR(20) PRIMARY KEY,
PARENT VARCHAR(20),
CONSTRAINT FK2 FOREIGN KEY(PARENT) REFERENCES TRG(ID)
);
This will not work:
MERGE INTO TRG t USING(
SELECT PARENT, ID FROM SRC
) s ON (t.ID=s.ID)
WHEN NOT MATCHED THEN INSERT(ID,PARENT) VALUES (s.ID,s.PARENT);
But this will work.
MERGE INTO TRG t USING(
SELECT ID, PARENT FROM SRC
) s ON (t.ID=s.ID)
WHEN NOT MATCHED THEN INSERT(ID,PARENT) VALUES (s.ID,s.PARENT);
If you change the datatype of these columns to NUMBER, it will work.
DROP TABLE SRC;
CREATE TABLE SRC (
ID NUMBER PRIMARY KEY,
PARENT NUMBER
);
INSERT INTO SRC SELECT 1, null FROM DUAL;
INSERT INTO SRC SELECT 2, 1 FROM DUAL;
DROP TABLE TRG;
CREATE TABLE TRG (
ID NUMBER PRIMARY KEY,
PARENT NUMBER,
CONSTRAINT FK2 FOREIGN KEY(PARENT) REFERENCES TRG(ID)
);
MERGE INTO TRG t USING(
SELECT PARENT, ID FROM SRC
) s ON (t.ID=s.ID)
WHEN NOT MATCHED THEN INSERT(ID,PARENT) VALUES (s.ID,s.PARENT);
Edit:
Forgot to tell: I am using 12c

Change datatype without changing "not null" constraint

I created table "A" with datatype VARCHAR2(3000) with "Not null" constraint. Table "A" has one column "someColumn" which is as primary key. As below:
CREATE TABLE A (
"someColumn" VARCHAR2(3000) NOT NULL
)
ALTER TABLE A
ADD CONSTRAINT pk_A PRIMARY KEY (
"someColumn"
)
Now I want change datatype from VARCHAR2(3000) to VARCHAR2(4000) but I don't want change constraint. So I used:
ALTER TABLE A
MODIFY
(
"someColumn" VARCHAR2(4000)
)
It worked and now I have ddl like below:
PROMPT CREATE TABLE a
CREATE TABLE a (
"someColumn" VARCHAR2(4000) NOT NULL
)
/
PROMPT ALTER TABLE a ADD CONSTRAINT pk_a PRIMARY KEY
ALTER TABLE a
ADD CONSTRAINT pk_a PRIMARY KEY (
"someColumn"
)
/
Then I used code as below:
ALTER TABLE A
MODIFY
(
"someColumn" VARCHAR2(3000) NULL
)
I got message "Alter table, executed..." but when I checked ddl again - I have "Not null" constraint still and new datatype (4000).
It's Oracle error?
To be sure that I don't have any cache in my "SQLTools" I am using:
SELECT * FROM all_tab_cols WHERE table_name = 'A'
Answer:
The change to NULLABLE fails but silently, so I see no error message.
on a column that is primary key you may change the length, but you can't do it nullable (because it is a PK which can't be NULL).
Initial state 3000 length NOT NULL
select COLUMN_NAME, DATA_LENGTH, NULLABLE from user_tab_columns where table_name = 'A';
COLUMN_NAME DATA_LENGTH N
------------------------------ ----------- -
someColumn 3000 N
Change length to 4000 - OK
ALTER TABLE A
MODIFY
(
"someColumn" VARCHAR2(4000)
)
;
select COLUMN_NAME, DATA_LENGTH, NULLABLE from user_tab_columns where table_name = 'A';
COLUMN_NAME DATA_LENGTH N
------------------------------ ----------- -
someColumn 4000 N
Change length to 3000 - OK
make it nullable - fails SILENTLY as PK can't be nullable
ALTER TABLE A
MODIFY
(
"someColumn" VARCHAR2(3000) NULL
);
select COLUMN_NAME, DATA_LENGTH, NULLABLE from user_tab_columns where table_name = 'A';
COLUMN_NAME DATA_LENGTH N
------------------------------ ----------- -
someColumn 3000 N
If you wan't to see a error message - split the change in two (change length and set nullable).
The first one will pass, the second will explicitely fail.
ALTER TABLE A
MODIFY
(
"someColumn" VARCHAR2(3000)
);
ALTER TABLE A
MODIFY
(
"someColumn" NULL
);
ORA-01451: column to be modified to NULL cannot be modified to NULL

Unique constraint on any combination of two columns

I am trying to implement a unique constraint for a combination of two columns. I am running oracle 11g.
Specifically I have two columns A and B.
I have a row like below
A B
1 2
Then I want the following combinations to fail when inserted
A B
1 2
2 1
Is this possible to achieve with a unique index in Oracle?
Yes, it is possible(for example using generated columns):
CREATE TABLE tab(A INT NOT NULL, B INT NOT NULL);
ALTER TABLE tab ADD c1 AS (LEAST(A,B));
ALTER TABLE tab ADD c2 AS (GREATEST(A,B));
CREATE UNIQUE INDEX UQ_tab ON tab(c1,c2);
You could hide these columns if needed(Oracle 12c):
ALTER TABLE tab MODIFY c1 INVISIBLE;
ALTER TABLE tab MODIFY c2 INVISIBLE;
DBFiddle Demo
EDIT:
Even simpler approach:
CREATE UNIQUE INDEX UQ_tab ON tab(least(A,B), greatest(A,B));
DBFiddle Demo
You can use a UNIQUE INDEX with LEAST, GREATEST and COALESCE functions:
CREATE TABLE table_name (
a INT,
b INT
);
CREATE UNIQUE INDEX table_name__a__b__u ON TABLE_NAME(
COALESCE( LEAST( a, b ), a, b ),
GREATEST( a, b )
);
You need to include COALESCE in case one of the values is NULL.
DBFiddle
INSERT INTO table_name ( a, b ) VALUES ( 1, 2 );
1 rows affected
INSERT INTO table_name ( a, b ) VALUES ( 3, NULL );
1 rows affected
INSERT INTO table_name ( a, b ) VALUES ( 2, 1 );
ORA-00001: unique constraint (SCHEMA_NAME.TABLE_NAME__A__B__U) violated
INSERT INTO table_name ( a, b ) VALUES ( NULL, 3 );
ORA-00001: unique constraint (SCHEMA_NAME.TABLE_NAME__A__B__U) violated

How can I make a copy of a table with a PK?

In an Oracle 10g database, I would like to make a copy of an existing table. I would like it to have the same data and rows as the original table. The original table uses a PK though, so I'm not sure how to copy it and keep them unique.
oracle maintains the pk as a column constraint. you have to copy the table and subsequently create this constraint for the new table.
the following code illustrates how to get your job done.
-- setting up table t1 - this is just for the sake of demonstration
create table t1 (
t_id integer
, t_data varchar2(40)
);
alter table t1 modify ( t_id constraint t1_pk primary key );
insert into t1 values ( 1, 'test');
insert into t1 values ( 2, 'another test');
insert into t1 values ( 3, 'final test');
commit;
-- copying table t1 (definition + contents) and defining the pk
create table t2 as ( select * from t1 );
alter table t2 modify ( t_id constraint t2_pk primary key );
hope this helps,
best regards,
carsten
You can make the copy using
CREATE TABLE dummy_copy as SELECT * FROM dummy//Structure and data
Also you could use dbms_metadata.get_ddl to get the associated constraints of the table
and create it with all the checks
SELECT dbms_metadata.get_ddl( 'TABLE', 'dummy' ) FROM DUAL;
Or you can just do it all in one statement:
create table mike_temp_1 (
col1,
col2,
col3,
col4,
col5,
constraint xpk_mike_temp_1 primary key (col1)
)
as select *
from OLD_POLICY_TERM;
I think the format of specifying column names when using create table as select is a bit fiddly in that I don't believe that you can specify data types (sort of obvious really) but you can specify constraints such as not null, primary key and foreign key.