Drop foreign key without knowing the name of the constraint? - sql-server

I have created one table using the below command:
create table Table1(
Id int Not Null
Foreign key
references Table2(Id)
on delete cascade
on update cascade,
UserName nvarchar(150),
TimeInSeconds int Not Null
primary key(Id,TimeInSeconds)
);
But now I want to drop the foreign key.
As I haven't given a constraint name, I can't use:
Alter table <tablename>
drop foreign key <foreign key name>
Is there any way?

You can find the name of the constraint in INFORMATION_SCHEMA.TABLE_CONSTRAINTS
select CONSTRAINT_NAME
from INFORMATION_SCHEMA.TABLE_CONSTRAINTS
where TABLE_NAME = 'Table1'

Similar to Ed's Answer but you can use this to select the key name based on the table and column name.
That way you can run it in a script or maybe as a subquery to drop the constraint.
SELECT CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME = 'post'
AND COLUMN_NAME = 'userID'

Expanding on the answers since I ran into some gotchas. Also, I had 2 foreign keys declared, so I added an optional key to keep, if it's null it'll just be ignored:
declare #name varchar(255),
#table varchar(255) = 'mytable',
#column varchar(255) = 'mykeycolumn',
#validkey varchar(255) = 'mykeyIwanttokeep'
SELECT #name = CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME = #table
AND COLUMN_NAME = #column
AND (CONSTRAINT_NAME != #validkey or #validkey is null)
declare #sql varchar(1023) = 'alter table ' + #table + ' drop ' + #name
exec (#sql)

A SQL Server option:
DECLARE #foreignkey varchar(100)
DECLARE #tablename varchar(100)
DECLARE #command nvarchar(1000)
DECLARE db_cursor CURSOR FOR
SELECT fk.name, t.name
FROM sys.foreign_keys fk
JOIN sys.tables t ON t.object_id = fk.parent_object_id
WHERE t.name IN (
'table_1_name_here',
'table_2_name_here'
)
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #foreignkey, #tablename
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #command = 'ALTER TABLE ' + #tablename + ' DROP CONSTRAINT ' + #foreignkey
EXECUTE(#command)
FETCH NEXT FROM db_cursor INTO #foreignkey, #tablename
END
CLOSE db_cursor
DEALLOCATE db_cursor
The SQL selects all the constraints for the tables you care about into a cursor and drops them one by one. All you need to know are the names of the tables you want them dropped from.

To drop a foreign key use the following commands :
SHOW CREATE TABLE table_name;
ALTER TABLE table_name DROP FOREIGN KEY table_name_ibfk_3;
("table_name_ibfk_3" is constraint foreign key name assigned for unnamed constraints). It varies.
ALTER TABLE table_name DROP column_name.

If you just look at the table in enterprise manager / management studio you will be able to see the list of keys and delete it from there.

Never mind, below is Postgres syntax. It would be better if the question had sql server in the title as I didn't notice the tag
You could also drop and re-add the primary key on the parent table using cascade. This will remove any foreign keys that reference that table without you needing to know the foreign key names.
ALTER TABLE parent_table
DROP CONSTRAINT 'pk_id' CASCADE
-- add back pk
ALTER TABLE parent_table
ADD CONSTRAINT 'pk_id' PRIMARY KEY (id)
WARNING: you'd want to check all the dependencies first and if there are other tables, you'd need to add back their foreign keys. That does allow you to name the foreign keys properly when you add them back. This approach also may not be viable in a high transaction system due to the blocking transaction.

you can put:
> show create table tablename;
you will see how was created the table...columns, types...etc. and you could see your constraint name.

Related

Executing script for add primary keys to all tables returns error

I want to add Primary Key IDD to every 'Temp...' table in the schema. I'm trying to do it the following way:
DECLARE #addId VARCHAR(MAX) = '';
SELECT #addId = #addId + 'ALTER TABLE ['+ TABLE_NAME +'] ADD IDD int IDENTITY(1,1);ALTER TABLE ['+TABLE_NAME +'] ADD PRIMARY KEY (IDD);' FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'Temp%'
EXEC (#addId );
I'm returned with such error:
Multiple identity columns specified for table 'TempTable'. Only one identity column per table is allowed.
What is my wrongdoing?
EDIT: There is no Primary Key already defined in the tables.
try this
SELECT #addId = #addId +
ALTER TABLE ['+ TABLE_NAME +'] ADD IDD int PRIMARY KEY IDENTITY(1,1);
FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'Temp%'
Use this query to get all table which doesn't have primary key:
select * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME NOT IN(SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE='PRIMARY KEY')
And modify your dynamic query accordingly.

T-SQL Drop Constraint on Dynamically Selected Table

I have a situation in which I know a constraint name but do not know the name of a table. I would like to write a script that finds and drops the constraint based on its name, regardless of the table on which it resides. My trouble is that this appears to work only on alter table statements, which assume you know the table name. I can find a constraint using this:
SELECT *
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_NAME='constraint_name'
and would like to use the table info provided there to alter whatever table is in my results and drop the constraint.
Pseudo code of what I want:
alter table (select top 1* TABLE_NAME from
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_NAME='constraint_name') drop constraint 'constraint_name'
declare #constraint varchar(255)
declare #tbalename varchar(255)
declare #tbalename=select table_name from INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_NAME=#constraint
declare #sql nvarchar(max)
set #sql='ALTER TABLE '+#tbalename +'DROP CONSTRAINT '+ #constraint ;
exec(#SQL)

SQL Server - Foreign key creation to multiple tables

I have a requirement where I need to create a foreign key for more than 200 tables. Ex, there is emp table which has ID has primary key, now the 200 tables have emp_id, which I need to reference to emp.id.
I know I can write 200 alter statements to create the foreign key. Is there an easier way to create with one simple script?
Please advise. Thanks for your help.
Here is a trick to do it
DECLARE #sql NVARCHAR(max)=''
SELECT #sql += '
ALTER TABLE ' + Object_name(object_id)
+ '
ADD CONSTRAINT FK_'
+ Object_name(object_id)
+ '_EMP_emp_id FOREIGN KEY (emp_id) REFERENCES EMP(id);'
FROM sys.COLUMNS
WHERE NAME = 'emp_id'
--Print #sql
EXEC Sp_executesql
#sql
Note :
Print #SQL variable and check the generated SQL is good
Above code consider's all the 200 table has the same name 'emp_id' to which foreign key is created
This may fail when the 'emp_id' column has bad data (ie) a 'emp_id' which is not present in EMP table
You could probably generate the alter table statements dynamically using information_schema.columns. Something like this should get you started:
SELECT 'ALTER TABLE '+ TABLE_NAME +
' ADD CONSTRAINT FK_'+ TABLE_NAME +'_Emp FOREIGN KEY ('+ COLUMN_NAME +')'+
' REFERENCES emp (Id)'+
' ON DELETE CASCADE'+
' ON UPDATE CASCADE;'+
' GO '
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'emp_id'

Truncate Table With Foreign Key

I have one database having above 1000+ tables. I am creating fresh Blank setup. For that i have to truncate all the tables but some of the tables i do not wish to truncate so i created on table and stored the names in the table.
----------- Create hardcode table ----------------------
Create table TblHardCodeTableNotToTruncate(TableName varchar(100))
go
insert into TblHardCodeTableNotToTruncate
select 'TblHardCodeTableNotToTruncate'
go
---- insert the table names which dont wish to truncate ------------
Insert into TblHardCodeTableNotToTruncate
select 'TblAccount'
go
Insert into TblHardCodeTableNotToTruncate
select 'TblCity'
go
etc, Following is the query i used to truncate all the tables except these inserted tables
------------------------- Truncate all the tables except the tables specified in the Hardcode table -------------------------
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
GO
EXEC sp_MSForEachTable 'ALTER TABLE ? DISABLE TRIGGER ALL'
GO
DECLARE #TBLTEMP TABLE(TABLENAME VARCHAR(100))
insert into #TBLTEMP
select name from sysobjects where xtype = 'U'
delete from #TBLTEMP where tablename in (
select tablename from TblHardCodeTableNotToTruncate)
DECLARE #SQLQUERY VARCHAR(MAX) =''
DECLARE #INTCNT INT = 1
DECLARE #TABLENAME VARCHAR(100) =''
WHILE (SELECT COUNT(*) FROM #TBLTEMP) > 0
BEGIN
select top 1 #TABLENAME = TABLENAME from #TBLTEMP
SET #SQLQUERY = 'Truncate table ' + #TABLENAME
EXEC(#SQLQUERY)
PRINT #SQLQUERY
DELETE FROM #TBLTEMP WHERE TABLENAME = #TABLENAME
END
go
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
GO
EXEC sp_MSForEachTable 'ALTER TABLE ? ENABLE TRIGGER ALL'
go
But i get the error foreign key reference error. I know i need to drop constraint before doing it. But is there any way to do it as i cannot drop then truncate and again add each time with so many tables. Is there any unique script can we write in below which will drop constraint if exists,truncate table and add the dropped constraint again to the table again.
I'm afraid that there is no way to do that without dropping constraints,
you can write a code that extracts the constraints for the tables and drop them it's simple.
Create a temporary table and use this code to get the tables constraint and notice that the sysconstraints.status must be 1 or 3 to get foreign and primary keys:
Select SysObjects.[Name] As "Constraint Name",
Tabls.[Name] as "Table Name",
Cols.[Name] As "Column Name"
From SysObjects Inner Join
(Select [Name],[ID] From SysObjects) As Tabls
On Tabls.[ID] = Sysobjects.[Parent_Obj]
Inner Join sysconstraints On sysconstraints.Constid = Sysobjects.[ID]
Inner Join SysColumns Cols On Cols.[ColID] = sysconstraints.[ColID]
And Cols.[ID] = Tabls.[ID]
where sysconstraints.status in (1, 3)
order by [Tabls].[Name]
you gonna have to recreate these constraints again after truncate, that's simple too, but I'm not gonna do all your job :)
Even if all tabled are empty and you disable all constraints the truncate ill fail due to the mere FK existence. You really must drop it.
You can create a script to automate it (truncate all tables dropping and recreating FKs)
I found one here (use with discretion)
http://www.sqlservercentral.com/scripts/Development/62892/
Also if you just want to create a "blanket" DB you can export the script to create all objects and just populate that few (domain?) tables do you need.

How to remove foreign key constraint in sql server?

I want to remove foreign key from another table so i can insert values of my choice.
I am new in databases so please tell me correct sql query to drop or remove foreign key value.
Try following
ALTER TABLE <TABLE_NAME> DROP CONSTRAINT <FOREIGN_KEY_NAME>
Refer : http://www.w3schools.com/sql/sql_foreignkey.asp
Its wrong to do that in refer to referential integrity, because once its broken its not easy to turn it on again without having to go through the records and delete the ones which breaks the constraints.
Anyway the Syntax is as follows:
ALTER TABLE Tablename DROP CONSTRAINT ContName;
See MSDN:
Delete Primary Keys
Delete Foreign Key Relationships
ALTER TABLE [TableName] DROP CONSTRAINT [CONSTRAINT_NAME]
But, be careful man, once you do that, you may never get a chance back, and you should read some basic database book see why we need foreign key
To remove all the constraints from the DB:
SELECT 'ALTER TABLE ' + Table_Name +' DROP CONSTRAINT ' + Constraint_Name
FROM Information_Schema.CONSTRAINT_TABLE_USAGE
You should consider (temporarily) disabling the constraint before you completely delete it.
If you look at the table creation TSQL you will see something like:
ALTER TABLE [dbo].[dbAccounting] CHECK CONSTRAINT [FK_some_FK_constraint]
You can run
ALTER TABLE [dbo].[dbAccounting] NOCHECK CONSTRAINT [FK_some_FK_constraint]
... then insert/update a bunch of values that violate the constraint, and then turn it back on by running the original CHECK statement.
(I have had to do this to cleanup poorly designed systems I've inherited in the past.)
Drop all the foreign keys of a table:
USE [Database_Name]
DECLARE #FOREIGN_KEY_NAME VARCHAR(100)
DECLARE FOREIGN_KEY_CURSOR CURSOR FOR
SELECT name FOREIGN_KEY_NAME FROM sys.foreign_keys WHERE parent_object_id = (SELECT object_id FROM sys.objects WHERE name = 'Table_Name' AND TYPE = 'U')
OPEN FOREIGN_KEY_CURSOR
----------------------------------------------------------
FETCH NEXT FROM FOREIGN_KEY_CURSOR INTO #FOREIGN_KEY_NAME
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #DROP_COMMAND NVARCHAR(150) = 'ALTER TABLE Table_Name DROP CONSTRAINT' + ' ' + #FOREIGN_KEY_NAME
EXECUTE Sp_executesql #DROP_COMMAND
FETCH NEXT FROM FOREIGN_KEY_CURSOR INTO #FOREIGN_KEY_NAME
END
-----------------------------------------------------------------------------------------------------------------
CLOSE FOREIGN_KEY_CURSOR
DEALLOCATE FOREIGN_KEY_CURSOR
Depending on the DB you are using there's a syntax or another.
If you're using Oracle you have to put what the other users told you:
ALTER TABLE table_name DROP CONSTRAINT fk_name;
But if you use MySQL then this will give you a syntax error, instead you can type:
ALTER TABLE table_name DROP INDEX fk_name;
firstly use
show create table table_name;
to see the descriptive structure of your table.
There you may see constraints respective to foreign keys you used in that table.
First delete the respective constraint with
alter table table_name drop constraint constraint_name;
and then delete the respective foreign keys or column you wanted...GoodLuck!!
ALTER TABLE table
DROP FOREIGN KEY fk_key
EDIT: didn't notice you were using sql-server, my bad
ALTER TABLE table
DROP CONSTRAINT fk_key
Use those queries to find all FKs:
Declare #SchemaName VarChar(200) = 'Schema Name'
Declare #TableName VarChar(200) = 'Table name'
-- Find FK in This table.
SELECT
'IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N''' +
'[' + OBJECT_SCHEMA_NAME(FK.parent_object_id) + '].[' + FK.name + ']'
+ ''') AND parent_object_id = OBJECT_ID(N''' +
'[' + OBJECT_SCHEMA_NAME(FK.parent_object_id) + '].['
+ OBJECT_NAME(FK.parent_object_id) + ']' + ''')) ' +
'ALTER TABLE ' + OBJECT_SCHEMA_NAME(FK.parent_object_id) +
'.[' + OBJECT_NAME(FK.parent_object_id) +
'] DROP CONSTRAINT ' + FK.name
, S.name , O.name, OBJECT_NAME(FK.parent_object_id)
FROM sys.foreign_keys AS FK
INNER JOIN Sys.objects As O
ON (O.object_id = FK.parent_object_id )
INNER JOIN SYS.schemas AS S
ON (O.schema_id = S.schema_id)
WHERE
O.name = #TableName
And S.name = #SchemaName
-- Find the FKs in the tables in which this table is used
SELECT
' IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N''' +
'[' + OBJECT_SCHEMA_NAME(FK.parent_object_id) + '].[' + FK.name + ']'
+ ''') AND parent_object_id = OBJECT_ID(N''' +
'[' + OBJECT_SCHEMA_NAME(FK.parent_object_id) + '].['
+ OBJECT_NAME(FK.parent_object_id) + ']' + ''')) ' +
' ALTER TABLE ' + OBJECT_SCHEMA_NAME(FK.parent_object_id) +
'.[' + OBJECT_NAME(FK.parent_object_id) +
'] DROP CONSTRAINT ' + FK.name
, S.name , O.name, OBJECT_NAME(FK.parent_object_id)
FROM sys.foreign_keys AS FK
INNER JOIN Sys.objects As O
ON (O.object_id = FK.referenced_object_id )
INNER JOIN SYS.schemas AS S
ON (O.schema_id = S.schema_id)
WHERE
O.name = #TableName
And S.name = #SchemaName
Alternatively, you can also delete a Foreign Key Constraint from the SQL Server Management Studio itself. You can try it if the commands do not work.
Expand your database view.
Right Click on Table which has foreign key constraint. Choose Design. A tab with the information about table columns will open.
Right click on the column which has the foreign key reference. Or you can right click on any column. Choose Relationships.
A list of relationships will appear (if you have one) in a pop up window.
From there you can delete the foreign key constraint.
I hope that helps
If you find yourself in a situation where the FK name of a table has been auto-generated and you aren't able to view what it exactly is (in the case of not having rights to a database for instance) you could try something like this:
DECLARE #table NVARCHAR(512), #sql NVARCHAR(MAX);
SELECT #table = N'dbo.Table';
SELECT #sql = 'ALTER TABLE ' + #table
+ ' DROP CONSTRAINT ' + NAME + ';'
FROM sys.foreign_keys
WHERE [type] = 'F'
AND [parent_object_id] = OBJECT_ID(#table);
EXEC sp_executeSQL #sql;
Build up a stored proc which drops the constraint of the specified table without specifying the actual FK name. It drops the constraint where the object [type] is equal to F (Foreign Key constraint).
Note: if there are multiple FK's in the table it will drop them all. So this solution works best if the table you are targeting has just one FK.
If you don't know foreign key constraint name then try this to find it.
sp_help 'TableName'
additionally for different schema
sp_help 'schemaName.TableName'
then
ALTER TABLE <TABLE_NAME> DROP CONSTRAINT <FOREIGN_KEY_NAME>
To be on the safer side, just name all your constraints and take note of them in the comment section.
ALTER TABLE[table_name]
DROP CONSTRAINT Constraint_name
alter table <referenced_table_name> drop primary key;
Foreign key constraint will be removed.

Resources