Dropping FK Constraint On Something Other Than Name - oracle

I have a application database where there are lots of different copies of the schema on different servers (developers, stag, prod etc)
I have two tables that were related by a FK contraint like
Foo.fk = Bar.Id
I want to drop the Bar table. but I don't want to drop the Foo.fk column. I just want to remove the constraint from it.
The problem is that the script that originally created the constraint made it different in different environments. Is there a way to remove the constraint by some way other than drop by name?

No need to drop the constraint manually:
DROP TABLE bar CASCADE CONSTRAINTS;
will drop the bar table and any constraint referencing it.

Related

Is Oracle alter table drop constraint drop index syntactically valid?

I have Oracle 11.2.0.2.0 and a table with unique constraint created by following script:
create table foo (id varchar(26) not null, name varchar(50) not null);
alter table foo add constraint pk_foo primary key (id);
/**/
alter table foo add constraint un_foo unique (name);
I need to drop the unique constraint, which is easy:
alter table foo drop constraint un_foo;
The trouble is: when the database is backuped in SQL Developer and then restored, then the un_foo unique index is created by explicit command placed at /**/ line:
CREATE UNIQUE INDEX un_foo ON foo (name);
Such an explicitly-created index is not deleted by the alter command above. I realized following command works:
alter table foo drop constraint un_foo drop index;
For primary key, similar command alter table foo drop primary key drop index is in documentation or in Oracle Developer Community discussion. Also, this answer at AskTom uses this syntax too (for keep index). However I don't see any reasoning for such syntax in railroad diagram of alter table command.
Question: is the syntax alter table foo drop constraint un_foo drop index legal? If so, based on what documentation or flow in railroad diagram? If not, why the command doesn't fail?
Thanks!
According to #Chris Saxon's answer to my equivalent question posted to AskTom, the syntax is confirmed as working but not present in documentation.
The decision whether it is doc bug or unintended side effect is still unresolved.
I personally decided to rely on the syntax since, among other things, it is advised also in My Oracle Support.
If absolute safety (read: conforming to the documentation) is required, the only possibility is to use statement alter table foo drop unique (name) drop index;.
I summarized (not so substantial) circumstances around this issue in blogpost (in Czech).

How to drop Parent table without deleting or dropping constraints on child table in Oracle

I have two tables one is Parent and Child. Parent table have primary constraint on it and the Child table have a foreign key constraint on it. Now I want to drop the Parent table without deleting or dropping constraints which are there on child table.
I have tried disabling the constraints on both parent and child table and tried to drop the parent table. But still I was not able to drop the Parent table.
And If the delete the primary constraint on the parent delete, then it also drops the foreign key constraint on the child table.
Please if any one can help me out.
Thanks.
You can't drop a parent table if you have a child table with a foreign key constraint in place, unless you specify the CASCADE CONSTRAINTS clause:
DROP TABLE P CASCADE CONSTRAINTS;
This command drops the FK constraint too.
Deleting a table will necessarily drop all constraints related to this table. if a table is referenced by this table, you will have to drop those constraints first before to avoid rules violation.
*The oracle documentation says: *
http://docs.oracle.com/cd/B28359_01/server.111/b28310/tables010.htm#ADMIN01505
The following statement drops the t table:
DROP TABLE t;
If the table to be dropped contains any primary or unique keys referenced by foreign keys of other tables and you intend to drop the FOREIGN KEY constraints of the child tables, then include the CASCADE clause in the DROP TABLE statement, as shown below:
DROP TABLE t CASCADE CONSTRAINTS;
Weird... if you disabled correctly the constraints you should be able to delete parent table without any error.
:|

how to drop and add multi constraints by 1 sql statement for H2 database

I'm working on H2 database, and I meet this problem -
to drop one constraint is fine, I can use this statement
alter table customer drop constraint if exists fk_customer_order ;
for add one constraint is fine too, I can use this statement.
alter table customer add constraint fk_customer_order foreign key (order_id) references order (id) on delete cascade on update cascade;
but the problems is, in customer table I have more foreign key and I want delete them in one query statement.
Something like this
alter table customer drop constraint fk_customer_order
drop constraint fk_customer_information
drop constraint ....
but this seem can not be done in h2 database, anyone can tell me can or not add or drop multi constraint by 1 sql statment? Any answer are welcome and I appreciate much.
I think it can not be done. Why don't you use multiple statements?

