How do I drop a foreign key in SQL Server? - sql-server

I have created a foreign key (in SQL Server) by:
alter table company add CountryID varchar(3);
alter table company add constraint Company_CountryID_FK foreign key(CountryID)
references Country;
I then run this query:
alter table company drop column CountryID;
and I get this error:
Msg 5074, Level 16, State 4, Line 2
The object 'Company_CountryID_FK' is dependent on column 'CountryID'.
Msg 4922, Level 16, State 9, Line 2
ALTER TABLE DROP COLUMN CountryID failed because one or more objects access this column
I have tried this, yet it does not seem to work:
alter table company drop foreign key Company_CountryID_FK;
alter table company drop column CountryID;
What do I need to do to drop the CountryID column?
Thanks.

Try
alter table company drop constraint Company_CountryID_FK
alter table company drop column CountryID

This will work:
ALTER TABLE [dbo].[company] DROP CONSTRAINT [Company_CountryID_FK]

I think this will helpful to you...
DECLARE #ConstraintName nvarchar(200)
SELECT
#ConstraintName = KCU.CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU
ON KCU.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG
AND KCU.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA
AND KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
WHERE
KCU.TABLE_NAME = 'TABLE_NAME' AND
KCU.COLUMN_NAME = 'TABLE_COLUMN_NAME'
IF #ConstraintName IS NOT NULL EXEC('alter table TABLE_NAME drop CONSTRAINT ' + #ConstraintName)
It will delete foreign Key Constraint based on specific table and column.

First check of existence of the constraint then drop it.
if exists (select 1 from sys.objects where name = 'Company_CountryID_FK' and type='F')
begin
alter table company drop constraint Company_CountryID_FK
end

alter table company drop constraint Company_CountryID_FK

I don't know MSSQL but would it not be:
alter table company drop **constraint** Company_CountryID_FK;

You can also Right Click on the table, choose modify, then go to the attribute, right click on it, and choose drop primary key.

Are you trying to drop the FK constraint or the column itself?
To drop the constraint:
alter table company drop constraint Company_CountryID_FK
You won't be able to drop the column until you drop the constraint.

Related

Dropping an existing constraint in Microsoft SQL Server

