2009-03-22 15 views
12

Będąc nowicjuszem, utworzyłem klucze obce bez wyraźnej nazwy.Zrzucanie nienazwanych wiązań

Następnie założyłem generowane przez SQL zwariowane nazwy, takie jak FK__Machines__IdArt__760D22A7. Zgadnij, że będą generowane z różnymi nazwami na różnych serwerach.

Czy istnieje niezła funkcja upuszczania nienazwanych więzów FK przekazujących jako argumenty tabele i pola, o których mowa?

Odpowiedz

5

Nie ma wbudowanej procedury, aby to osiągnąć, ale można tworzyć własne, korzystając z informacji w widokach informacji_schematu.

oparty Tabela przykładem

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

Można użyć powyższej taktykę z procedury sp_rename także aby nazwy bardziej czytelny, jeśli chcesz zrobić, że zamiast po prostu je upuść. –

+0

Czy istnieje sposób na uniknięcie upuszczenia wszystkich ograniczeń bez nazwy ze stołu? Na przykład: "dropFK" Machines "," IdArticle "," Articles "", gdzie IdArticle to PK a artykuły to tabela, do której się odwołujemy? – nano

+0

Z pewnością wystarczy trochę głębiej zagłębić się w tabelach systemowych, ograniczając to, co konkretnie można osiągnąć, łącząc się z sysforeignkeys – cmsjr

13

Dla upuszczenie indywidualny nienazwany domyślne ograniczyć na kolumnie należy użyć następującego kodu:

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 

Jeśli chcesz zrobić to dla kolumny domyślnej, która jest prawdopodobnie bardziej powszechne niż oryginalne pytanie i jestem pewien, że wielu ludzi wyląduje na tym z wyszukiwarki Google, a następnie po prostu zmień linię:

obj.type = 'F' 

do

obj.type = 'D' 
+1

to nie działa dla mnie - default_object_id jest puste dla kolumny chcę –

1

To pozwoli Ci spaść konkretnego klucza obcego w oparciu o tablename + kolumny nazwy

Po wypróbowaniu innych odpowiedzi miałem tylko grzebać w tabelach systemowych aż znalazłem coś prawdopodobnie wyglądający.

Ten chcesz to Constraint_Column_Usage które zgodnie z docs Returns one row for each column in the current database that has a constraint defined on the column.

Mam dołączył go do sys.objects po prostu dostać klucze obce.

W procedurze (to pożycza od innych odpowiedzi wiwaty facetów.!):

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 
Powiązane problemy