How do I rename a table in Oracle so that all foreign keys, constraints, triggers and sequences are updated and any existing data is preserved?

I need to rename a table in Oracle but I want to be sure that any foreign keys, constraints, triggers and sequences that reference the table are updated to use the new name.
How can I be sure that I have not broken anything?
Note that I want to preserve any existing data that the table contains.
If you
ALTER TABLE old_table_name
RENAME TO new_table_name;
all the existing constraints (foreign key and other constraints) and triggers will reference the newly renamed object. Sequences have no relationship to tables so there will be no impact on the sequences (though if you mean that you are referencing the sequence in a trigger on the table, the trigger will continue to reference the same sequence after the rename). Any stored procedures that you have written that reference the old table name, however, will need to be updated to reference the new table name.
Now, while the constraints and triggers will continue to work correctly, they will retain their original names. If you have naming conventions for these objects that you want to maintain after the table name, you'd need to do more. For example, if you want a row-level before insert trigger on table FOO to be named TRG_BI_FOO and you rename the table to BAR, you'd need to alter the trigger explicitly to change its name
ALTER TRIGGER trg_bi_foo
RENAME TO trg_bi_bar;
Similarly, you'd need to rename your constraints and indexes
ALTER TABLE bar
RENAME CONSTRAINT pk_foo TO pk_bar;
It depends on what you mean by "any foreign keys, constraints, triggers and sequences that reference the table are updated to use the new name."
Any existing indexes, constraints, and triggers against the table being renamed will automatically reference the new name.
However, any naming conventions used for those objects won't automatically use the updated name. For example, if the primary key for TABLE_NAME is generally named TABLE_NAME_PK, renaming TABLE_NAME to NEW_TABLE_NAME won't automatically rename the primary key constraint to NEW_TABLE_NAME_PK.
What will need to be checked is code - packages, procedures, and functions - which referenced the old table name, as well as any triggers which referenced the old table name. Similarly, views against the old table name will break as well. The view ALL_DEPENDENCIES can help identify which of those objects need to be updated.
ALTER TABLE oldName RENAME TO newName
Will preserve the table's dependencies and data but there can always be a piece of PL/SQL that references the old name which is going to become invalid.

Create constraint in alter table without checking existing data

I'm trying to create a constraint on the OE.PRODUCT_INFORMATION table which is delivered with Oracle 11g R2.
The constraint should make the PRODUCT_NAME unique.
I've tried it with the following statement:
ALTER TABLE PRODUCT_INFORMATION
ADD CONSTRAINT PRINF_NAME_UNIQUE UNIQUE (PRODUCT_NAME);
The problem is, that in the OE.PRODUCT_INFORMATION there are already product names which currently exist more than twice.
Executing the code above throws the following error:
an alter table validating constraint failed because the table has
duplicate key values.
Is there a possibility that a new created constraint won't be used on existing table data?
I've already tried the DISABLED keyword. But when I enable the constraint then I receive the same error message.
You can certainly create a constraint which will validate any newly inserted or updated records, but which will not be validated against old existing data, using the NOVALIDATE keyword, e.g.:
ALTER TABLE PRODUCT_INFORMATION
ADD CONSTRAINT PRINF_NAME_UNIQUE UNIQUE (PRODUCT_NAME)
NOVALIDATE;
If there is no index on the column, this command will create a non-unique index on the column.
If you are looking to enforce some sort of uniqueness for all future entries whilst keeping your current duplicates you cannot use a UNIQUE constraint.
You could use a trigger on the table to check the value to be inserted against the current table values and if it already exists, prevent the insert.
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_triggers.htm
or you could just remove the duplicate values and then enfoce your UNIQUE constraint.
EDIT: After Jonearles and Jeffrey Kemp's comments, I'll add that you can actually enable a unique constraint on a table with duplicate values present using the NOVALIDATE clause but you'd not be able to have a unique index on that constrained column.
See Tom Kyte's explanation here.
However, I would still worry about how obvious the intent was to future people who have to support the database. From a support perspective, it'd be more obvious to either remove the duplicates or use the trigger to make your intent clear.
YMMV
You can use deferrable .
ALTER TABLE PRODUCT_INFORMATION
ADD CONSTRAINT PRINF_NAME_UNIQUE UNIQUE (PRODUCT_NAME)
deferrable initially deferred NOVALIDATE;

Resources