232

In Microsoft SQL Server, I know the query to check if a default constraint exists for a column and drop a default constraint is:

IF EXISTS(SELECT * FROM sysconstraints
  WHERE id=OBJECT_ID('SomeTable')
  AND COL_NAME(id,colid)='ColName'
  AND OBJECTPROPERTY(constid, 'IsDefaultCnst')=1)    
ALTER TABLE SomeTable DROP CONSTRAINT DF_SomeTable_ColName

But due to typo in previous versions of the database, the name of the constraint could be DF_SomeTable_ColName or DF_SmoeTable_ColName.

How can I delete the default constraint without any SQL errors? Default constraint names don't show up in INFORMATION_SCHEMA table, which makes things a bit trickier.

So, something like 'delete the default constraint in this table/column', or 'delete DF_SmoeTable_ColName', but don't give any errors if it can't find it.

OMG Ponies
  • 325,700
  • 82
  • 523
  • 502
Robo
  • 4,588
  • 7
  • 40
  • 48
  • 1
    I am not proficient with SQL Server, can you rename a constraint after you found out its name? "Alter table sometable rename constraint xxx to yyy" in Oracle. – Juergen Hartelt Sep 16 '09 at 01:29

16 Answers16

302

Expanding on Mitch Wheat's code, the following script will generate the command to drop the constraint and dynamically execute it.

declare @schema_name nvarchar(256)
declare @table_name nvarchar(256)
declare @col_name nvarchar(256)
declare @Command  nvarchar(1000)

set @schema_name = N'MySchema'
set @table_name = N'Department'
set @col_name = N'ModifiedDate'

select @Command = 'ALTER TABLE ' + @schema_name + '.[' + @table_name + '] DROP CONSTRAINT ' + d.name
 from sys.tables t
  join sys.default_constraints d on d.parent_object_id = t.object_id
  join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id
 where t.name = @table_name
  and t.schema_id = schema_id(@schema_name)
  and c.name = @col_name

--print @Command

execute (@Command)
Jacob van Lingen
  • 8,989
  • 7
  • 48
  • 78
Philip Kelley
  • 39,426
  • 11
  • 57
  • 92
  • 2
    Check http://stackoverflow.com/a/15786313/2049986 to see a version to drop all contraints for a table – Jacob van Lingen Mar 31 '14 at 10:55
  • 2
    I use ***sys.check_constraints*** , not ***sys.default_constraints*** – Kiquenet Jul 07 '16 at 07:46
  • ***Not valid*** if some columns that had ***multiple*** _default constraints or check constraints_ created, Only executed for ***last constraints*** in query. – Kiquenet Jul 07 '16 at 08:54
  • 6
    This query only addresses default constraints, of which there can only be one per column. Dealing with check constraints is a different problem. – Philip Kelley Jul 07 '16 at 14:12
  • 1
    I've updated this answer to add support for non-default schema names. Hope you don't mind, I can revert and post a separate answer if you like. – Jakub Januszkiewicz Oct 20 '16 at 06:17
  • @Jakub, Good change--I'd done less work with non-DBO schemas back then. Seven year old question, seven year old answer, your revision would be an 11th and likely ignored answer, so I'd say leave it here. – Philip Kelley Oct 20 '16 at 15:04
  • I'm going to tweak it again, remove the extra join and make it a system function call/check--tighter code, easier to work with. – Philip Kelley Oct 20 '16 at 15:04
  • I have been looking for this for a while. That is the only answer that resolved my problem. Thanks! – bellotto Sep 16 '22 at 17:53
239

Rob Farley's blog post might be of help:

Something like:

 declare @table_name nvarchar(256)
 declare @col_name nvarchar(256)
 set @table_name = N'Department'
 set @col_name = N'ModifiedDate'

 select t.name, c.name, d.name, d.definition
 from 
     sys.tables t
     join sys.default_constraints d on d.parent_object_id = t.object_id
     join sys.columns c on c.object_id = t.object_id
                           and c.column_id = d.parent_column_id
 where 
     t.name = @table_name
     and c.name = @col_name
Tabatha
  • 103
  • 2
  • 7
Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
126

I found that this works and uses no joins:

DECLARE @ObjectName NVARCHAR(100)
SELECT @ObjectName = OBJECT_NAME([default_object_id]) FROM SYS.COLUMNS
WHERE [object_id] = OBJECT_ID('[tableSchema].[tableName]') AND [name] = 'columnName';
EXEC('ALTER TABLE [tableSchema].[tableName] DROP CONSTRAINT ' + @ObjectName)

Just make sure that columnName does not have brackets around it because the query is looking for an exact match and will return nothing if it is [columnName].

