2009-05-15 14 views
34

Ho un database SQL 2005 con circa 250 tabelle.SQL Script per modificare TUTTE le chiavi esterne da aggiungere ON DELETE CASCADE

Desidero abilitare temporaneamente ON DELETE CASCADE su tutte le chiavi esterne in modo da poter eseguire facilmente un'eliminazione di massa.

Quindi desidero disattivare ON DELETE CASCADE su tutte le chiavi esterne.

L'unico modo che conosco di fare questo, è quello di utilizzare Management Studio per generare un database completo creare uno script, fare una sorta di ricerca e sostituzione per togliere tutto ma Chiavi esterne, salvare lo script, quindi fare un po 'più di ricerca e sostituendo per aggiungere l'ON DELETE CASCADE.

Quindi eseguo lo script, eseguo l'eliminazione e quindi eseguo l'altro script.

C'è un modo più semplice per produrre questo script? Questo metodo sembra troppo incline all'errore e dovrò mantenere aggiornato lo script con qualsiasi altra modifica apportata al database, o rigenerarlo manualmente ogni volta che potrò aver bisogno di usarlo.

È un'opzione alternativa per eseguire una selezione sulle tabelle di sistema per "generare" lo script per me? Potrebbe anche essere possibile eseguire un aggiornamento su una tabella di sistema che abiliti e disabiliti ON DELETE CASCADE?

risposta

65

Ecco uno script che ho usato per uno scopo simile. Non supporta le chiavi esterne composte (che utilizzano più di un campo). E probabilmente sarà necessario qualche ritocco prima che funzioni per la tua situazione. EDIT: In particolare, non gestisce correttamente le chiavi esterne multi-colonna.

select 
    DropStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema + 
     '].[' + ForeignKeys.ForeignTableName + 
     '] DROP CONSTRAINT [' + ForeignKeys.ForeignKeyName + ']; ' 
, CreateStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema + 
     '].[' + ForeignKeys.ForeignTableName + 
     '] WITH CHECK ADD CONSTRAINT [' + ForeignKeys.ForeignKeyName + 
     '] FOREIGN KEY([' + ForeignKeys.ForeignTableColumn + 
     ']) REFERENCES [' + schema_name(sys.objects.schema_id) + '].[' + 
    sys.objects.[name] + ']([' + 
    sys.columns.[name] + ']) ON DELETE CASCADE; ' 
from sys.objects 
    inner join sys.columns 
    on (sys.columns.[object_id] = sys.objects.[object_id]) 
    inner join (
    select sys.foreign_keys.[name] as ForeignKeyName 
    ,schema_name(sys.objects.schema_id) as ForeignTableSchema 
    ,sys.objects.[name] as ForeignTableName 
    ,sys.columns.[name] as ForeignTableColumn 
    ,sys.foreign_keys.referenced_object_id as referenced_object_id 
    ,sys.foreign_key_columns.referenced_column_id as referenced_column_id 
    from sys.foreign_keys 
     inner join sys.foreign_key_columns 
     on (sys.foreign_key_columns.constraint_object_id 
      = sys.foreign_keys.[object_id]) 
     inner join sys.objects 
     on (sys.objects.[object_id] 
      = sys.foreign_keys.parent_object_id) 
     inner join sys.columns 
      on (sys.columns.[object_id] 
      = sys.objects.[object_id]) 
      and (sys.columns.column_id 
      = sys.foreign_key_columns.parent_column_id) 
    ) ForeignKeys 
    on (ForeignKeys.referenced_object_id = sys.objects.[object_id]) 
    and (ForeignKeys.referenced_column_id = sys.columns.column_id) 
where (sys.objects.[type] = 'U') 
    and (sys.objects.[name] not in ('sysdiagrams')) 
+3

Questo è un inferno di un'utile istruzione di selezione. –

+0

Grazie, ha funzionato alla grande. – rball

+5

* Tear * thats ... so ... beautiful –

3

Dovrete per modificare la tabella, eliminare i vincoli FK e ricrearli:

Questa è la sintassi DB2. SQLServer dovrebbe essere simile

ALTER TABLE emp DROP CONSTRAINT fk_dept; 

