I got the problem is when I run following command in Oracle, I encounter the error.
Truncate table mytable;
Errors:
ORA-02266: unique/primary keys in table referenced by enabled foreign keys
I found that, this mytable has relationship with other tables. That's why Truncate command cannot proceed anymore. How to delete data from myTable with the SQL scripts using Truncate command?
You have to swap the TRUNCATE statement to DELETE statements, slower and logged but that's the way to do it when constraints are in place.
DELETE mytablename;
Either that or you can find the foreign keys that are referencing the table in question and disable them temporarily.
select 'ALTER TABLE '||TABLE_NAME||' DISABLE CONSTRAINT '||CONSTRAINT_NAME||';'
from user_constraints
where R_CONSTRAINT_NAME='<pk-of-table>';
Where pk-of-table is the name of the primary key of the table being truncated
Run the output of the above query. When this has been done, remember to enable them again, just change DISABLE CONSTRAINT into ENABLE CONSTRAINT
this page offers a very good solution ...
ORA-02266: unique/primary keys in table referenced by enabled foreign keys
I'm here copying from it the Solution:
Find the referenced ENABLED foreign key constraints and disable them.
truncate/delete from the table .
using any text editor .. just change disable to enable in the output you get from the query , then run it.
select 'alter table '||a.owner||'.'||a.table_name||' disable constraint '||a.constraint_name||';'
from all_constraints a, all_constraints b
where a.constraint_type = 'R' and a.status='ENABLED'
and a.r_constraint_name = b.constraint_name
and a.r_owner = b.owner
and b.table_name = upper('YOUR_TABLE');
The error message is telling you that there are other table(s) with a foreign key constraint referring to your table.
According to the Oracle docs
You cannot truncate the parent table
of an enabled foreign key constraint.
You must disable the constraint before
truncating the table.
The syntax for disabling a foreign key is:
ALTER TABLE table_name disable
CONSTRAINT constraint_name;
Issue:
Error “ORA-02266: unique/primary keys in table referenced by enabled foreign keys” when trying to truncate a table.
Error Message:
SQL> truncate table TABLE_NAME;
truncate table TABLE_NAME
*
ERROR at line 1:
ORA-02266: unique/primary keys in table referenced by enabled foreign keys
Solution:
-- Find the referenced foreign key constraints.
SQL> select 'alter table '||a.owner||'.'||a.table_name||' disable constraint '||a.constraint_name||';'
2 from all_constraints a, all_constraints b
3 where a.constraint_type = 'R'
4 and a.r_constraint_name = b.constraint_name
5 and a.r_owner = b.owner
6 and b.table_name = 'TABLE_NAME';
'ALTER TABLE'||A.OWNER||'.'||A.TABLE_NAME||'DISABLE CONSTRAINT'||A.CONSTRAINT_NAME||';'
---------------------------------------------------------------------------------------------------------
alter table SCHEMA_NAME.TABLE_NAME_ATTACHMENT disable constraint CONSTRAINT_NAME;
alter table SCHEMA_NAME.TABLE_NAME_LOCATION disable constraint CONSTRAINT_NAME;
-- Disable them
alter table SCHEMA_NAME.TABLE_NAME_ATTACHMENT disable constraint CONSTRAINT_NAME;
alter table SCHEMA_NAME.TABLE_NAME_LOCATION disable constraint CONSTRAINT_NAME;
-- Run the truncate
SQL> truncate table TABLE_NAME;
Table truncated.
-- Enable the foreign keys back
SQL> select 'alter table '||a.owner||'.'||a.table_name||' enable constraint '||a.constraint_name||';'
2 from all_constraints a, all_constraints b
3 where a.constraint_type = 'R'
4 and a.r_constraint_name = b.constraint_name
5 and a.r_owner = b.owner
6 and b.table_name = 'TABLE_NAME';
'ALTER TABLE'||A.OWNER||'.'||A.TABLE_NAME||'ENABLE CONSTRAINT'||A.CONSTRAINT_NAME||';'
--------------------------------------------------------------------------------
alter table SCHEMA_NAME.TABLE_NAME_ATTACHMENT enable constraint CONSTRAINT_NAME;
alter table SCHEMA_NAME.TABLE_NAME_LOCATION enable constraint CONSTRAINT_NAME;
-- Enable them
alter table SCHEMA_NAME.TABLE_NAME_ATTACHMENT enable constraint CONSTRAINT_NAME;
alter table SCHEMA_NAME.TABLE_NAME_LOCATION enable constraint CONSTRAINT_NAME;
Oracle 12c introduced a feature to truncate a table that is a parent of a referential integrity constraint having ON DELETE rule.
Instead of truncate table tablename; use:
TRUNCATE TABLE tablename CASCADE;
From Oracle truncate table documentation:
If you specify CASCADE, then Oracle Database truncates all child tables that reference table with an enabled ON DELETE CASCADE referential constraint. This is a recursive operation that will truncate all child tables, granchild tables, and so on, using the specified options.
A typical approach to delete many rows with many constraints is as follows:
create mytable_new with all the columns but without constrains (or create constraints disabled);
copy whatever data you need from mytable to mytable_new.
enable constraints on mytable_new to see that everything is ok.
alter any constraints that reference mytable to reference mytable_new instead and see that everything is ok.
drop table mytable.
alter table mytable_new rename to mytable.
It's far faster than deleting a million records with many slow constraints.
I had the similar issue and I sorted it out by the following scripts.
begin
for i in (select constraint_name, table_name from user_constraints a where a.owner='OWNER' and a.table_name not in
(select b.table_name from user_constraints b where b.table_name like '%BIN%')
and a.constraint_type not in 'P')
LOOP
execute immediate 'alter table '||i.table_name||' disable constraint '||i.constraint_name||'';
end loop;
end;
/
truncate table TABLE_1;
truncate table TABLE_2;
begin
for i in (select constraint_name, table_name from user_constraints a where a.owner='OWNER' and a.table_name not in
(select b.table_name from user_constraints b where b.table_name like '%BIN%')
and a.constraint_type not in 'P')
LOOP
execute immediate 'alter table '||i.table_name||' enable constraint '||i.constraint_name||'';
end loop;
end;
/
This script will first disable all the Constraints. Truncates the data in the tables and then enable the contraints.
Hope it helps.
cheers..
TRUNCATE TABLE TEST2 DROP ALL STORAGE;
This statement Actually works when there is an foreign key constraint applied on a .table
As mentioned by the error message, you cannot truncate a table that is referenced by enabled foreign keys. If you really want to use the truncate DDL command, disable the foreign key constraint first, run the truncate command, and enable it back.
Reference: Difference between TRUNCATE, DELETE and DROP commands
Related
I want to alter a table in my Crate DB to change the primary key constraint to add a column to the existing one. If I need to drop the constraint and create a new one what would be the SQL syntax for the same. I have been trying the conventional SQL syntax and it does not seem to work:
alter table my_data_table drop primary key;
the above command gives an error:
SQLActionException[SQLParseException: line 1:34: no viable alternative at input 'alter table my_data_table drop']
I checked the Alter table SQL reference and can only find ways to add columns but nothing about altering the constraints.So if you are aware of how to do this, please let me know. cheers!
there's no way to alter the primary key once a table has been created. You need to create a new table that has the schema you'd like to have and then either move the data over with COPY TO and COPY FROM or with insert into to_table (i) (select ... from t). With CrateDB > 2.0 it's also possible to rename tables, so you can still use the original table name.
First use the following code snippets for finding the constraints
SELECT Col.Column_Name from
INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab,
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col WHERE
Col.Constraint_Name = Tab.Constraint_Name
AND Col.Table_Name = Tab.Table_Name
AND Constraint_Type = 'PRIMARY KEY'
AND Col.Table_Name = '<your table name>'
Then use this to drop the constraint
ALTER TABLE Customer DROP CONSTRAINT Constraint_Name;
P.S: considering you are using SQL SERVER
Parent table A with some records.
Child table B with 0 records.
I have a cursor to do truncation on these tables in reverse tree order (i.e. truncate child first, then parent)
But I'm still getting this error when I truncate the parent table 'ORA-02266: unique/primary keys in table referenced by enabled foreign keys' error, despite the fact that the child table has no records at all.
However, when I do 'Delete from ' in the same order, all constraint related errors were avoided. And 'Delete from' takes really long time to run.
I don't want to disable or drop any constraints.
However, when I do 'Delete from ' in the same order, all constraint related errors were avoided.
That's the only way if you have constraints enabled. You cannot truncate. If you still want to truncate the table, then you could find the constraint name from user_constraints, and then DISABLE them:
ALTER TABLE table_name DISABLE CONSTRAINT constraint_name;
Then you could TRUNCATE the table, and re-enable the constraint:
ALTER TABLE table_name ENABLE CONSTRAINT constraint_name;
If your table has ON DELETE CASCADE option, then from Oracle 12.1 onward, you could use:
TRUNCATE TABLE table_name CASCADE;
Note, both the DELETE CASCADE and the TRUNCATE CASCADE will fail if any of the relationships in the hierarchy are not defined with the ON DELETE CASCADE clause.
There are three ways to delete from parent/child tables:
CREATE TABLE par (i NUMBER CONSTRAINT par_pk PRIMARY KEY);
CREATE TABLE chi (i NUMBER CONSTRAINT chi_fk REFERENCES par(i) ON DELETE CASCADE);
INSERT INTO par VALUES(1);
INSERT INTO chi VALUES(1);
1) If you have Oracle 12 or later, and you have foreign keys with ON DELETE CASCADE, you can use TRUNCATE CASCADE, which I expect to be the fastest option:
TRUNCATE TABLE par CASCADE;
Table PAR truncated.
SELECT count(*) FROM par;
0
SELECT count(*) FROM chi;
0
2) If your foreign keys are defined with ON DELETE CASCADE, you can use DELETE, which I expect to be the slowest option:
DELETE FROM par;
1 row deleted.
SELECT count(*) FROM par;
0
SELECT count(*) FROM chi;
0
3) Otherwise, you can disable the foreign keys, truncate the tables and reenable the foreign keys. This is fast, but is a little bit more risky than the other options (please check that the constraints are all valid afterwards):
ALTER TABLE chi DISABLE CONSTRAINT chi_fk;
TRUNCATE TABLE chi;
TRUNCATE TABLE par;
ALTER TABLE chi ENABLE CONSTRAINT chi_fk;
AFAIK, it is not possible to alter a foreign key from normal to ON DELETE CASCADE. I guess you have to drop and recreate them:
ALTER TABLE chi DROP CONSTRAINT chi_fk;
ALTER TABLE chi ADD CONSTRAINT chi_fk REFERENCES par(i) ON DELETE CASCADE;
Is it possible to delete check constraint(no constraint name declared) that is created within CREATE TABLE command?
Run the below query to find the list of check constraints in your table, including what they are checking for:
select constraint_name, search_condition
from user_constraints
where table_name = 'Your table name'
and constraint_type = 'C' -- To filter Check constraints alone
Copy the name of the relevant constraint and paste it in the Alter table drop constraint command.
Alter Table Your_table_name
Drop Constraint constraint_name; -- Replace constraint_name from above query result
Whenever I try to drop a table or create a table it is showing these errors:
DROP TABLE SUBURB;
DROP TABLE STOCKITEM;
DROP TABLE MANUFACTURER;
DROP TABLE WAREHOUSE;
DROP TABLE CITY;
DROP TABLE STATE;
Error at line 1: ORA-02449: unique/primary keys in table referenced
by foreign keys
CREATE TABLE STATE (
statecode varchar(3)
,statename varchar(30)
,population number(8)
,primary key(statecode)
);
Error at line 1: ORA-00955: name is already used by an existing object
Can anybody explain why this happens?
If you're really sure you want to drop the table even though it's referenced in foreign keys you can force it like this:
drop table state cascade constraints;
This syntax is defined in the Oracle SQL Reference.
Note that this drops any foreign key relationships. So you will need to recreate them after you have rebuilt the table (and its primary key). Normally this is okay because the most common use case is trashing and re-creating schemas in Development or CI environments.
We can use cascade constraints to make our build scripts easier to maintain. There are two alternatives:
Explicitly drop the foreign key constraints before dropping the
tables, either with a script or with dynamic SQL.
Order the DROP
TABLE statements so that dependent tables are zapped first, along
with their pesky foreign keys. Easy enough for a handful of tables,
more painful with a large schema.
You can use below query to fetch the references of table which should be dropped before dropping the table.
select table_name, constraint_name, status, owner
from dba_constraints
where 1=1
--and r_owner = :p_owner --if you know schema
and constraint_type = 'R'
and r_constraint_name in
(
select constraint_name from dba_constraints
where constraint_type in ('P','U')
and lower(table_name) = lower(:p_table_name)
--and r_owner = :p_owner
)
order by table_name, constraint_name
if you create the primary key and also create the foreign key than you cannot drop the table
you drop the table in this way for example if you have the table of students or teachers you want to drop this table you should write
DROP TABLE students CASCADE CONSTRAINTS;
and also you drop the table of teachers
DROP TABLE teachers CASCADE CONSTRAINTS;
SUBURB
Table is a parent table for any other table First you drop the child table then you can drop the SUBURB table....
And a table named as STATE is already present in your database...so you cant create the table having the same name....once if you drop the STATE table you can create another....
here's the solution that works for me fine in Oracle sample database :
DROP TABLE ['Your_Table_Name'] STATE CASCADE CONSTRAINTS;
I'm pretty new to SQL, so it sould be rather easy to answer my questions.
Here is what I want to do:
Deactivate constraints:
Deactivate constraints in the database:
begin
for cur in (select fk.owner, fk.constraint_name , fk.table_name
from all_constraints fk, all_constraints pk
where fk.CONSTRAINT_TYPE = 'R' and
pk.owner = 'USER1' and
fk.R_CONSTRAINT_NAME = pk.CONSTRAINT_NAME ) loop
execute immediate 'ALTER TABLE '||cur.owner||'.'||cur.table_name||' MODIFY CONSTRAINT '||cur.constraint_name||' DISABLE';
end loop;
end;
Delete from tables:
delete from USER_TEST.Table1;
delete from USER_TEST.Table2;
delete from USER_TEST.Table3;
Reactivate Constraints:
begin
for cur in (select fk.owner, fk.constraint_name , fk.table_name
from all_constraints fk, all_constraints pk
where fk.CONSTRAINT_TYPE = 'R' and
pk.owner = 'USER1' and
fk.R_CONSTRAINT_NAME = pk.CONSTRAINT_NAME ) loop
execute immediate 'ALTER TABLE '||cur.owner||'.'||cur.table_name||' MODIFY CONSTRAINT '||cur.constraint_name||' ENABLE NOVALIDATE';
end loop;
end;
Does anyone know how to combine these steps into one .sql script so I can run this on Oracle SQLDeveloper? Or maybe a more elegant way to perform the deletion from the tables?
I'd be very thankful
If it is just about deleting from tables which have foreign keys to each other, you can always delete in constraint order ("children first"). Then you won't have to mess with your constraints at all. Don't forget to commit at the end.
If it is about speed, then you may want to disable constraints and empty the tables via TRUNCATE rather then DELETE. You should however, not delete ALL constraints of the schema, but just the foreign keys of the affected tables which point to another affected table. This will prevent you from shooting into your foot. You can to this without looping, just disable the constraints explicitly. E
So the entire script should look like this
Alter Table User_test.Table1 Modify Constraint FK... Disable;
Alter Table User_test.Table2 Modify Constraint FK... Disable;
...
Trunacte Table user_test.Table1;
Trunacte Table user_test.Table2;
...
Alter Table User_test.Table1 Modify Constraint FK... Enable;
Alter Table User_test.Table2 Modify Constraint FK... Enable;
...