2009-09-16 10 views
163

Dans Microsoft SQL Server, je sais la requête pour vérifier si une contrainte par défaut existe pour une colonne et supprimer une contrainte par défaut est:Comment faire pour supprimer la contrainte SQL par défaut sans connaître son nom?

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 

Mais en raison de fautes de frappe dans les versions précédentes de la base de données, le nom du la contrainte peut être DF_SomeTable_ColName ou DF_SmoeTable_ColName. Comment puis-je supprimer la contrainte par défaut sans erreurs SQL? Les noms de contrainte par défaut n'apparaissent pas dans la table INFORMATION_SCHEMA, ce qui rend les choses un peu plus compliquées. Donc, quelque chose comme "supprimer la contrainte par défaut dans cette table/colonne", ou "supprimer DF_SmoeTable_ColName", mais ne donne pas d'erreurs s'il ne peut pas le trouver.

+1

Je ne suis pas compétent avec SQL Server, vous pouvez renommer une contrainte après avoir trouvé son prénom? "Modifier la table peut parfois renommer la contrainte xxx en yyy" dans Oracle. –

Répondre

232

expansion sur le code de Mitch blé, le script suivant va générer la commande abandonne la contrainte et l'exécute dynamiquement.

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) 
+0

Vérifiez http://stackoverflow.com/a/15786313/2049986 pour voir une version pour supprimer toutes les contraintes pour une table –

+0

J'utilise *** sys.check_constraints ***, pas *** sys .default_constraints *** – Kiquenet

+0

*** Non valide *** si certaines colonnes ayant *** multiples *** _default contraintes ou cochées_contraintes_ ont été créées, Uniquement exécuté pour *** dernières contraintes *** dans la requête. – Kiquenet

229

poste de blog de Rob Farley pourrait être utile:

Quelque chose comme:

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 
+1

Meilleure réponse de cette question – gdmanandamohon

10

Pour tomber contrainte pour plusieurs colonnes:

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) 
3

Supprimez toutes les contstraints par défaut dans une base de données - sécurité pour le seuil de 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 
+0

*** Non valide *** si certaines colonnes qui avaient *** multiples *** _default contraintes ou vérifier les contraintes_ créées, Seulement exécuté pour *** top 1 contraintes *** dans la requête. – Kiquenet

79

Je trouve que cela fonctionne et utilise sans jointures:

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) 

Assurez-vous que columnName ne pas parenthèses autour d'elle parce que la requête est à la recherche d'une correspondance exacte et retournera rien si elle est [nom_colonne].

+0

Et cette réponse fonctionne avec des schémas autres que le [dbo] par défaut, contrairement à toutes les autres réponses. – Contango

+0

Je ne l'ai pas testé, mais vous pouvez essayer d'ajouter un WHILE (@ObjectName IS NOT NULL) autour de lui, mettre TOP 1 avant SELECT (at) ObjectName = OBJECT_Name ([par défaut ... et seulement lancer l'EXEC (' ALTER TA ... if (at) Nom de l'objet IS NOT NULL – ScubaSteve

+5

Pour rendre ce script idempotent, ajoutez 'IF @ObjectName IS NOT NULL' avant la commande EXEC – Seven

4

solution étendue (prend schéma de la table en compte):

-- 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) 
0

j'avais des colonnes qui avaient plusieurs contraintes par défaut créées, donc je crée la procédure stockée suivante:

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 '[email protected]_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 
1

Exécutez cette commande pour parcourir toutes les contraintes:

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

Cela ressemble à quelque chose comme t ses: DF__Mytable__Column__[ABC123]. Ensuite, vous pouvez simplement laisser tomber la contrainte.

+0

Ne fonctionne pas pour moi: 'exec sp_helpconstraint 'Roles2016.UsersCRM'' – Kiquenet

+0

@Kiquenet Doit être uniquement le nom de la table: exec sp_helpconstraint' Roles2016 ' –

+0

Il montre juste les contraintes de clé étrangère. pas la valeur par défaut constaint – Ronnie

0

Utile pour certaines colonnes qui avaient plusieursdefault constraints or check constraints créé:

modifié https://stackoverflow.com/a/16359095/206730 scénario

Remarque: ce script est pour sys.check_constraints

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 
0

I espère que thi s pourrait être utile pour qui a le même problème. Dans la fenêtre ObjectExplorer, sélectionnez votre base de données => Tables, => votre table => Contraintes. Si le client est défini lors de la création de l'heure de la colonne, vous pouvez voir le nom par défaut de la contrainte, y compris le nom de la colonne. puis utilisez:

ALTER TABLE yourTableName DROP CONSTRAINT DF__YourTa__NewCo__47127295; 

(le nom de contrainte est juste un exemple)

0

Toujours générer script et vérifiez avant de vous lancer. Ci-dessous le script

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 
0
 declare @ery nvarchar(max) 
     declare @tab nvarchar(max) = 'myTable' 
     declare @qu nvarchar(max) = 'alter table '[email protected]+' 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(@[email protected]) 

     **Take a look** 
+1

Même si votre code apporte une solution, il est préférable que vous l'enveloppiez d'un peu d'explications sur la raison pour laquelle il résout la question. – Fabien

0

solution suivante va laisser tomber la contrainte par défaut spécifique d'une colonne de la table

Declare @Const 

SET @Const = (
       SELECT TOP 1 'ALTER TABLE' + YOUR TABLE NAME +' DROP CONSTRAINT '+name 
       FROM Sys.default_constraints A 
       JOIN sysconstrints 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) 
Questions connexes