ALTER TABLE emp ADD CONSTRAINT fk_dept 
FOREIGN KEY(dept_no) 
REFERENCES dept(deptno) 
ON DELETE CASCADE; 

È possibile scrivere il proprio sp per interrogare la tabella di sistema per tutte le chiavi esterne, farli cadere e ricreare. Dovrai usare sql dinamico nel tuo sp per fare ciò dove puoi fare un ciclo attraverso il defn fk, metterli in un varchar e aggiungere/modificare per includere CASCADE e quindi eseguire stmt.

0

creare una nuova stored procedure, in cui l'unico parametro è il nome della tabella da elaborare. In questa procedura, dovrai eseguire il loop su sys.foreign_keys e sys.foreign_key_columns per creare il drop appropriato e creare la sintassi, basta usare un cursore e alcune stampe (KISS).

chiamata di questa procedura con la sintassi:

EXEC sp_msforeachtable 'YourProcedureName ''?''' 

e verrà eseguito per ogni tabella. Prendi ed esegui l'output, e hai finito.

+0

Per fortuna tutti gli altri poi ha preso il tempo per suggerire _how_ questo potrebbe essere costruito. –

11

risposta di Andomar sopra è buona, ma lavora per una sola colonna solo vincoli di chiave esterna. Ho adattato un po 'per i vincoli a più colonne:

create function dbo.fk_columns (@constraint_object_id int) 
returns varchar(255) 
as begin 
declare @r varchar(255) 
select @r = coalesce(@r + ',', '') + c.name 
from sys.foreign_key_columns fkc 
join sys.columns c 
    on fkc.parent_object_id = c.object_id 
    and fkc.parent_column_id = c.column_id 
where fkc.constraint_object_id = @constraint_object_id 
return @r 
end 

select distinct 
    DropStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema + 
     '].[' + ForeignKeys.ForeignTableName + 
     '] DROP CONSTRAINT [' + ForeignKeys.ForeignKeyName + '] ' 
, CreateStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema + 
    '].[' + ForeignKeys.ForeignTableName + 
    '] WITH CHECK ADD CONSTRAINT [' + ForeignKeys.ForeignKeyName + 
    '] FOREIGN KEY(' + dbo.fk_columns(constraint_object_id) + ')' + 
    'REFERENCES [' + schema_name(sys.objects.schema_id) + '].[' + 
    sys.objects.[name] + '] ' 
    + ' ON DELETE CASCADE' 
from sys.objects 
    inner join sys.columns 
    on (sys.columns.[object_id] = sys.objects.[object_id]) 
    inner join (
select sys.foreign_keys.[name] as ForeignKeyName 
,schema_name(sys.objects.schema_id) as ForeignTableSchema 
,sys.objects.[name] as ForeignTableName 
,sys.columns.[name] as ForeignTableColumn 
,sys.foreign_keys.referenced_object_id as referenced_object_id 
,sys.foreign_key_columns.referenced_column_id as referenced_column_id 
,sys.foreign_keys.object_id as constraint_object_id 
from sys.foreign_keys 
    inner join sys.foreign_key_columns 
    on (sys.foreign_key_columns.constraint_object_id 
     = sys.foreign_keys.[object_id]) 
    inner join sys.objects 
    on (sys.objects.[object_id] 
     = sys.foreign_keys.parent_object_id) 
    inner join sys.columns 
     on (sys.columns.[object_id] 
     = sys.objects.[object_id]) 
     and (sys.columns.column_id 
     = sys.foreign_key_columns.parent_column_id) 
-- Uncomment this if you want to include only FKs that already 
-- have a cascade constraint. 
--  where (delete_referential_action_desc = 'CASCADE' or update_referential_action_desc = 'CASCADE') 
) ForeignKeys 
on (ForeignKeys.referenced_object_id = sys.objects.[object_id]) 
and (ForeignKeys.referenced_column_id = sys.columns.column_id) 
where (sys.objects.[type] = 'U') 
    and (sys.objects.[name] not in ('sysdiagrams')) 

È inoltre possibile utilizzare la query per aiutare a rimuovere ON DELETE CASCADE da FKS che attualmente hanno.

