2010-02-08 2 views
4

Qu'est-ce qu'une méthode pour déterminer s'il existe une contrainte par défaut sur une colonne et son nom, et les noms de tous les index pour les supprimer avant de tomber la colonne?Comment faire pour supprimer une colonne avec une contrainte de valeur par défaut non nommée et des index inconnus

+1

Quelle est votre question? –

+0

Comment faire pour supprimer une colonne avec des contraintes et des index par défaut sans nom? Désolé si le "comment" n'est pas dans la ligne objet, mais il y a un tel méli-mélo d'informations sur ce site concernant ces sujets, et la FAQ dit que vous pouvez répondre à votre propre question, que je pensais que je posterais un solution concise pour que cela puisse aider les autres. – avenmore

+0

À l'avenir, vous pouvez suivre ce processus: -> Ecrire question -> Publier question -> Ecrire une réponse (dans la section de réponse) -> Réponse post -> marque comme réponse. Bien que si vous aimez bloguer, cela ressemble au genre de chose qui ferait un bon sujet. –

Répondre

9

Le processus d'utilitaire suivant accomplira la tâche.

if (exists (select * from [dbo].sysobjects where (id = object_id(N'[dbo]._spDropDefaultValueConstraint')) and (xtype = 'P'))) 
drop procedure [dbo]._spDropDefaultValueConstraint 
GO 

create procedure [dbo]._spDropDefaultValueConstraint 
@TableName varchar(256), 
@ColumnName varchar(256) 
as 
/* This proc will drop the default value constraint on 
a column even when you don't know what its name is. 
*/ 
declare @ConstraintName varchar(256) 
set @ConstraintName = (
select 
    dobj.name 
from sys.columns col 
    left outer join sys.objects dobj 
    on dobj.object_id = col.default_object_id and dobj.type = 'D' 
where col.object_id = object_id('[dbo].'[email protected]) 
and dobj.name is not null 
and col.name = @ColumnName) 

if(isnull(@ConstraintName, '') <> '') 
exec('alter table [dbo].['[email protected]+'] drop constraint ['[email protected]+']') 

GO 

------------------------------------------------------------------------------------------- 

if (exists (select * from [dbo].sysobjects where (id = object_id(N'[dbo]._spDropIndexesForColumn')) and (xtype = 'P'))) 
drop procedure [dbo]._spDropIndexesForColumn 
GO 

create procedure [dbo]._spDropIndexesForColumn 
@TableName varchar(256), 
@ColumnName varchar(256) 
as 
/* This proc will drop all indexes on a column, both indexes 
and unique constraints as well as multi-part indexes that reference it. 
*/ 
declare @IndexName varchar(256) 
declare @IsPrimaryKey bit 
declare @IsUniqueConstraint bit 

declare crIndexes cursor for 
select 
    ind.name, ind.is_primary_key, ind.is_unique_constraint 
from 
    sys.indexes ind 
    inner join sys.index_columns ic on ind.object_id = ic.object_id and ind.index_id = ic.index_id 
    inner join sys.columns col on ic.object_id = col.object_id and ic.column_id = col.column_id 
    inner join sys.tables t on ind.object_id = t.object_id 
where 
    t.name = @TableName and 
    col.name = @ColumnName  
open crIndexes 
fetch next from crIndexes into @IndexName, @IsPrimaryKey, @IsUniqueConstraint 
while(@@fetch_status = 0) begin 
if(@IsPrimaryKey = 1) or (@IsUniqueConstraint = 1) 
    exec('alter table [dbo].['[email protected]+'] drop constraint ['[email protected]+']') 
else 
    exec('drop index [dbo].['[email protected]+'].['[email protected]+']') 
fetch next from crIndexes into @IndexName, @IsPrimaryKey, @IsUniqueConstraint 
end 
close crIndexes 
deallocate crIndexes 

GO 

------------------------------------------------------------------------------------------- 

if (exists (select * from [dbo].sysobjects where (id = object_id(N'[dbo]._spDropColumn')) and (xtype = 'P'))) 
drop procedure [dbo]._spDropColumn 
GO 

create procedure [dbo]._spDropColumn 
@TableName varchar(256), 
@ColumnName varchar(256) 
as 
/* This proc will drop a column (first dropping the default value 
constraint and any indexes if they exist) if it exists. 
*/ 
if (exists (select * from [dbo].sysobjects where (id = object_id('[dbo].'[email protected])) and (xtype = 'U'))) and 
    (exists (select * from [dbo].syscolumns where (id = object_id('[dbo].'[email protected])) and (name = @ColumnName))) begin 
exec [dbo]._spDropIndexesForColumn @TableName, @ColumnName 
exec [dbo]._spDropDefaultValueConstraint @TableName, @ColumnName 
exec('alter table [dbo].['[email protected]+'] drop column ['[email protected]+']') 
end 
GO 

Il est alors facile d'invoquer comme suit:

exec [dbo]._spDropColumn 'TableName', 'ColumnName' 

Je ne l'ai pas regardé les clés étrangères que nous ne les utilisons pas, mais peut-être ils pourraient être inclus aussi.

Questions connexes