ScubaSteve
  • 7,724
  • 8
  • 52
  • 65
  • 1
    And this answer works with schemas other than the default [dbo], unlike any of the other answers. – Contango Mar 12 '14 at 13:49
  • I haven't tested it, but you can try and add a WHILE (@ObjectName IS NOT NULL) around it, put TOP 1 before SELECT (at)ObjectName = OBJECT_Name([default... and only run the EXEC('ALTER TA... if (at)ObjectName IS NOT NULL. – ScubaSteve May 09 '14 at 13:26
  • 7
    To make this script idempotent add `IF @ObjectName IS NOT NULL` before EXEC command – Seven Jun 17 '15 at 12:22
  • 3
    Not working for me using ***CHECK constraints***. `[default_object_id])` is ***0***. I get ***NULL*** value. – Kiquenet Jul 07 '16 at 08:01
  • Sweet and simple, but according to the microsoft docs this way of doing things will not be around forever. There is a warning indicating that it will be going away in the next version https://learn.microsoft.com/en-us/sql/t-sql/statements/drop-default-transact-sql – Hopeless Dec 02 '17 at 02:57
  • I am trying all these queries but none is woking for me – Umair Khan Aug 10 '20 at 18:48
  • I am looking to query to delete foriegn key – Umair Khan Aug 10 '20 at 18:48
12

To drop constraint for multiple columns:

declare @table_name nvarchar(256)

declare @Command nvarchar(max) = ''

set @table_name = N'ATableName'

select @Command = @Command + 'ALTER TABLE ' + @table_name + ' drop constraint ' + d.name + CHAR(10)+ CHAR(13)
from sys.tables t
join sys.default_constraints d on d.parent_object_id = t.object_id
join sys.columns c on c.object_id = t.object_id
     and c.column_id = d.parent_column_id
where t.name = @table_name and c.name in ('column1','column2','column3')

--print @Command

execute (@Command)
Abdur Rahman
  • 1,420
  • 1
  • 21
  • 32
Ken Yao
  • 1,506
  • 1
  • 13
  • 24
5

Expanded solution (takes table schema into account):

-- Drop default contstraint for SchemaName.TableName.ColumnName
DECLARE @schema_name NVARCHAR(256)
DECLARE @table_name NVARCHAR(256)
DECLARE @col_name NVARCHAR(256)
DECLARE @Command  NVARCHAR(1000)

set @schema_name = N'SchemaName'
set @table_name = N'TableName'
set @col_name = N'ColumnName'

SELECT @Command = 'ALTER TABLE [' + @schema_name + '].[' + @table_name + '] DROP CONSTRAINT ' + d.name
 FROM sys.tables t   
  JOIN sys.default_constraints d       
   ON d.parent_object_id = t.object_id  
  JOIN sys.schemas s
        ON s.schema_id = t.schema_id
  JOIN    sys.columns c      
   ON c.object_id = t.object_id      
    AND c.column_id = d.parent_column_id
 WHERE t.name = @table_name
    AND s.name = @schema_name 
  AND c.name = @col_name

EXECUTE (@Command)
Jorge Garcia
  • 2,042
  • 23
  • 25
4

Run this command to browse all constraints:

exec sp_helpconstraint 'mytable' --and look under constraint_name. 

It will look something like this: DF__Mytable__Column__[ABC123]. Then you can just drop the constraint.

Kiquenet
  • 14,494
  • 35
  • 148
  • 243
Baked Inhalf
  • 3,375
  • 1
  • 31
  • 45
3

Drop all default contstraints in a database - safe for nvarchar(max) threshold.

/* WARNING: THE SAMPLE BELOW; DROPS ALL THE DEFAULT CONSTRAINTS IN A DATABASE */ 
/* MAY 03, 2013 - BY WISEROOT  */
declare @table_name nvarchar(128)
declare @column_name nvarchar(128)
declare @df_name nvarchar(128)
declare @cmd nvarchar(128) 

declare table_names cursor for 
 SELECT t.name TableName, c.name ColumnName
 FROM sys.columns c INNER JOIN
     sys.tables t ON c.object_id = t.object_id INNER JOIN
     sys.schemas s ON t.schema_id = s.schema_id
     ORDER BY T.name, c.name

     open table_names
fetch next from table_names into @table_name , @column_name
while @@fetch_status = 0
BEGIN

if exists (SELECT top(1) d.name from sys.tables t join sys.default_constraints d on d.parent_object_id = t.object_id join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id where t.name = @table_name and c.name = @column_name)
BEGIN
    SET @df_name = (SELECT top(1) d.name from sys.tables t join sys.default_constraints d on d.parent_object_id = t.object_id join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id where t.name = @table_name and c.name = @column_name)
    select @cmd = 'ALTER TABLE [' + @table_name +  '] DROP CONSTRAINT [' +  @df_name + ']'
    print @cmd
    EXEC sp_executeSQL @cmd;