Questo continua a non gestire il caso in cui le colonne sono denominate cose diverse nelle due tabelle - un'altra funzione definita dall'utente dovrebbe essere definita per questo.

+0

Genio, puro genio. –

1

La risposta di @Andomar ha funzionato per me, ma era un po 'manuale - è necessario eseguirlo, quindi copiare i risultati ed eseguirli. Avevo bisogno di usarlo come parte del mio setup di test automatico, quindi avevo bisogno che fosse eseguito automaticamente in una query.

ho fornito con la seguente che ottiene tutta l'SQL per l'esecuzione al fine di modificare i vincoli di chiave esterna, quindi in realtà corre tutto d'un fiato:

IF Object_id('tempdb..#queriesForContraints') IS NOT NULL 
     BEGIN 
      DROP TABLE #queriesForContraints 
     END 

    DECLARE @ignoreTablesCommaSeparated VARCHAR(1000) 

    SELECT 'ALTER TABLE [' 
      + ForeignKeys.foreigntableschema + '].[' 
      + ForeignKeys.foreigntablename 
      + '] DROP CONSTRAINT [' 
      + ForeignKeys.foreignkeyname + ']; ' 
      + 'ALTER TABLE [' 
      + ForeignKeys.foreigntableschema + '].[' 
      + ForeignKeys.foreigntablename 
      + '] WITH CHECK ADD CONSTRAINT [' 
      + ForeignKeys.foreignkeyname 
      + '] FOREIGN KEY([' 
      + ForeignKeys.foreigntablecolumn 
      + ']) REFERENCES [' 
      + Schema_name(sys.objects.schema_id) + '].[' 
      + sys.objects.[name] + ']([' 
      + sys.columns.[name] 
      + ']) ON DELETE CASCADE; ' AS query 
    INTO #queriesForContraints 
    FROM sys.objects 
      INNER JOIN sys.columns 
        ON (sys.columns.[object_id] = sys.objects.[object_id]) 
      INNER JOIN (SELECT sys.foreign_keys.[name]      AS 
           ForeignKeyName, 
           Schema_name(sys.objects.schema_id)   AS 
        ForeignTableSchema, 
           sys.objects.[name]       AS 
        ForeignTableName, 
           sys.columns.[name]       AS 
        ForeignTableColumn, 
           sys.foreign_keys.referenced_object_id  AS 
        referenced_object_id, 
           sys.foreign_key_columns.referenced_column_id AS 
        referenced_column_id 
         FROM sys.foreign_keys 
           INNER JOIN sys.foreign_key_columns 
             ON ( 
           sys.foreign_key_columns.constraint_object_id = 
           sys.foreign_keys.[object_id]) 
           INNER JOIN sys.objects 
             ON (sys.objects.[object_id] = 
             sys.foreign_keys.parent_object_id) 
           INNER JOIN sys.columns 
             ON (sys.columns.[object_id] = 
              sys.objects.[object_id]) 
             AND (sys.columns.column_id = 
    sys.foreign_key_columns.parent_column_id)) 
    ForeignKeys 
    ON (ForeignKeys.referenced_object_id = sys.objects.[object_id]) 
    AND (ForeignKeys.referenced_column_id = sys.columns.column_id) 
    WHERE (sys.objects.[type] = 'U') 
      AND (sys.objects.[name] NOT IN ( 
       'sysdiagrams' --add more comma separated table names here if required 
      )) 

    DECLARE @queryToRun NVARCHAR(MAX) 

    SELECT @queryToRun = STUFF(
      (SELECT query + '' 
      FROM #queriesForContraints 
      FOR XML PATH ('')) 
     , 1, 0, '') 

    EXEC sp_executesql @statement = @queryToRun 

    IF Object_id('tempdb..#queriesForContraints') IS NOT NULL 
     BEGIN 
      DROP TABLE #queriesForContraints 
     END 
4

Più Standards soluzione conforme:

