Drop foreign-key constraint - sql

How to drop a foreign key if I have not named it during creation
create table abc(
id number(10),
foreign key (id) references tab(roll)
);
even
alter table abc drop foreign key mn_ibfk_1;
is not working for me. I am using Oracle 10g.

As you did not specify a constraint name, Oracle generated one for you (something like SYS_034849548).
You need to find the constraint name in order to be able to drop it:
select constraint_name
from user_constraints
where table_name = 'ABC'
and constraint_type = 'R'
will display the constraint name. Then you can drop the constraint using:
alter table abc drop constraint <constraint_name>;
(replace <constraint_name> with the name you retrieved using the SQL statement)
Note that the syntax is alter table ... drop constraint. There is no drop foreign key.

Try this
alter table mn drop constraint mn_ibfk_1;
to find out for sure the name of the constraint try this query
SELECT a.table_name child_table,
b.table_name parent_table,
a.constraint_name child_constraint,
b.constraint_name parent_constraint,
c.column_name child_column,
d.column_name parent_column
FROM user_constraints a,
user_constraints b,
user_cons_columns c,
user_cons_columns d
WHERE a.constraint_type = 'R'
AND b.constraint_type = 'P'
AND b.constraint_name = a.r_constraint_name
AND A.table_name = c.table_name
AND b.table_name = d.table_name
AND a.constraint_name = c.constraint_name
AND b.constraint_name = d.constraint_name
AND c.position = d.position
AND a.table_name = 'mn' ;

Related

How to name the constraint when add NOT NULL on ALTER TABLE

ALTER TABLE ACTOR MODIFY FIRST_NAME VARCHAR2(45) NOT NULL;
I know have to set FIST_NAME to NOT NULL, but I don not know how to name this constraint.
The name of this constraint should be "CK_Fanme"
You can use
ALTER TABLE actor MODIFY ( first_name CONSTRAINT not_null_first_name NOT NULL );
and query to see the result through use of user_constraints data dictionary view such as
SELECT constraint_name
FROM user_constraints
WHERE table_name = 'ACTOR'
Demo

How to remove check constraint?

I am having difficult to remove CHECK using Alter in sql. Can anyone help me please?
CREATE TABLE MyProject_COST (
ID int(4) NOT NULL UNIQUE,
detail varchar2(25) NOT NULL,
cost int(6) CONSTRAINT cost_project CHECK(cost>=500)
);
ALTER TABLE MyProject_COST ALTER COLUMN Cost int(6)
Oracle does have an alter table ... drop constraint syntax for this.
But since you created an anonymous constraint, so this is tricky - because you don't know the name of the constraint.
One option is to use dynamic SQL to retrieve the constraint name, and drop it with an execute immediate command:
declare
c_name varchar2(255 char);
begin
select c.constraint_name into c_name
from all_constraints c
join all_cons_columns cc
on cc.table_name = c.table_name
and cc.constraint_name = c.constraint_name
where
cc.table_name = 'MYPROJECT_COST'
and cc.column_name ='COST'
and c.constraint_type = 'C' ;
if c_name is not null then
execute immediate
'alter table myproject_cost drop constraint "' || c_name || '"';
end if;
end;
/
Demo on DB Fiddle:
create table myproject_cost (
id int not null unique,
detail varchar2(25) not null,
cost int check(cost >= 500)
);
insert into MyProject_COST(id, detail, cost) values(1, 'foo', 0);
-- ORA-02290: check constraint (FIDDLE_XUVVCZVSYWWROHKPBFUF.SYS_C0030623) violated
declare
c_name varchar2(255 char);
begin
select c.constraint_name into c_name
from all_constraints c
join all_cons_columns cc
on cc.table_name = c.table_name
and cc.constraint_name = c.constraint_name
where
cc.table_name = 'MYPROJECT_COST'
and cc.column_name ='COST'
and c.constraint_type = 'C' ;
if c_name is not null then
execute immediate
'alter table myproject_cost drop constraint "' || c_name || '"';
end if;
end;
/
-- 1 rows affected
insert into MyProject_COST(id, detail, cost) values(1, 'foo', 0);
-- 1 rows affected

SQL : Check if primary key is foreign key

I want to extract the name of primary key column of table if it is also foreign key from information schema
like two tables :
Student
std_id std_name
And
PHDstudent
std_id reaserchfield
That std_id in PHDstudent is primary key and foreign key at same time that refers to Student table.
Run this query
SELECT Tab.TABLE_NAME, 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 '
INTERSECT
SELECT Tab.TABLE_NAME, 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 = 'FOREIGN KEY '
SELECT s.std_id FROM Student s
INNER JOIN PHDstudent p
ON s.std_id = p.std_id
Have a read on INNER JOINS
I think you are asking about primary key column name, than you should go with below query which gives you the primary key column name.....
SELECT column_name
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE OBJECTPROPERTY(OBJECT_ID(constraint_name), 'IsPrimaryKey') = 1
AND table_name = 'PHDstudent'

SQL Server 2008 select constraints order by primary key