END

  fetch next from table_names into @table_name , @column_name
END

close table_names 
deallocate table_names
Brian J
  • 694
  • 1
  • 21
  • 34
  • ***Not valid*** if some columns that had ***multiple*** _default constraints or check constraints_ created, Only executed for ***top 1 constraints*** in query. – Kiquenet Jul 07 '16 at 09:10
2

I hope this could be helpful for whom has similar problem . In ObjectExplorer window, select your database=> Tables,=> your table=> Constraints. If the customer is defined on create column time, you can see the default name of constraint including the column name. then use:

ALTER TABLE  yourTableName DROP CONSTRAINT DF__YourTa__NewCo__47127295;

(the constraint name is just an example)

Elnaz
  • 2,854
  • 3
  • 29
  • 41
  • 1
    This is bad practice for production-ready migrations. The unique identifier `47127295` may change depending when/where the table is defined. – airvine Feb 14 '22 at 16:40
2

Following solution will drop specific default constraint of a column from the table

Declare @Const NVARCHAR(256)

SET @Const = (
              SELECT TOP 1 'ALTER TABLE' + YOUR TABLE NAME +' DROP CONSTRAINT '+name
              FROM Sys.default_constraints A
              JOIN sysconstraints B on A.parent_object_id = B.id
              WHERE id = OBJECT_ID('YOUR TABLE NAME')
              AND COL_NAME(id, colid)='COLUMN NAME'
              AND OBJECTPROPERTY(constid,'IsDefaultCnst')=1
            )
 EXEC (@Const)
cooLLedge
  • 15
  • 1
  • 7
Abdur Rahman
  • 1,420
  • 1
  • 21
  • 32
1
declare @ery nvarchar(max)
declare @tab nvarchar(max) = 'myTable'
declare @qu nvarchar(max) = 'alter table '+@tab+' drop constraint '

select @ery = (select bj.name from sys.tables as tb 
inner join sys.objects as bj 
on tb.object_id = bj.parent_object_id
where tb.name = @tab and bj.type = 'PK')

exec(@qu+@ery)

Take a look.

Pang
  • 9,564
  • 146
  • 81
  • 122
  • 2
    Even if your code brings a solution, it is best that you wrap it around a little bit of explanations as to why it solves the question. – Fabien Jul 15 '17 at 02:58
1

Here is a simple solution, just replace your_table and the column_name.

DECLARE @var0 nvarchar(128)
SELECT @var0 = name
FROM sys.default_constraints
WHERE parent_object_id = object_id(N'${default_schema}.your_table')
  AND col_name(parent_object_id, parent_column_id) = 'column_name';
IF @var0 IS NOT NULL
    EXECUTE ('ALTER TABLE ${default_schema}.your_table DROP CONSTRAINT [' + @var0 + ']');
GO
Andrew
  • 36
  • 2
0

I had some columns that had multiple default constraints created, so I create the following stored procedure:

CREATE PROCEDURE [dbo].[RemoveDefaultConstraints] @table_name nvarchar(256), @column_name nvarchar(256)
AS
BEGIN

    DECLARE @ObjectName NVARCHAR(100)

    START: --Start of loop
    SELECT 
        @ObjectName = OBJECT_NAME([default_object_id]) 
    FROM 
        SYS.COLUMNS
    WHERE 
        [object_id] = OBJECT_ID(@table_name) 
        AND [name] = @column_name;

    -- Don't drop the constraint unless it exists
    IF @ObjectName IS NOT NULL
    BEGIN
        EXEC ('ALTER TABLE '+@table_name+' DROP CONSTRAINT ' + @ObjectName)
        GOTO START; --Used to loop in case of multiple default constraints
    END
END
GO

-- How to run the stored proc.  This removes the default constraint(s) for the enabled column on the User table.
EXEC [dbo].[RemoveDefaultConstraints] N'[dbo].[User]', N'enabled'
GO

-- If you hate the proc, just get rid of it
DROP PROCEDURE [dbo].[RemoveDefaultConstraints]
GO
anztenney
  • 627
  • 2
  • 7
  • 17
0

Useful for some columns that had multiple default constraints or check constraints created:

Modified https://stackoverflow.com/a/16359095/206730 script

Note: this script is for sys.check_constraints

declare @table_name nvarchar(128)
declare @column_name nvarchar(128)
declare @constraint_name nvarchar(128)
declare @constraint_definition nvarchar(512)

declare @df_name nvarchar(128)
declare @cmd nvarchar(128) 