;WITH CTE AS 
(
    SELECT 
     KCU1.CONSTRAINT_NAME AS FK_CONSTRAINT_NAME 
     ,KCU1.TABLE_SCHEMA AS FK_SCHEMA_NAME 
     ,KCU1.TABLE_NAME AS FK_TABLE_NAME 
     ,KCU1.COLUMN_NAME AS FK_COLUMN_NAME 
     ,KCU1.ORDINAL_POSITION AS FK_ORDINAL_POSITION 
     ,KCU2.CONSTRAINT_NAME AS REFERENCED_CONSTRAINT_NAME 
     ,KCU2.TABLE_SCHEMA AS REFERENCED_SCHEMA_NAME 
     ,KCU2.TABLE_NAME AS REFERENCED_TABLE_NAME 
     ,KCU2.COLUMN_NAME AS REFERENCED_COLUMN_NAME 
     ,KCU2.ORDINAL_POSITION AS REFERENCED_ORDINAL_POSITION 
    FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC 

    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU1 
     ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG 
     AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA 
     AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME 

    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU2 
     ON KCU2.CONSTRAINT_CATALOG = RC.UNIQUE_CONSTRAINT_CATALOG 
     AND KCU2.CONSTRAINT_SCHEMA = RC.UNIQUE_CONSTRAINT_SCHEMA 
     AND KCU2.CONSTRAINT_NAME = RC.UNIQUE_CONSTRAINT_NAME 
     AND KCU2.ORDINAL_POSITION = KCU1.ORDINAL_POSITION 
) 


SELECT 
    FK_CONSTRAINT_NAME 
    --,FK_SCHEMA_NAME 
    --,FK_TABLE_NAME 
    --,FK_COLUMN_NAME 
    --,FK_ORDINAL_POSITION 
    --,REFERENCED_CONSTRAINT_NAME 
    --,REFERENCED_SCHEMA_NAME 
    --,REFERENCED_TABLE_NAME 
    --,REFERENCED_COLUMN_NAME 
    --,REFERENCED_ORDINAL_POSITION 

    , 
     'ALTER TABLE [' + FK_SCHEMA_NAME + ']' 
     + '.[' + FK_TABLE_NAME + '] ' 
     + 'DROP CONSTRAINT [' + FK_CONSTRAINT_NAME + ']; ' 
    AS DropStmt 

    , 
    'ALTER TABLE [' + FK_SCHEMA_NAME + ']' 
     + '.[' + FK_TABLE_NAME + '] ' + 
     + 'WITH CHECK ADD CONSTRAINT [' + FK_CONSTRAINT_NAME + '] ' 
     + 'FOREIGN KEY([' + FK_COLUMN_NAME + ']) ' 
     + 'REFERENCES [' + REFERENCED_SCHEMA_NAME + '].[' + REFERENCED_TABLE_NAME + ']([' + REFERENCED_COLUMN_NAME + ']) ON DELETE CASCADE; ' 
    AS CreateStmt 

FROM CTE 

WHERE (1=1) 
/* 
AND FK_TABLE_NAME IN 
(
    'T_SYS_Geschossrechte' 
    ,'T_SYS_Gebaeuderechte' 
    ,'T_SYS_Standortrechte' 
) 

AND REFERENCED_TABLE_NAME NOT LIKE 'T_AP_Ref_Mandant' 
*/ 

ORDER BY 
    FK_TABLE_NAME 
    ,FK_CONSTRAINT_NAME 
    ,FK_COLUMN_NAME 
    ,FK_ORDINAL_POSITION 
    ,REFERENCED_CONSTRAINT_NAME 
    ,REFERENCED_TABLE_NAME 
    ,REFERENCED_COLUMN_NAME 
    ,REFERENCED_ORDINAL_POSITION 

Edit:
estesa per stranieri-keys a più colonne:

