Oracle foreign key allow one extra specific value - oracle

I have one simple table:
-- Create table
create table FAVOURITE_RULES
( rule_id NUMBER(9) not null,
user_id NUMBER(9) not null);
-- Create/Recreate primary, unique and foreign key constraints
alter table FAVOURITE_RULES
add constraint FAV_RULES_PK primary key (RULE_ID, USER_ID)
alter table FAVOURITE_RULES
add constraint FAV_RULES_RULE_ID_FK foreign key (RULE_ID)
references RULES (RULE_ID) on delete cascade;
alter table FAVOURITE_RULES
add constraint FAV_RULES_USER_ID foreign key (USER_ID)
references USER_AUTHENTICATION (USER_ID) on delete cascade;
I have a rule (from .Net code) that doesn't exist in the original table RULES. It has the Id=-999.
When I try to insert into the FAVOURITE_RULES I get an error about integrity constraint violation (as expected) (FAV_RULES_RULE_ID_FK) violated - parent key not found.
Can I keep the foreign key (FAV_RULES_RULE_ID_FK ) and allow extra only this value (-999) to be inserted?

May be this can help.
Step 1: drop fk constraint
Step 2: insert your violating row
Step 3: again create fk constraint with ENABLE NOVALIDATE

Related

oracle: deferring Foreign Key checks not working

oracle: deferring Foreign Key checks not working. e.g.,
create table Foo (id number(20,0), name varchar(20),
primary key(id));
create table Bar (id number(20,0), name varchar(20),
primary key(id),
constraint FK1 foreign key (id) references Foo (id));
insert into Foo(id,name) values(1, 'foo');
insert into Bar(id,name) values(1, 'bar');
delete data:
SET CONSTRAINTS ALL DEFERRED;
delete from Foo;
delete from Bar;
SET CONSTRAINTS ALL IMMEDIATE;
ERROR:
ORA-02292: integrity constraint violated - child record found
You can't defer a constraint if it is NOT DEFERRABLE. A constraint can be either deferrable or not, but the default (if you don't explicitly specify either way) is NOT DEFERRABLE.
In your sample code, add the keyword deferrable right after the foreign key constraint definition, and then run everything again. It will work as expected.
That is: Edit the following line of code
constraint FK1 foreign key (id) references Foo (id));
to
constraint FK1 foreign key (id) references Foo (id) deferrable);

Tried to have recursive relation

I use oracle and I try to have a recursive relation
CREATE TABLE "EVENT"
(
"EVENT_ID" NUMBER(18) NOT NULL, //primary key
"NAME" VARCHAR(20) NULL,
"RELATED_EVENT_ID" NUMBER(18) NULL //foreign key
);
Event 1 parent is Event 2....
When I try to create this table, I get this error.
ALTER TABLE "EVENT"
ADD CONSTRAINT "FK_RELATED_EVENT_ID"
FOREIGN KEY ("RELATED_EVENT_ID") REFERENCES "EVENT" ("RELATED_EVENT_ID")
Error report -
SQL 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.
*Action: Find the correct column names using the ALL_CONS_COLUMNS
catalog view
You have two problems:
There is no primary key constraint on this table.
The foreign key constraint you defined has RELATED_EVENT_ID referencing RELATED_EVENT_ID. I suspect that was just a typo.
Change your table definition to:
CREATE TABLE EVENT
(EVENT_ID NUMBER
NOT NULL
CONSTRAINT PK_EVENT
PRIMARY KEY
USING INDEX,
NAME VARCHAR2(20),
RELATED_EVENT_ID NUMBER);
Then add the foreign key constraint as
ALTER TABLE EVENT
ADD CONSTRAINT EVENT_FK1
FOREIGN KEY (RELATED_EVENT_ID) REFERENCES EVENT(EVENT_ID);
db<>fiddle here
EDIT
Note that the better way to handle this is to use a junction table, such as:
CREATE TABLE EVENT_EVENT
(EVENT_ID1 NUMBER
CONSTRAINT EVENT_EVENT_FK1
REFERENCES EVENT(EVENT_ID),
EVENT_ID2 NUMBER
CONSTRAINT EVENT_EVENT_FK2
REFERENCES EVENT(EVENT_ID),
CONSTRAINT PK_EVENT_EVENT
PRIMARY KEY (EVENT_ID1, EVENT_ID2)
USING INDEX);
Then you can drop the RELATED_EVENT_ID column from EVENT as you no longer need it.
According to oracle document :
Foreign key specifies that the values in the column must correspond to values in a
referenced primary key or unique key column or that they are NULL.
In your case, create primary key on column (EVENT_ID) and use it in reference clause as following:
ALTER TABLE "EVENT"
ADD CONSTRAINT "FK_RELATED_EVENT_ID"
FOREIGN KEY ("RELATED_EVENT_ID")
REFERENCES "EVENT" ("EVENT_ID") -- this
Now, use EVENT2's EVENT_ID as RELATED_EVENT_ID in EVENT1 record to make EVENT2 as parent of EVENT1.
Cheers!!

I'm trying to create foreign key between two tables but got: ORA-02270

