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

Rob*_*obo 190 sql t-sql sql-server

在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
Run Code Online (Sandbox Code Playgroud)

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

如何在没有任何SQL错误的情况下删除默认约束?默认约束名称不会显示在INFORMATION_SCHEMA表中,这会使事情变得有点棘手.

因此,类似于"删除此表/列中的默认约束"或"删除DF_SmoeTable_ColName",但如果无法找到它,则不会出现任何错误.

Phi*_*ley 256

扩展Mitch Wheat的代码,以下脚本将生成删除约束并动态执行它的命令.

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)
Run Code Online (Sandbox Code Playgroud)

  • 此查询仅解决默认约束,每个列只能有一个约束.处理检查约束是一个不同的问题. (4认同)
  • 检查http://stackoverflow.com/a/15786313/2049986以查看删除表的所有约束的版本 (2认同)
  • 我使用 ***sys.check_constraints*** ,而不是 ***sys.default_constraints*** (2认同)

Mit*_*eat 232

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
Run Code Online (Sandbox Code Playgroud)


Scu*_*eve 100

我发现这有效并且不使用连接:

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)
Run Code Online (Sandbox Code Playgroud)

只需确保columnName没有括号,因为查询正在查找完全匹配,如果它是[columnName]则不返回任何内容.

  • 要使此脚本具有幂等性,请在EXEC命令之前添加"IF @ObjectName IS NOT NULL" (6认同)
  • 使用***CHECK约束***不适合我.`[default_object_id])`是***0***.我得到***NULL***值. (3认同)

Ken*_*Yao 11

要删除多列的约束:

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)
Run Code Online (Sandbox Code Playgroud)


Jor*_*cia 5

扩展解决方案(将表模式考虑在内):

-- 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)
Run Code Online (Sandbox Code Playgroud)