代码之家  ›  专栏  ›  技术社区  ›  Robo

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

  •  179
  • Robo  · 技术社区  · 16 年前

    在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错误?默认约束名不会出现在信息模式表中,这使得事情变得更加棘手。

    因此,类似于“删除此表/列中的默认约束”或“删除” df_mometable_colname 但如果找不到就不要出错。

    13 回复  |  直到 7 年前
        1
  •  247
  •   Jacob van Lingen    7 年前

    在mitchweat的代码上展开,下面的脚本将生成删除约束并动态执行约束的命令。

    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)
    
        2
  •  230
  •   Tabatha    8 年前

    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
    
        3
  •  93
  •   ScubaSteve    12 年前

    我发现这个方法有效,不使用连接:

    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],则不会返回任何内容。

        4
  •  11
  •   Abdur Rahman sithum dilanga    7 年前

    要删除多列的约束:

    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)
    
        5
  •  5
  •   Jorge Garcia    7 年前

    扩展解决方案(考虑表架构):

    -- 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)
    
        6
  •  3
  •   Brian J    12 年前

    删除数据库中的所有默认约束-对于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
    
        7
  •  2
  •   cooLLedge Abdur Rahman    8 年前

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

    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)
    
        8
  •  1
  •   Kiquenet user385990    9 年前

    运行此命令浏览所有约束:

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

    它看起来像这样: DF__Mytable__Column__[ABC123] . 然后您可以直接删除约束。

        9
  •  0
  •   anztenney    11 年前

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

    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
    
        10
  •  0
  •   Community Mohan Dere    9 年前

    对某些列有用 倍数 default constraints or check constraints 创建:

    被改进的 https://stackoverflow.com/a/16359095/206730 脚本

    注意:此脚本用于 系统检查限制

    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
    
        11
  •  0
  •   Elnaz    9 年前

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

    ALTER TABLE  yourTableName DROP CONSTRAINT DF__YourTa__NewCo__47127295;
    

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

        12
  •  0
  •   user8310624    8 年前
            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**
    
        13
  •  0
  •   Abdur Rahman sithum dilanga    7 年前

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

      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