Maybe I'm burnout, but I don't understand this. I have two tables in Oracle: TBL_a and TBL_x. I'm trying to create a foreign key between thos two tables as follows and get error
ORA-02270: no matching unique or primary key.
CREATE TABLE tbl_a (
cod_op integer,
cod_dni char(8),
cod_correl integer,
varchar2(50)
);
CREATE TABLE tbl_x (
cod_op integer,
cod_dni char(8),
blabla varchar2(50)
);
CREATE UNIQUE INDEX TBL_A_PK ON TBL_A (COD_OP);
CREATE UNIQUE INDEX TBL_x_PK ON TBL_x (COD_OP);
ALTER TABLE TBL_a ADD CONSTRAINT TBL_a_R01
FOREIGN KEY (COD_OP) REFERENCES TBL_x (COD_OP);
The problem is that you've created unique INDEXES on your tables, but you didn't create a unique or primary key CONSTRAINT. Oracle requires that the constraints exist in order to establish a foreign key relationship.
If you drop your existing indexes and add the appropriate constraints you can establish your foreign key relationship:
DROP INDEX TBL_A_PK;
DROP INDEX TBL_x_PK;
ALTER TABLE TBL_A
ADD CONSTRAINT UQ_A
UNIQUE(COD_OP)
USING INDEX;
ALTER TABLE TBL_X
ADD CONSTRAINT UQ_X
UNIQUE(COD_OP)
USING INDEX;
dbfiddle here
The table that is referred by the foreign key (here, tbl_x) must have a primary key or a unique constraint.
In your use case, as you are declaring a unique index on cod_op, you could simply make cod_op the primary key of tbl_x instead: that would make the error disappear.
Demo on DB Fiddle
In general, it is a good practice to have a primary key on any table. Extending the principe of turning your unique indexes to primary keys, your DDL statements could be simplified as follows:
CREATE TABLE tbl_x (
cod_op INTEGER PRIMARY KEY,
cod_dni CHAR(8),
blabla VARCHAR2(50)
);
CREATE TABLE tbl_a (
cod_op INTEGER PRIMARY KEY,
cod_dni CHAR(8),
cod_correl INTEGER,
blabla VARCHAR2(50),
CONSTRAINT TBL_a_R01 FOREIGN KEY (COD_OP) REFERENCES TBL_x (COD_OP)
);
Demo on DB Fiddle

Oracle foreign key constraints - check constraint syntax?

I have a child table in oracle that has two foreign key columns, relating to two different parent tables. I want to create a constraint that says the child must have at least one of those parents - e.g.
ALTER TABLE table_name
ADD CONSTRAINT constraint_name
FOREIGN KEY (column1)
REFERENCES parent_table (column1)
OR
FOREIGN KEY (column2)
REFERENCES parent_table_2 (column1)
This won't work with a foreign key constraint because that can only relate to one parent table - is it possible to do this with a check constraint instead?
Foreign key constraints ensure the referential integrity, not mandatory values.
I think you have to have to separate FK contraints and additional check constraint like this:
alter table table_name
add constraint c_check_cols
check(column1 is not null or column2 is not null);
You can do it with constraints:
ALTER TABLE table_name
ADD CONSTRAINT constraint_name_1
FOREIGN KEY (column1)
REFERENCES parent_table (column1);
ALTER TABLE table_name
ADD CONSTRAINT constraint_name_2
FOREIGN KEY (column2)
REFERENCES parent_table_2 (column1);
ALTER TABLE table_name
ADD CONSTRAINT constraint_name_3
check (COALESCE(column1, column2) IS NOT NULL);
Of course for column1 and column2 column you must permit NULL values.

why deletion taking time and creating lock in oracle?

I have a table with around 3,00,000 records, like
CREATE TABLE xxx
( xxx_PK NUMBER(10,0),
CREATEDTIME TIMESTAMP (6),
MODIFIEDTIME TIMESTAMP (6),
CREATOR NUMBER(10,0),
LASTMODIFIER_FK NUMBER(10,0),
a_FK NUMBER(10,0),
b_FK NUMBER(10,0),
c_FK NUMBER(10,0),
d_FK NUMBER(10,0),
e_FK NUMBER(10,0),
f NUMBER(10,0),
PRIMARY KEY (xxx_PK),
CONSTRAINT FOREIGN KEY (LASTMODIFIER_FK)
REFERENCES USERS (USERID_PK) ENABLE NOVALIDATE,
CONSTRAINT FOREIGN KEY (a_FK)
REFERENCES a (a_PK) ENABLE NOVALIDATE,
CONSTRAINT FOREIGN KEY (b_FK)
REFERENCES b (b_PK) ENABLE NOVALIDATE,
CONSTRAINT FOREIGN KEY (c_FK)
REFERENCES c (c_PK) ENABLE NOVALIDATE,
CONSTRAINT FOREIGN KEY (d_FK)
REFERENCES d (d_PK) ENABLE NOVALIDATE,
CONSTRAINT FOREIGN KEY (e_FK)
REFERENCES e (e_PK) ENABLE NOVALIDATE
);
CREATE INDEX f_INDEX ON xxx (f) ;
When I am trying to truncate, getting error -
ora 02266
02266, 00000, "unique/primary keys in table referenced by enabled foreign keys"
*Cause: An attempt was made to truncate a table with unique or
primary keys referenced by foreign keys enabled in another table.
Other operations not allowed are dropping/truncating a partition of a
partitioned table or an ALTER TABLE EXCHANGE PARTITION.
*Action: Before performing the above operations the table, disable the
foreign key constraints in other tables. You can see what
constraints are referencing a table by issuing the following
command:
SELECT * FROM USER_CONSTRAINTS WHERE TABLE_NAME = "tabnam";
We also table yyy and zzz which contains reference of table xxx. Table yyy and zzz is empty.
EDIT -
When I disabled constraint of his child table yyy and zzz, it was successfully truncated.
Please suggest what should I do.
You need Foreign Keys with cascade delete
in linked tables.

Resources