2009-03-22 24 views
12

Al ser un novato, he creado algunas claves externas sin un nombre explícito.Eliminando restricciones sin nombre

Luego he fundado SQL nombres locos como FK__Machines__IdArt__760D22A7. Supongo que se generarán con diferentes nombres en diferentes servidores.

¿Hay alguna buena función para eliminar las restricciones FK no nombradas pasando como argumentos las tablas y los campos en cuestión?

Respuesta

5

No hay un procedimiento integrado para lograr esto, pero puede crear el suyo usando la información en las vistas de información_schema.

Tabla basada ejemplo

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

Puede utilizar la táctica anterior con sp_rename así para que los nombres más legible si se quiere hacer eso en lugar de solo déjalos caer. –

+0

¿Hay alguna manera de evitar eliminar todas las restricciones sin nombre de la tabla? Por ejemplo: "dropFK 'Machines', 'IdArticle', 'Articles'", donde IdArticle es PK y Articles es la tabla a la que se hace referencia? – nano

+0

Ciertamente, solo necesita profundizar un poco más en las tablas del sistema, restringiendo eso específicamente podría lograrse uniéndose a sysforeignkeys – cmsjr

13

Para soltar un defecto no identificado individuo restringe en una columna de utilizar el siguiente código:

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 quieres hacer esto por una columna predeterminada, que es, probablemente, más común que la pregunta original y estoy seguro de que mucha gente aterrizará en esto desde una búsqueda en Google, luego simplemente cambie la línea:

obj.type = 'F' 

a

obj.type = 'D' 
+1

esto no funciona para mí - default_object_id está en blanco para la columna que quiero –

1

Esto le permitirá caer una restricción de clave externa específica basada en nombredetabla + columna de nombre

Después de probar las otras respuestas que acaba de tener un hurgar en las tablas del sistema hasta que encontré algo probablemente mirando.

la que desea es Constraint_Column_Usage que de acuerdo con los documentos Returns one row for each column in the current database that has a constraint defined on the column.

Me he unido a sys.objects para obtener sólo las claves externas.

En un procedimiento (esto toma prestado de las otras respuestas Saludos muchachos.!):

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