如何在不知道名称的情况下删除SQL默认约束?

在Microsoft SQL Server中,我知道查询是否存在一个列的默认约束,并删除默认约束是:

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 

但由于数据库以前版本中的拼写错误,约束的名称可能是DF_SomeTable_ColNameDF_SmoeTable_ColName

我怎样才能删除没有任何SQL错误的默认约束? 默认的约束名称不会显示在INFORMATION_SCHEMA表中,这使得事情有点棘手。

所以,就像'删除这个表/列中的默认约束',或者'删除DF_SmoeTable_ColName ',但是如果它找不到它,就不会给出任何错误。

在Mitch Wheat的代码上展开,以下脚本将生成命令来删除约束并dynamic执行它。

 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) 

Rob Farley的博文可能有帮助:

  • 有两种方法可以在不知道名称的情况下查找/删除默认约束

就像是:

  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 

我发现这个工作,并没有使用连接:

 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) 

只要确保columnName没有括号就可以了,因为查询正在查找完全匹配,并且如果它是[columnName],将不会返回任何内容。

要删除多列的约束:

 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) 

扩展的解决scheme(考虑表格模式):

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

将所有默认限制放在数据库中 – 对于nvarchar(max)阈值是安全的。

 /* 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 

运行这个命令浏览所有约束:

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

它会看起来像这样: DF__Mytable__Column__[ABC123] 。 那么你可以放弃约束。

我有一些列创build了多个默认约束,所以我创build了以下存储过程:

 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 

对于有多个 default constraints or check constraints创build的列有用:

修改了https://stackoverflow.com/a/16359095/206730脚本;

注意:这个脚本是针对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 

我希望这可以帮助有类似问题的人。 在ObjectExplorer窗口中,select你的数据库=>表,=>你的表=>约束。 如果在创build列时间上定义了客户,则可以看到包含列名的约束的默认名称。 然后使用:

 ALTER TABLE yourTableName DROP CONSTRAINT DF__YourTa__NewCo__47127295; 

(约束名称只是一个例子)

运行前始终生成脚本并进行检查。 在脚本下面

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

以下解决scheme将从表中删除列的特定默认约束

 Declare @Const SET @Const = ( SELECT TOP 1 'ALTER TABLE' + YOUR TABLE NAME +' DROP CONSTRAINT '+name FROM Sys.default_constraints A JOIN sysconstrints 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)