web-dev-qa-db-fra.com

Supprimer la contrainte par défaut sur une colonne dans SQL

J'ai un tableau avec une colonne comme celle-ci qui est actuellement en ligne:

name NVARCHAR(128) NOT NULL DEFAULT ''

Je modifie la colonne comme ceci pour la rendre nullable:

ALTER TABLE  mytable ALTER COLUMN name NVARCHAR(128) NULL

Cependant, la contrainte par défaut, nommée "DF__mytable__datab__7DE4B36" dans une instance de la table, reste toujours. Je sais que cela aurait pu être évité si l'auteur d'origine avait nommé la contrainte. J'ai plusieurs instances de ces tables mais je ne veux pas supprimer manuellement toutes les contraintes de chaque table que j'ai. Quelle est la façon la plus simple et la plus élégante de supprimer cette contrainte par défaut sur une colonne dans Sql Server que je peux appliquer uniformément à chaque instance de cette table?

MODIFIER

Voici le script que j'ai fini par utiliser:

DECLARE @table_id AS INT
DECLARE @name_column_id AS INT
DECLARE @sql nvarchar(255) 

-- Find table id
SET @table_id = OBJECT_ID('mytable')

-- Find name column id
SELECT @name_column_id = column_id
FROM sys.columns
WHERE object_id = @table_id
AND name = 'name'

-- Remove default constraint from name column
SELECT @sql = 'ALTER TABLE mytable DROP CONSTRAINT ' + D.name
FROM sys.default_constraints AS D
WHERE D.parent_object_id = @table_id
AND D.parent_column_id = @name_column_id
EXECUTE sp_executesql @sql

Un autre script qui peut être utilisé pour accomplir cela peut être trouvé ici: Comment supprimer la contrainte par défaut SQL sans connaître son nom?

Merci!

34
Mohammed Ali

C'est ainsi que vous supprimeriez la contrainte

ALTER TABLE <schema_name, sysname, dbo>.<table_name, sysname, table_name>
   DROP CONSTRAINT <default_constraint_name, sysname, default_constraint_name>
GO

Avec un script

-- t-sql scriptlet to drop all constraints on a table
DECLARE @database nvarchar(50)
DECLARE @table nvarchar(50)

set @database = 'dotnetnuke'
set @table = 'tabs'

DECLARE @sql nvarchar(255)
WHILE EXISTS(select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where constraint_catalog = @database and table_name = @table)
BEGIN
    select    @sql = 'ALTER TABLE ' + @table + ' DROP CONSTRAINT ' + CONSTRAINT_NAME 
    from    INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
    where    constraint_catalog = @database and 
            table_name = @table
    exec    sp_executesql @sql
END

Les crédits vont à Jon Galloway http://weblogs.asp.net/jgalloway/archive/2006/04/12/442616.aspx

56
buckley

Je voudrais suggerer:

DECLARE @sqlStatement nvarchar(MAX),
        @tableName nvarchar(50) = 'TripEvent',
        @columnName nvarchar(50) = 'CreatedDate';

SELECT                  @sqlStatement = 'ALTER TABLE ' + @tableName + ' DROP CONSTRAINT ' + dc.name + ';'
        FROM            sys.default_constraints AS dc
            LEFT JOIN   sys.columns AS sc
                ON      (dc.parent_column_id = sc.column_id)
        WHERE           dc.parent_object_id = OBJECT_ID(@tableName)
        AND         type_desc = 'DEFAULT_CONSTRAINT'
        AND         sc.name = @columnName
PRINT'   ['+@tableName+']:'+@@SERVERNAME+'.'+DB_NAME()+'@'+CONVERT(VarChar, GETDATE(), 127)+';  '+@sqlStatement;
IF(LEN(@sqlStatement)>0)EXEC sp_executesql @sqlStatement
2
Konigmann

Je voudrais renvoyer une question précédente, parce que j'ai rencontré le même problème et résolu par ceci solution . Tout d'abord, une contrainte est toujours construite avec une valeur Hash dans son nom. Le problème est donc que HASH varie en fonction de la machine ou de la base de données. Par exemple DF__Companies__IsGlo__6AB17FE4 ici 6AB17FE4 est la valeur de hachage (8 bits). Je fais donc référence à un seul script qui sera fructueux pour tous

DECLARE @Command NVARCHAR(MAX)
     declare @table_name nvarchar(256)
     declare @col_name nvarchar(256)
     set @table_name = N'ProcedureAlerts'
     set @col_name = N'EmailSent'

     select @Command ='Alter Table dbo.ProcedureAlerts Drop Constraint [' + ( select 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 = @col_name) + ']'

    --print @Command
    exec sp_executesql @Command

Cela supprimera votre contrainte par défaut. Cependant, si vous souhaitez le recréer, vous pouvez simplement essayer ceci

ALTER TABLE [dbo].[ProcedureAlerts] ADD DEFAULT((0)) FOR [EmailSent]

Enfin, exécutez simplement une commande DROP pour supprimer la colonne.

1
gdmanandamohon