如何在不知道名称的情况下删除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_ColName
或DF_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)