I have the following SQL statement to retrieve drop constraint statements.
SELECT DISTINCT 'ALTER TABLE '+TABLE_NAME+' DROP CONSTRAINT '+CONSTRAINT_NAME AS 'DropConstraintStatement'
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE
WHERE TABLE_NAME = 'USER';
The result of this query is:
ALTER TABLE UNITS DROP CONSTRAINT FK_USER_TASK_ID
ALTER TABLE UNITS DROP CONSTRAINT PK_USER
ALTER TABLE UNITS DROP CONSTRAINT UQ_USER_NAME_VERSION
I want to execute these statements within a Java application, hence I need these statements ordered such that the drop primary key constraint is at the last position like:
ALTER TABLE UNITS DROP CONSTRAINT FK_USER_TASK_ID
ALTER TABLE UNITS DROP CONSTRAINT UQ_USER_NAME_VERSION
ALTER TABLE UNITS DROP CONSTRAINT PK_USER
Is there any nice possibility to do this with native SQL?
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE does not hold the necessary information to distinguish between PK and other constraints. If you are sure your PK names start with PK
you could try adding ORDER BY like this:
ORDER BY CASE WHEN CONSTRAINT_NAME LIKE 'PK%' THEN 1 ELSE 0 END
However, I would suggest switching to SQL Server system views for more precise data. sys.key_constraints holds info about primary keys and unique constraints, and sys.foreign_keys about foreign keys.
WITH CTE AS
(
SELECT OBJECT_NAME(parent_object_id) AS TABLE_NAME
, name AS CONSTRAINT_NAME, Type
FROM sys.key_constraints
WHERE parent_object_id = object_id('YourTable')
UNION
SELECT OBJECT_NAME(parent_object_id) AS TABLE_NAME
, name AS CONSTRAINT_NAME, Type
FROM sys.foreign_keys
WHERE parent_object_id = object_id('YourTable')
)
SELECT 'ALTER TABLE '+TABLE_NAME+' DROP CONSTRAINT '+CONSTRAINT_NAME AS 'DropConstraintStatement'
FROM CTE
ORDER BY CASE WHEN Type = 'PK' THEN 1 ELSE 0 END

If Foreign Key Not Exist Then Add Foreign Key Constraint(Or Drop a Foreign Key Constraint If Exist) without using Name?

I am finding difficulties to creating a a query. Let say I have a Products and Brands table. I can add a foreign key using this command,
ALTER TABLE Products
ADD FOREIGN KEY (BrandID)
REFERENCES Brands(ID)
But I need to only run this command if Foreign Key does not exist.
A similar thing I need is that drop a Foreign Key Constraint If Exist without using name.
Try this:
IF NOT EXISTS (SELECT * FROM sys.objects o WHERE o.object_id = object_id(N'[dbo].[FK_Products_Brands]') AND OBJECTPROPERTY(o.object_id, N'IsForeignKey') = 1)
BEGIN
ALTER TABLE [dbo].[Products] WITH CHECK ADD CONSTRAINT [FK_Products_Brands] FOREIGN KEY([BrandID]) REFERENCES [dbo].[Brands] ([Id])
END
First of all, you should always name your FKs and all other constraints in order to save yourself trouble like this.
But, if you don't know the name of FK you can check it using multiple system views:
IF NOT EXISTS
(
SELECT * FROM sys.foreign_key_columns fk
INNER JOIN sys.columns pc ON pc.object_id = fk.parent_object_id AND pc.column_id = fk.parent_column_id
INNER JOIN sys.columns rc ON rc.object_id = fk.referenced_object_id AND rc.column_id = fk.referenced_column_id
WHERE fk.parent_object_id = object_id('Products') AND pc.name = 'BrandID'
AND fk.referenced_object_id = object_id('Brands') AND rc.NAME = 'ID'
)
ALTER TABLE Products
ADD CONSTRAINT Your_New_FK_NAME FOREIGN KEY (BrandID)
REFERENCES Brands(ID)
You can use this as well.
IF(OBJECT_ID('FK_Products_Brands', 'F') IS NULL)
ALTER TABLE [dbo].[Products] WITH CHECK ADD CONSTRAINT [FK_Products_Brands] FOREIGN KEY([BrandID]) REFERENCES [dbo].[Brands] ([Id])
To do this without knowing the constraint's name and without inner joins, you can do:
IF NOT EXISTS(SELECT NULL FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE WHERE [TABLE_NAME] = 'Products' AND [COLUMN_NAME] = 'BrandID')
BEGIN
ALTER TABLE Products
ADD FOREIGN KEY (BrandID)
REFERENCES Brands(ID)
END
If you wanted to, you could get the name of the contraint from this table, then do a drop/add.
This worked smoothly for me in Azure sql server.
IF NOT EXISTS (
SELECT NULL
FROM information_schema.TABLE_CONSTRAINTS
WHERE
CONSTRAINT_SCHEMA = 'dbo' AND
CONSTRAINT_NAME = 'FK_company_id' AND
CONSTRAINT_TYPE = 'FOREIGN KEY'
) ALTER TABLE dbo.table_main
ADD CONSTRAINT FK_company_id
FOREIGN KEY (company_id)
REFERENCES dbo.table_company(id);