Dropping an existing constraint in Microsoft SQL Server - 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.

Related

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.

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.

"Invalid column name" error when calling insert after table created

I'm developing SQL script, using SSMS, which makes some changes in database:
USE MyDatabase;
BEGIN TRANSACTION;
-- some statements
PRINT(N'#1');
IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = N'dbo' AND TABLE_NAME = N'Table1' AND COLUMN_NAME = 'Table2_Id'))
BEGIN
ALTER TABLE [dbo].[Table1] DROP CONSTRAINT [FK_Table1_Table2_Table2_Id];
ALTER TABLE [dbo].[Table1] DROP COLUMN [Table2_Id];
DROP TABLE [dbo].[Table2];
PRINT(N'Table2 was dropped.');
END
PRINT(N'#2');
IF (NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = N'dbo' AND TABLE_NAME = N'Table2'))
BEGIN
CREATE TABLE [dbo].[Table2]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[Number] INT NOT NULL UNIQUE,
[Name] NVARCHAR(200) NOT NULL,
[RowVersion] TIMESTAMP NOT NULL
);
PRINT(N'Table2 was re-created.');
INSERT INTO [dbo].[Table2]([Number], [Name]) VALUES(-1, N'Default value');
PRINT(N'Default value was inserted in Table2.');
END
-- some statements
COMMIT TRANSACTION;
If Table1 has a column, named Table2_Id, then database has two tables (Table1 and Table2) and a foreign key relationship between them. In that case, I need to:
drop foreign key relationship FK_Table1_Table2_Table2_Id;
drop foreign key column Table1.Table2_Id;
drop Table2;
re-create Table2, using new table schema;
insert some default value in Table2.
When I'm trying to execute this script, I'm getting these errors:
Msg 207, Level 16, State 1, Line 262 Invalid column name 'Number'.
Msg 207, Level 16, State 1, Line 262 Invalid column name 'Name'.
Looks like SQL Server uses old schema for Table2 (which indeed hasn't these columns), but how is this possible, if the table has just created with new schema?
What am I doing wrong?
Server version is SQL Server 2012 (SP1) - 11.0.3128.0 (X64).
UPDATE.
I've added PRINT calls (see script above). There's nothing in message window, except error messages. So, the script isn't being executed... What's going on??
SQL Server tries to compile the whole batch. If the table already exists then it will compile according to the pre-existing definition. The statement referencing the new columns doesn't compile and so the batch never executes.
You need to group the statements using the new definition into a new batch. If you are running this in SSMS just insert a GO
USE MyDatabase;
BEGIN TRANSACTION;
-- some statements
PRINT(N'#1');
IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = N'dbo' AND TABLE_NAME = N'Table1' AND COLUMN_NAME = 'Table2_Id'))
BEGIN
ALTER TABLE [dbo].[Table1] DROP CONSTRAINT [FK_Table1_Table2_Table2_Id];
ALTER TABLE [dbo].[Table1] DROP COLUMN [Table2_Id];
DROP TABLE [dbo].[Table2];
PRINT(N'Table2 was dropped.');
END
GO
PRINT(N'#2');
IF (NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = N'dbo' AND TABLE_NAME = N'Table2'))
BEGIN
CREATE TABLE [dbo].[Table2]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[Number] INT NOT NULL UNIQUE,
[Name] NVARCHAR(200) NOT NULL,
[RowVersion] TIMESTAMP NOT NULL
);
PRINT(N'Table2 was re-created.');
INSERT INTO [dbo].[Table2]([Number], [Name]) VALUES(-1, N'Default value');
PRINT(N'Default value was inserted in Table2.');
END
COMMIT
Otherwise you could run the offending line in a child batch
EXEC(N'INSERT INTO [dbo].[Table2]([Number], [Name]) VALUES(-1, N''Default value'');')

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...

How do I drop a foreign key in 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.

Resources