How to drop column with constraint?

后端 未结 8 554
半阙折子戏
半阙折子戏 2020-11-29 16:58

How to drop a column which is having Default constraint in SQL Server 2008?

My query is

alter table tbloffers
drop column checkin

相关标签:
8条回答
  • 2020-11-29 17:36

    I got the same:

    ALTER TABLE DROP COLUMN failed because one or more objects access this column message.

    My column had an index which needed to be deleted first. Using sys.indexes did the trick:

    DECLARE @sql VARCHAR(max)
    
    SELECT @sql = 'DROP INDEX ' + idx.NAME + ' ON tblName'
    FROM sys.indexes idx
    INNER JOIN sys.tables tbl ON idx.object_id = tbl.object_id
    INNER JOIN sys.index_columns idxCol ON idx.index_id = idxCol.index_id
    INNER JOIN sys.columns col ON idxCol.column_id = col.column_id
    WHERE idx.type <> 0
        AND tbl.NAME = 'tblName'
        AND col.NAME = 'colName'
    
    EXEC sp_executeSql @sql
    GO
    
    ALTER TABLE tblName
    DROP COLUMN colName
    
    0 讨论(0)
  • 2020-11-29 17:40

    It's not always just a default constraint that prevents from droping a column and sometimes indexes can also block you from droping the constraint. So I wrote a procedure that drops any index or constraint on a column and the column it self at the end.

    IF OBJECT_ID ('ADM_delete_column', 'P') IS NOT NULL
       DROP procedure ADM_delete_column;
    GO
    
    CREATE procedure ADM_delete_column
        @table_name_in  nvarchar(300)
    ,   @column_name_in nvarchar(300)
    AS 
    BEGIN
        /*  Author: Matthis (matthis@online.ms at 2019.07.20)
            License CC BY (creativecommons.org)
            Desc:   Administrative procedure that drops columns at MS SQL Server
                    - if there is an index or constraint on the column 
                        that will be dropped in advice
                    => input parameters are TABLE NAME and COLUMN NAME as STRING
        */
        SET NOCOUNT ON
    
        --drop index if exist (search first if there is a index on the column)
        declare @idx_name VARCHAR(100)
        SELECT  top 1 @idx_name = i.name
        from    sys.tables t
        join    sys.columns c
        on      t.object_id = c.object_id
        join    sys.index_columns ic
        on      c.object_id = ic.object_id
        and     c.column_id = ic.column_id
        join    sys.indexes i
        on      i.object_id = ic.object_id
        and     i.index_id = ic.index_id
        where   t.name like @table_name_in
        and     c.name like @column_name_in
        if      @idx_name is not null
        begin 
            print concat('DROP INDEX ', @idx_name, ' ON ', @table_name_in)
            exec ('DROP INDEX ' + @idx_name + ' ON ' + @table_name_in)
        end
    
        --drop fk constraint if exist (search first if there is a constraint on the column)
        declare @fk_name VARCHAR(100)
        SELECT  top 1 @fk_name = CONSTRAINT_NAME 
        from    INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE
        where   TABLE_NAME like @table_name_in
        and     COLUMN_NAME like @column_name_in
        if      @fk_name is not null
        begin 
            print concat('ALTER TABLE ', @table_name_in, ' DROP CONSTRAINT ', @fk_name)
            exec ('ALTER TABLE ' + @table_name_in + ' DROP CONSTRAINT ' + @fk_name)
        end
    
        --drop column if exist
        declare @column_name VARCHAR(100)
        SELECT  top 1 @column_name = COLUMN_NAME 
        FROM    INFORMATION_SCHEMA.COLUMNS 
        WHERE   COLUMN_NAME like concat('%',@column_name_in,'%')
        if  @column_name is not null
        begin 
            print concat('ALTER TABLE ', @table_name_in, ' DROP COLUMN ', @column_name)
            exec ('ALTER TABLE ' + @table_name_in + ' DROP COLUMN ' + @column_name)
        end
    end;
    GO
    
    
    --to run the procedure use this execute and fill the parameters 
    execute ADM_delete_column 
        @table_name_in  = ''
    ,   @column_name_in = ''
        ;
    
    0 讨论(0)
提交回复
热议问题