2009-03-22 5 views
12

En tant que recrue, j'ai créé des clés étrangères sans nom explicite.Suppression de contraintes sans nom

Puis j'ai fondé des noms fous générés par SQL comme FK__Machines__IdArt__760D22A7. Devinez qu'ils seront générés avec des noms différents sur différents serveurs.

Existe-t-il une fonction intéressante pour supprimer les contraintes FK non nommées passant en arguments les tables et les champs en question?

Répondre

5

Il n'existe pas de procédure intégrée pour cela, mais vous pouvez créer les vôtres en utilisant les informations des vues information_schema.

Tableau basé exemple

Create Proc dropFK(@TableName sysname) 
as 
Begin 

Declare @FK sysname 
Declare @SQL nvarchar(4000) 
Declare crsFK cursor for 

select tu.Constraint_Name from 
information_schema.constraint_table_usage TU 
LEFT JOIN SYSOBJECTS SO 
ON TU.Constraint_NAME = SO.NAME 
where xtype = 'F' 
and Table_Name = @TableName 
open crsFK 
fetch next from crsFK into @FK 
While (@@Fetch_Status = 0) 
Begin 
    Set @SQL = 'Alter table ' + @TableName + ' Drop Constraint ' + @FK 
    Print 'Dropping ' + @FK 
    exec sp_executesql @SQL 
    fetch next from crsFK into @FK 
End 
Close crsFK 
Deallocate crsFK 
End 
+1

Vous pouvez utiliser la tactique ci-dessus avec sp_rename et de rendre les noms plus lisibles si vous voulez le faire plutôt que il suffit de les laisser tomber. –

+0

Existe-t-il un moyen d'éviter de supprimer toutes les contraintes non nommées de la table? Par exemple: "dropFK 'Machines', 'IdArticle', 'Articles'", où IdArticle est le PK et Articles est la table référencée? – nano

+0

Certes, vous avez juste besoin de creuser un peu plus profond dans les tables système, restreignant cela pourrait être accompli en se joignant à sysforeignkeys – cmsjr

13

Pour déposer un défaut sans nom individuel contraignent sur une colonne en utilisant le code suivant:

DECLARE @ConstraintName VARCHAR(256) 
SET @ConstraintName = (
    SELECT    obj.name 
    FROM    sys.columns col 

    LEFT OUTER JOIN sys.objects obj 
    ON     obj.object_id = col.default_object_id 
    AND    obj.type = 'F' 

    WHERE    col.object_id = OBJECT_ID('TableName') 
    AND    obj.name IS NOT NULL 
    AND    col.name = 'ColunmName' 
) 

IF(@ConstraintName IS NOT NULL) 
BEGIN 
    EXEC ('ALTER TABLE [TableName] DROP CONSTRAINT ['[email protected]+']') 
END 

Si vous voulez faire cela pour une colonne par défaut, ce qui est probablement plus commun que la question d'origine et je suis sûr que beaucoup de gens vont atterrir sur ce à partir d'une recherche Google, puis simplement changer la ligne:

obj.type = 'F' 

à

obj.type = 'D' 
+1

cela ne fonctionne pas pour moi - default_object_id est vide pour la colonne que je veux –

1

Cela vous permettra de supprimer une contrainte de clé étrangère spécifique basée sur le nom tablename + colonne

Après avoir essayé les autres réponses que je viens d'avoir un coup de coude autour des tables système jusqu'à ce que je trouve quelque chose regarder probablement.

celui que vous voulez est constraint_column_usage qui, selon les docs Returns one row for each column in the current database that has a constraint defined on the column.

Je l'ai rejoint à sys.objects pour obtenir juste les clés étrangères.

Dans une procédure (ce qui emprunte les autres réponses acclamations gars.!):

Create Proc yourSchema.dropFK(@SchemaName NVarChar(128), @TableName NVarChar(128), @ColumnName NVarChar(128)) 
as 
Begin 

    DECLARE @ConstraintName nvarchar(128) 
    SET @ConstraintName = (
     select c.Constraint_Name 
      from Information_Schema.Constraint_Column_usage c 
      left join sys.objects o 
      on o.name = c.Constraint_Name 
      where c.TABLE_SCHEMA = @SchemaName and 
       c.Table_name = @TableName and 
       c.Column_Name = @ColumnName and 
       o.type = 'F' 
    ) 

    exec ('alter table [' + @SchemaName + '].[' + @TableName + '] drop constraint [' + @ConstraintName + ']') 
End 
Questions connexes