PRINT 'DROP CONSTRAINT [Roles2016.UsersCRM].Estado'

declare constraints cursor for 
 select t.name TableName, c.name ColumnName, d.name ConstraintName, d.definition ConstraintDefinition
 from sys.tables t   
 join sys.check_constraints d  on d.parent_object_id = t.object_id  
 join sys.columns c  on c.object_id = t.object_id      
 and c.column_id = d.parent_column_id
 where t.name = N'Roles2016.UsersCRM' and c.name = N'Estado'

open constraints
fetch next from constraints into @table_name , @column_name, @constraint_name, @constraint_definition
while @@fetch_status = 0
BEGIN
    print 'CONSTRAINT: ' + @constraint_name
    select @cmd = 'ALTER TABLE [' + @table_name +  '] DROP CONSTRAINT [' +  @constraint_name + ']'
    print @cmd
    EXEC sp_executeSQL @cmd;

  fetch next from constraints into @table_name , @column_name, @constraint_name, @constraint_definition
END

close constraints 
deallocate constraints
Community
  • 1
  • 1
Kiquenet
  • 14,494
  • 35
  • 148
  • 243
0

Always generate script and review before you run. Below the script

  select 'Alter table dbo.' + t.name + ' drop constraint '+ d.name  
  from sys.tables t
  join sys.default_constraints d on d.parent_object_id = t.object_id
  join sys.columns c on c.object_id = t.object_id
       and c.column_id = d.parent_column_id
  where c.name in ('VersionEffectiveDate','VersionEndDate','VersionReasonDesc')
  order by t.name
Abdur Rahman
  • 1,420
  • 1
  • 21
  • 32
0
declare @table_name nvarchar(100)
declare @col_name nvarchar(100)
declare @constraint nvarchar(100)
set @table_name = N'TableName'
set @col_name = N'ColumnName'

IF EXISTS (select       c.*
    from        sys.columns c 
    inner join  sys.tables t on t.object_id = c.object_id
    where       t.name = @table_name
    and         c.name = @col_name) 
BEGIN

select @constraint=d.name
from 
sys.tables t
join sys.default_constraints d on d.parent_object_id = t.object_id
join sys.columns c on c.object_id = t.object_id
and c.column_id = d.parent_column_id
where 
t.name = @table_name
and c.name = @col_name

    IF LEN(ISNULL(@constraint, '')) <> 0
    BEGIN
        DECLARE @sqlcmd VARCHAR(MAX)
        SET @sqlcmd = 'ALTER TABLE ' + QUOTENAME(@table_name) + ' DROP CONSTRAINT' + 
        QUOTENAME(@constraint);
        EXEC (@sqlcmd);

    END

END
GO
user2832577
  • 77
  • 2
  • 7
0

This will check if the foreign key exists or not. If it exists, then drop that.

DECLARE @SCHEMA_NAME NVARCHAR(256)
-- The table name you what drop the foreign key from.
DECLARE @ALTER_TABLE_NAME NVARCHAR(256)
-- The table name is liked with the foreign key.
DECLARE @REF_TABLE_NAME NVARCHAR(256) 
DECLARE @COMMAND  NVARCHAR(MAX)

SET @SCHEMA_NAME = N'MySchema';
SET @ALTER_TABLE_NAME = N'MyAlterTable';
SET @REF_TABLE_NAME = N'MyReferTable';

IF EXISTS (
    SELECT NAME
    FROM SYS.FOREIGN_KEYS
    WHERE PARENT_OBJECT_ID = (
        SELECT OBJECT_ID
        FROM SYS.OBJECTS
        WHERE OBJECT_ID = OBJECT_ID(@ALTER_TABLE_NAME)
    )
    AND REFERENCED_OBJECT_ID = (
        SELECT OBJECT_ID
        FROM SYS.OBJECTS
        WHERE OBJECT_ID = OBJECT_ID(@REF_TABLE_NAME)
    )
)
BEGIN
    SELECT @COMMAND = 'ALTER TABLE ['
        + @SCHEMA_NAME
        + '].['
        + @ALTER_TABLE_NAME
        + '] DROP CONSTRAINT '
        + NAME
    FROM SYS.FOREIGN_KEYS
    WHERE PARENT_OBJECT_ID = (
        SELECT OBJECT_ID
        FROM SYS.OBJECTS
        WHERE OBJECT_ID = OBJECT_ID(@ALTER_TABLE_NAME)
    )
    AND REFERENCED_OBJECT_ID = (
        SELECT OBJECT_ID
        FROM SYS.OBJECTS
        WHERE OBJECT_ID = OBJECT_ID(@REF_TABLE_NAME)
    )
    
    EXECUTE (@COMMAND)
END
GO