;WITH CTE AS 
( 
    SELECT 
     KCU1.CONSTRAINT_NAME AS FK_CONSTRAINT_NAME 
     ,KCU1.TABLE_SCHEMA AS FK_SCHEMA_NAME 
     ,KCU1.TABLE_NAME AS FK_TABLE_NAME 
     ,KCU1.COLUMN_NAME AS FK_COLUMN_NAME 
     ,KCU1.ORDINAL_POSITION AS FK_ORDINAL_POSITION 
     ,KCU2.CONSTRAINT_NAME AS REFERENCED_CONSTRAINT_NAME 
     ,KCU2.TABLE_SCHEMA AS REFERENCED_SCHEMA_NAME 
     ,KCU2.TABLE_NAME AS REFERENCED_TABLE_NAME 
     ,KCU2.COLUMN_NAME AS REFERENCED_COLUMN_NAME 
     ,KCU2.ORDINAL_POSITION AS REFERENCED_ORDINAL_POSITION 
    FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC 

    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU1 
     ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG 
     AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA 
     AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME 

    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU2 
     ON KCU2.CONSTRAINT_CATALOG = RC.UNIQUE_CONSTRAINT_CATALOG 
     AND KCU2.CONSTRAINT_SCHEMA = RC.UNIQUE_CONSTRAINT_SCHEMA 
     AND KCU2.CONSTRAINT_NAME = RC.UNIQUE_CONSTRAINT_NAME 
     AND KCU2.ORDINAL_POSITION = KCU1.ORDINAL_POSITION 
) 
SELECT 
    FK_SCHEMA_NAME 
    ,FK_TABLE_NAME 
    ,FK_CONSTRAINT_NAME 
    --,FK_COLUMN_NAME 
    --,REFERENCED_COLUMN_NAME 



    , 
    'ALTER TABLE ' + QUOTENAME(FK_SCHEMA_NAME) + '.' + QUOTENAME(FK_TABLE_NAME) + ' ' 
     + 'DROP CONSTRAINT ' + QUOTENAME(FK_CONSTRAINT_NAME) + '; ' 
    AS DropStmt 

    , 
    'ALTER TABLE ' + QUOTENAME(FK_SCHEMA_NAME) + '.' + QUOTENAME(FK_TABLE_NAME) + ' 
    ADD CONSTRAINT ' + QUOTENAME(FK_CONSTRAINT_NAME) + ' 
    FOREIGN KEY(' 
    + 
     SUBSTRING 
     ( 
      (
       SELECT ', ' + QUOTENAME(FK.FK_COLUMN_NAME) AS [text()] 
       FROM CTE AS FK 
       WHERE FK.FK_CONSTRAINT_NAME = CTE.FK_CONSTRAINT_NAME 
       AND FK.FK_SCHEMA_NAME = CTE.FK_SCHEMA_NAME 
       AND FK.FK_TABLE_NAME = CTE.FK_TABLE_NAME 
       FOR XML PATH, TYPE 
      ).value('.[1]', 'nvarchar(MAX)') 
      ,3, 4000 
     ) 
    + ') 
' 
    + ' REFERENCES ' + QUOTENAME(REFERENCED_SCHEMA_NAME) + '.' + QUOTENAME(REFERENCED_TABLE_NAME) + '(' 
    + SUBSTRING 
     ( 
      (
       SELECT ', ' + QUOTENAME(Referenced.REFERENCED_COLUMN_NAME) AS [text()] 
       FROM CTE AS Referenced 
       WHERE Referenced.FK_CONSTRAINT_NAME = CTE.FK_CONSTRAINT_NAME 
       AND Referenced.REFERENCED_SCHEMA_NAME = CTE.REFERENCED_SCHEMA_NAME 
       AND Referenced.REFERENCED_TABLE_NAME = CTE.REFERENCED_TABLE_NAME 
       FOR XML PATH, TYPE 
     ).value('.[1]', 'nvarchar(MAX)') 
      , 3, 4000 
    ) 
    + ') 
    ON DELETE CASCADE 
; ' AS CreateStmt 

FROM CTE 

GROUP BY 
    FK_SCHEMA_NAME 
    ,FK_TABLE_NAME 
    ,FK_CONSTRAINT_NAME 

    ,REFERENCED_SCHEMA_NAME 
    ,REFERENCED_TABLE_NAME 

E la versione molto più semplice per PostgreSQL:

;WITH CTE AS 
( 
    SELECT 
     KCU1.CONSTRAINT_NAME AS FK_CONSTRAINT_NAME 
     ,KCU1.TABLE_SCHEMA AS FK_SCHEMA_NAME 
     ,KCU1.TABLE_NAME AS FK_TABLE_NAME 
     ,KCU1.COLUMN_NAME AS FK_COLUMN_NAME 
     ,KCU1.ORDINAL_POSITION AS FK_ORDINAL_POSITION 
     ,KCU2.CONSTRAINT_NAME AS REFERENCED_CONSTRAINT_NAME 
     ,KCU2.TABLE_SCHEMA AS REFERENCED_SCHEMA_NAME 
     ,KCU2.TABLE_NAME AS REFERENCED_TABLE_NAME 
     ,KCU2.COLUMN_NAME AS REFERENCED_COLUMN_NAME 
     ,KCU2.ORDINAL_POSITION AS REFERENCED_ORDINAL_POSITION 
    FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC 

    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU1 
     ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG 
     AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA 
     AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME 

    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU2 
     ON KCU2.CONSTRAINT_CATALOG = RC.UNIQUE_CONSTRAINT_CATALOG 
     AND KCU2.CONSTRAINT_SCHEMA = RC.UNIQUE_CONSTRAINT_SCHEMA 
     AND KCU2.CONSTRAINT_NAME = RC.UNIQUE_CONSTRAINT_NAME 
     AND KCU2.ORDINAL_POSITION = KCU1.ORDINAL_POSITION 
) 
SELECT 
    FK_SCHEMA_NAME 
    ,FK_TABLE_NAME 
    ,FK_CONSTRAINT_NAME 
    --,FK_COLUMN_NAME 
    --,REFERENCED_COLUMN_NAME 



    , 
    'ALTER TABLE ' || QUOTE_IDENT(FK_SCHEMA_NAME) || '.' || QUOTE_IDENT(FK_TABLE_NAME) || ' ' 
     || 'DROP CONSTRAINT ' || QUOTE_IDENT(FK_CONSTRAINT_NAME) || '; ' 
    AS DropStmt 

    , 
    'ALTER TABLE ' || QUOTE_IDENT(FK_SCHEMA_NAME) || '.' || QUOTE_IDENT(FK_TABLE_NAME) || ' 
    ADD CONSTRAINT ' || QUOTE_IDENT(FK_CONSTRAINT_NAME) || ' 
    FOREIGN KEY(' || string_agg(FK_COLUMN_NAME, ', ') || ') 
' 
    || ' REFERENCES ' || QUOTE_IDENT(REFERENCED_SCHEMA_NAME) || '.' || QUOTE_IDENT(REFERENCED_TABLE_NAME) || '(' || string_agg(REFERENCED_COLUMN_NAME, ', ') || ') 
    ON DELETE CASCADE 
; ' AS CreateStmt 

FROM CTE 

GROUP BY 
    FK_SCHEMA_NAME 
    ,FK_TABLE_NAME 
    ,FK_CONSTRAINT_NAME 

    ,REFERENCED_SCHEMA_NAME 
    ,REFERENCED_TABLE_NAME 
+0

ha mosso in su per la sintassi _wayyy_ nicer (vale a dire effettivamente leggibile) rispetto alle mostruose mostruosità nested -selezionate ', non ANSI sopra. Tuttavia, anche questo non gestisce i tasti compositi: ci fornisce ─ istruzioni separate 'aggiungi vincolo' per ogni colonna membro, piuttosto che il corretto' nomeTabella (lista, di, colonne) '. Uso le chiavi composite. Quindi, la mia prossima missione è prendere il tuo copione e sistemarlo per adattarlo. Se lo faccio, ti farò sapere! –

+0

@underscore_d: su PostGre, puoi eseguire il raggruppamento in base a FK_SCHEMA_Name, FK_TABLE_NAME, FK_COLUMN_NAME e quindi string_agg (FK_COLUMN_NAME, ','); su SQL-server, è necessario aggiungere l'aggregazione di stringhe come funzione CLR, oppure diventa molto più brutto con il percorso XML ... –

+0

@underscore_d: Multi-Column ora supportato. Non riesco ancora a capire perché qualcuno abbia bisogno di chiavi esterne a più colonne, anche se (dato che possono fare riferimento solo a una tabella, non a più tabelle, altrimenti avrebbe senso). –

Problemi correlati