I have tried to drop an existing constraint. Here's what I have:
The name of the constraint is: Data.Leraar.IsGeheim.DefaultValue
and the name of the table is: Data.Leraa.
This is the command I'm currently using:
IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.Leraar'))
BEGIN
ALTER TABLE Data.Leraar DROP CONSTRAINT [Data.Leraar.IsGeheim.DefaultValue]
END
If I execute this command, it says Command(s) completed successfully.
But the constraint still exists.
How should I change this command?
So you mean like this:
IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.Leraar'))
BEGIN
ALTER TABLE DataData.Leraar DROP FOREIGN KEY IsGeheim.DefaultValue;
END
But then I will get an error
Sorry, but I am using microsoft SQL
if I just do an simple:
ALTER TABLE [Data].[Leraar] DROP CONSTRAINT [Data.Leraar.IsGeheim.DefaultValue]
GO
it works. But I first want to check if it exists
If I do it like this:
IF exists (
SELECT *
FROM sys.default_constraints
WHERE
parent_object_id = OBJECT_ID(N'Data.Leraar') and
name = 'Data.Leraar.IsGeheim.DefaultValue'
)
ALTER TABLE Data.Leraar Drop Constraint Data.Leraar.IsGeheim.DefaultValue
GO
I get error on this line
ALTER TABLE Data.Leraar Drop Constraint Data.Leraar.IsGeheim.DefaultValue
after Data. I get error:
Msg 102, Level 15, State 1, Line 15 Incorrect syntax near '.'.
This works:
IF NOT EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.Leraar'))
BEGIN
ALTER TABLE [Data].[Leraar] ADD CONSTRAINT [Data.Leraar.IsGeheim.DefaultValue] DEFAULT ((1)) FOR [IsGeheim]
END
But to drop if it exists doens work
I have it now like this:
IF EXISTS (
SELECT *
FROM sys.default_constraints
WHERE
parent_object_id = OBJECT_ID(N'Data.Leraar') and
name = 'Data.Leraar.IsGeheim.DefaultValue'
)
ALTER TABLE Data.Leraar Drop Constraint [Data.Leraar.IsGeheim.DefaultValue]
PRINT 'constraint [Data.Leraar.IsGeheim.DefaultValue] has been dropped'
GO
IF NOT EXISTS((SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.Leraar') AND name ='Data.Leraar.IsGeheim.DefaultValue'))
BEGIN
ALTER TABLE [Data].[Leraar] ADD CONSTRAINT [Data.Leraar.IsGeheim.DefaultValue] DEFAULT ((1)) FOR [IsGeheim]
PRINT 'Constraint has been created [Data.Leraar.IsGeheim.DefaultValue]'
END
But is this correct?
You can also query sys.default_constraints system view as follows including the DROP Constraint clause of ALTER TABLE command
Please replace the table name and constraint name according to your case
IF exists (
SELECT *
FROM sys.default_constraints
WHERE
parent_object_id = OBJECT_ID(N'Table_1') and
name = 'DF_Table_1_col1'
)
ALTER TABLE Table_1 Drop Constraint DF_Table_1_col1
GO
I update the above command as follows since as I understand there is a misunderstanding
I assume now the schema for the table Leraar is Data
So please instead of dbo use Data as schema name
IF exists (
SELECT *
FROM sys.default_constraints
WHERE
parent_object_id = OBJECT_ID(N'Data.Leraar') and
name = 'Data.Leraar.IsGeheim.DefaultValue'
)
ALTER TABLE Data.Leraar Drop Constraint [Data.Leraar.IsGeheim.DefaultValue]
GO
You can simply use
IF (OBJECT_ID('Con_First') IS NOT NULL)
BEGIN
ALTER TABLE Customer DROP CONSTRAINT Con_First;
END
Here Con_First is the name of constraint you want to delete.

How to DROP table in correct order in SQL SERVER 2014?

I have following 5 tables and 1 table is connected as Foreign key in 2 tables. My dilemma is that I cannot figure out which table to drop first. below is the drop table code I am trying and I have created tables in following order
Updated Drop Table Code:
IF EXISTS (SELECT*FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='[Student Major]')
BEGIN
DROP TABLE [Student Major]
END
GO
IF EXISTS (SELECT*FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='Major')
BEGIN
DROP TABLE Major
END
GO
IF EXISTS (SELECT*FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='Citizenship')
BEGIN
DROP TABLE Citizenship
END
GO
IF EXISTS (SELECT*FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='Country')
BEGIN
DROP TABLE Country
END
IF EXISTS (SELECT*FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='Student')
BEGIN
DROP TABLE Student
END
GO
CREATE TABLE Student(
[Student ID] INT IDENTITY PRIMARY KEY
,[First Name] varchar (50) NOT NULL
,[Last Name] varchar (30) NOT NULL
)
GO
CREATE TABLE Country(
[Country ID] int identity PRIMARY KEY NOT NULL
,[Country of Birth] varchar (10)
,[Student ID] int FOREIGN KEY REFERENCES Student([Student ID]) NOT NULL
)
GO
CREATE TABLE Citizenship(
[Citizenship ID] int identity PRIMARY KEY
,[Country of Citizenship1] varchar (10)
,[Country of Citizenship2] varchar (10)
,[Student ID] int FOREIGN KEY REFERENCES Student([Student ID]) NOT NULL
,[Country ID] int FOREIGN KEY REFERENCES Country([Country ID]) NOT NULL
)
GO
CREATE TABLE Major(
[Major ID] int identity PRIMARY KEY
,[Major Name] varchar(30) NOT NULL
)
GO
CREATE TABLE [Student Major](
[Student MajorID] int identity
,[Student ID] int FOREIGN KEY REFERENCES Student([Student ID])
,[Major ID] int FOREIGN KEY REFERENCES Major([Major ID])
,[Graduated Major] varchar (30) NOT NULL
)
GO
I Would like to drop table in correct order
Errors:
Could not drop object 'Student' because it is referenced by a FOREIGN KEY constraint.
Also,Please provide explanation of dropping the table. I am new to SQL.
Thanks in advance!
Here is the way that I usually do it:
SELECT 'ALTER TABLE [' + O.[name] + '] DROP ' + F.[name]
FROM sys.objects O
INNER JOIN sys.foreign_keys F ON (F.parent_object_id = O.object_id)
WHERE O.[type] = 'U'
SELECT 'DROP TABLE [' + [name] + ']'
FROM sys.objects
WHERE [type] = 'U'
ORDER BY create_date DESC
This will generate a record set such as
ALTER TABLE Foo DROP FK_BLAH
ALTER TABLE Bar DROP FK_BAH
...
DROP TABLE Foo
DROP TABLE Bar
Which, you can then just copy and paste into a query window, and run from there.
(At the time that I'm writing this answer, I don't have access to an instance of SQL server, but I use code like the above all the time.)
DROP TABLE Student_Major; GO
SELECT 1 FROM Citizenship; GO
DROP TABLE Citizenship; GO
SELECT 1 FROM Major; GO
DROP TABLE Major; GO
SELECT 1 FROM Country; GO
DROP TABLE Country; GO
SELECT 1 FROM Student; GO
DROP TABLE Student; GO
It's just like you said, it has to be in the order so that any table that is referenced by a FK is not dropped, as long as the FK is there.
EDIT: GO forces the end of the batch
EDIT: I notice you have the GO in there already. You could use Information_schema to find the constraints associated with the table and drop them first, but I feel like you shouldn't need to do that. What if you injected a dummy query imbetween each DROP statement. It's hacky but if you don't feel like having to understand all the information_schema stuff it might be easier if it works.
You could first remove all FK constraints by:
ALTER TABLE ... DROP CONSTRAINT ...;
Then drop tables in any order.
If you are using SQL Server 2016 and above you could use DIE(drop if exists) and multiple tables at-once (still order matters):
DROP TABLE IF EXISTS [Student Major], Major, Citizenship, Country,Student;
DBFiddle Demo
If you are in doubt, and don't want to remove your constraints for some reason, you can always drop your tables in the exact opposite order in which you created them.
Since the first table doesn't reference any other, but maybe is referenced by other tables created after it, you should delete it last.
For the remaining tables, apply same logic. The first of the remaining tables is to be deleted last among them, and so on.

ALTER TABLE constraint problem

I'm trying to run the following SQL statement:
IF OBJECT_ID('MyTable') IS NOT NULL
DROP TABLE MyTable
SELECT
a.UserId
INTO
MyTable
FROM
UsersTable a
WHERE
a.UserId='12359670-1DC9-4A0A-8AE5-29B664C1A57E'
ALTER TABLE MyTable ALTER COLUMN UserId UNIQUEIDENTIFIER NOT NULL
ALTER TABLE MyTable ADD PRIMARY KEY(UserId)
However, I get the following error:
Cannot define PRIMARY KEY constraint on nullable column in table 'MyTable'.
Any ideas?
This assumes SQL Server based on UNIQUEIDENTIFIER
Put a GO between (or relevant batch separator if not SQL Server)
....
ALTER TABLE MyTable ALTER COLUMN UserId UNIQUEIDENTIFIER NOT NULL
GO
ALTER TABLE MyTable ADD PRIMARY KEY(UserId)
At batch compile time, the column is nullable. So break up the batches.
SQL isn't a line by line procedural language
You'll have to do this in a stored procedure
ALTER TABLE MyTable ALTER COLUMN UserId UNIQUEIDENTIFIER NOT NULL
EXEC('ALTER TABLE MyTable ADD PRIMARY KEY(UserId)')
Found a solution.
I'm using the following statement:
EXEC sp_ExecuteSQL N'ALTER TABLE MyTable ALTER COLUMN UserId UNIQUEIDENTIFIER NOT NULL'
EXEC sp_ExecuteSQL N'ALTER TABLE MyTable ADD PRIMARY KEY(UserId)'
You don't need dynamic SQL. Just create the table and the key first.
CREATE TABLE MyTable (UserId UNIQUEIDENTIFIER NOT NULL PRIMARY KEY);
INSERT INTO MyTable (UserId)
SELECT UserId
FROM UsersTable
WHERE UserId='12359670-1DC9-4A0A-8AE5-29B664C1A57E';

How to delete a primary key which doesn't have a name?

I am using SQL Server. Is there a way to drop the primary key which doesn't have a name?
It does have a name. Even if you don't name it explicitly SQL Server will auto create a name prefixed PK and based on the table name and the object_id of the constraint.
You can use the following query to see what it is.
SELECT CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE='PRIMARY KEY' AND TABLE_SCHEMA='dbo' AND TABLE_NAME='T'
The constraint name is required in the grammar for the DROP CONSTRAINT operation
ALTER TABLE [ database_name . [ schema_name ] . | schema_name . ] table_name
{
....
DROP
{
[ CONSTRAINT ] constraint_name
[ WITH ( <drop_clustered_constraint_option> [ ,...n ] ) ]
| COLUMN column_name
} [ ,...n ]
Primary key always has a name. If you didn't specify it in 'create table' or 'alter table' statement, the key name is auto-generated.
In the query bellow replace X with the name of your table and run the script.
It will drop the primary key.
declare #TableName sysname = 'X'
declare #PrimaryKeyName sysname = (
select name
from sys.key_constraints
where type = 'PK' and parent_object_id = object_id(#TableName))
execute ('alter table ' + #TableName + ' drop constraint ' + #PrimaryKeyName)
It is always a good idea to specify explicit names for constraints, because if you run 'create/alter table' script on different databases, all of them will have different constraint name created.
Later, when you need to delete the constraints you need to run this workaround script, instead just running simple 'alter table drop constraint' statement.
CREATE TABLE #Tempbox (Id int primary key identity(1,1), Name varchar(200) unique)
creating a table with column Id, and name, notice it doesn't have constraint name.
Well, if you don't set contraint name for column, sql server provides their own default unique constraint name to constraint like primary key, unique and so on.
1. Let's insert some value in our #Tempbox table
1. insert into #tempbox values ('Abc')
2. insert into #tempbox values ('Abc')
unique key violation error shown by sql server along with constraint name.
**Msg 2627, Level 14, State 1, Line 5
Violation of UNIQUE KEY constraint **'UQ__#Tempbox__737584F6A146D511'**. Cannot insert duplicate key in object 'dbo.#Tempbox'. The duplicate key value is (dsaf).
The statement has been terminated.**
you got the constraint name now.. which is 'UQ__#Tempbox__737584F6A146D511'
now let's drop the column with constraint. Remember you can't drop a column if it is using a constraint so in order to drop that column you will have to drop first constraint and after column.
ALTER TABLE #Tempbox drop constraint UQ__#Tempbox__737584F6A146D511; -- constraint is dropped
now drop the column
alter table #tempbox drop column Name
Now use the same procedure for primary key column
INSERT INTO #Tempbox (Id, Name) VALUES (1,'Abc')
INSERT INTO #Tempbox (Id, Name) VALUES (1,'Abc')
Error :
Msg 2627, Level 14, State 1, Line 3
Violation of PRIMARY KEY constraint **'PK__#Tempbox__3214EC07B3D09900'**. Cannot insert duplicate key in object 'dbo.#Tempbox'. The duplicate key value is (1).
The statement has been terminated.
drop constraint and drop column.
Another way to find the constraint name..
USE Adventure
SELECT CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE='PRIMARY KEY' AND TABLE_SCHEMA='pERSON' AND TABLE_NAME='PERSON'

SQL Server: How do I add a constraint to an existing table but only if the constraint does not already exist?

I need to add a constraint to an existing SQL server table but only if it does not already exist.
I am creating the constraint using the following SQL.
ALTER TABLE [Foo] ADD CONSTRAINT [FK_Foo_Bar] FOREIGN KEY ([BarId]) REFERENCES [Bar] ([BarId]) ON UPDATE CASCADE ON DELETE CASCADE
I'm hoping I can add some SQL to the begining of the SQL to test for the existence of the constraint but I have no idea how.
Personally I would drop the existing constraint, and recreate it - in case the one that is already there is in some way different
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[MyFKName]') AND OBJECTPROPERTY(id, N'IsForeignKey') = 1)
ALTER TABLE dbo.MyTableName DROP CONSTRAINT MyFKName
GO
ALTER TABLE dbo.MyTableName ADD CONSTRAINT [MyFKName] ...
The current, more modern, code I am using is:
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[MyFKName]') AND parent_object_id = OBJECT_ID(N'[dbo].[MyTableName]'))
ALTER TABLE dbo.[MyTableName] DROP CONSTRAINT [MyFKName]
GO
ALTER TABLE dbo.[MyTableName] ADD CONSTRAINT [MyFKName] FOREIGN KEY ...
not sure if there is any advantage of checking sys.objects ... or sys.foreign_keys ... but at some point I decided on sys.foreign_keys
Starting with SQL2016 new "IF EXISTS" syntax was added which is a lot more readable:
-- For SQL2016 onwards:
ALTER TABLE dbo.[MyTableName] DROP CONSTRAINT IF EXISTS [MyFKName]
GO
ALTER TABLE dbo.[MyTableName] ADD CONSTRAINT [MyFKName] FOREIGN KEY ...
I'd recommend using the INFORMATION_SCHEMA.TABLE_CONSTRAINTS view. It's portable across different database engines:
SELECT COUNT(*)
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE TABLE_NAME='Foo'
AND CONSTRAINT_NAME='FK_Foo_Bar'
AND CONSTRAINT_TYPE='FOREIGN KEY'
Check if the constraint already exists before adding it -
IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS WHERE CONSTRAINT_NAME = 'FK_Foo_Bar')
BEGIN
ALTER TABLE dbo.MyTableName ADD CONSTRAINT [MyFKName] ...
END
Alter table tableName add constraint constraintname default 0 for columnname
You can provide constraintname as you want without single quote
Drop the default constraint and create your own. ALTER table TABLE_NAME drop constraint CONSTRAINT NAME
GO
ALTER TABLE [dbo].[TABLE_NAME] ADD CONSTRAINT [DF_TABLE_NAME_COLUMN_NAME] FOR [COLUMN_NAME]
Very simple:
IF OBJECT_ID('Schema.keyname') IS NULL
ALTER TABLE Schema.tablename ADD CONSTRAINT keyname...

Resources