2009-03-22 16 views
12

Essendo un principiante, ho creato alcune chiavi esterne senza un nome esplicito.Eliminazione dei vincoli non denominati

Quindi ho fondato nomi pazzeschi generati da SQL come FK__Machines__IdArt__760D22A7. Immagino che verranno generati con nomi diversi su server diversi.

C'è qualche buona funzione per eliminare i vincoli FK senza nome passando come argomenti le tabelle e i campi in questione?

risposta

5

Non esiste una procedura incorporata per eseguire questa operazione, ma è possibile crearne una propria utilizzando le informazioni nelle viste information_schema.

tabella basata esempio

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

È possibile utilizzare la tattica di cui sopra con sp_rename anche per rendere i nomi più leggibile se si vuole fare questo, piuttosto che lasciateli cadere –

+0

C'è un modo per evitare di eliminare tutti i vincoli senza nome dalla tabella? Ad esempio: "dropFK" Machines "," IdArticle "," Articoli "", dove IdArticle è il PK e Articoli è la tabella di riferimento? – nano

+0

Certo, devi solo scavare un po 'più a fondo nelle tabelle di sistema, limitando ciò che specificamente potrebbe essere raggiunto unendo a sysforeignkeys – cmsjr

13

per far cadere un individuo di default senza nome vincolare su una colonna utilizzare il seguente codice:

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 

Se si vuole fare questo per una colonna di default, che è probabilmente più comune della domanda originale e sono sicuro che molte persone finiranno su questo da una ricerca su Google, quindi basta cambiare linea:

obj.type = 'F' 

a

obj.type = 'D' 
+1

questo non funziona per me - default_object_id è vuoto per la colonna che voglio –

1

Questo vi permetterà di cadere uno specifico vincolo di chiave esterna sulla base di tablename + colonna nome

Dopo aver provato le altre risposte che ho appena avuto un poke in giro per le tabelle di sistema fino a quando ho trovato qualcosa probabilmente

quello che si desidera è Constraint_Column_Usage che secondo la documentazione Returns one row for each column in the current database that has a constraint defined on the column.

ho aderito a sys.objects per ottenere solo le chiavi esterne.

In una procedura (questo prende in prestito dalle altre risposte Ciao ragazzi.!):

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 
Problemi correlati