2010-03-09 11 views
10

Sulla tabella "A" dipendono da altre 30 tabelle tramite FK a "A.Id".SQL Server: Drop Table con FK

Per il test di integrazione devo rilasciare la tabella e ricrearla per creare uno stato definito. A causa degli oggetti dipendenti, sembra che non sia possibile eliminare e ricreare la tabella. Il messaggio di errore è:

Impossibile eliminare oggetto 'dbo.A' perché fa riferimento a un FOREIGN vincolo KEY

Question (s):

  • Come posso eliminare e ricreare la tabella "A"?
  • (o) c'è un modo per disattivare le dipendenze dello schema a livello globale?
  • (o) esiste un modo per eseguire il backup (tutto!) Delle dipendenze prima di eliminare e ripristinare la tabella "A" e ripristinare tutte le dipendenze in seguito?
+0

Perché non si utilizza un DB separato per i test di integrazione in cui l'intero stato viene generato da zero ogni volta? – dbemerlin

+0

Il database è solo grande (alcune centinaia di tabelle con molti oggetti dipendenti). In questo modo, ogni test di integrazione richiederebbe circa 45 secondi + x solo per il tempo di avvio e senza alcun test effettivo. Inoltre alcune tabelle contengono dati. (Il dump del database totale senza dati personalizzati è di circa 35 MB). Avremo _many_test di integrazione, che vogliamo eseguire ad ogni check in, usando il server di integrazione. – Robert

+0

ogni stato di integrazione richiede lo stesso stato iniziale del DB, oppure è possibile pagare la penalità di avvio una volta e fare in modo che ogni test annulli le modifiche transitori che potrebbe aver apportato allo stato? – Mikeb

risposta

3

Passare al database in SSMS e fare clic con il tasto destro del mouse. Scegli le attività, genera script. Quindi passa attraverso le opzioni e impostale nel modo desiderato (Probaly sceglie solo le chiavi esterne nella tabella e crea oggetti dipendenti e rilascia e ricrea, non ha le opzioni di fronte a me ma le vedrai.Quindi scegliere le tabelle per cui si desidera scrivere gli FK e copiarle su un file. Aprire il file e separare le istruzioni di rilascio in un file e creare le impostazioni in un altro. Ora hai tweo file che puoi eseguire fai automaticamente ciò che vuoi quando esegui un test. Suggerirei di ricreare i file prima di eseguire il primo test (nel caso in cui siano stati modificati dall'ultima esecuzione dei test), ma non per ogni singolo test.

+0

Grazie, sono molto grato. Questo è ciò che ha funzionato meglio per me! – Robert

4

In Management Studio, è possibile fare clic con il tasto destro del mouse sulla tabella e creare il comando CREATE e il DROP che includerà tutte le chiavi esterne.


Per essere più specifici, questo fornirà tutti i vincoli da cui dipende la tabella. Tuttavia, non ti fornisce l'elenco delle chiavi esterne che dipendono da questa tabella. Quindi, oltre agli script che genereresti facendo clic con il pulsante destro del mouse sulla tabella in SMS, devi trovare e scrivere tutte le chiavi esterne. Per ottenere una lista di loro, è possibile eseguire una query in questo modo:

select FKConstraint.TABLE_NAME, FKConstraint.CONSTRAINT_NAME 
from INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS 
    Join INFORMATION_SCHEMA.TABLE_CONSTRAINTS As UniqueConstraint 
     On UniqueConstraint.CONSTRAINT_NAME = INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS.UNIQUE_CONSTRAINT_NAME 
    Join INFORMATION_SCHEMA.TABLE_CONSTRAINTS As FKConstraint 
     On FKConstraint.CONSTRAINT_NAME = INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS.CONSTRAINT_NAME   
Where UniqueConstraint.TABLE_NAME = 'TableA' 

Per ognuno di questi, è necessario creare script and drop. Dovresti aggiungere le gocce all'inizio del tuo script di rilascio e le creazioni alla fine del tuo script di creazione.

+0

Questo non contiene le dipendenze di riferimento, che sono il problema. – Robert

+1

Cosa intendi? SMS creerà uno script che lascerà cadere tutte le chiavi esterne alla tabella e quindi, alla fine, farà cadere la tabella. Inoltre, la creazione creerà tutte le chiavi esterne. – Thomas

+0

Hmm, ho provato questo .. e ho ottenuto uno script con molti: "SE ESISTE (SELEZIONA * DA sys.check_constraints DOVE" ... ma quando lo eseguo, ottengo ancora: "Impossibile rilasciare l'oggetto" dbo.A 'perché è referenziato da un vincolo FOREIGN KEY. "Questo è davvero, davvero strano! – Robert

2

Espandere la tabella in Sql Server Management Studio, espandere la cartella Constraints.

Annota tutti i vincoli che hai in modo da poterli ricreare. Elimina i vincoli e rilascia la tabella. Ricrea la tabella e ricrea i tuoi vincoli.

+0

Ho pensato anche a questo, ma dato che molte tabelle hanno molti vincoli e dipendenze, questo sarà molto lavoro. (E molto lavoro è, quello che cerco di evitare :-)) – Robert

+0

Sì, vorrei che Mircosoft rendere più facile l'esecuzione di questo compito. Ogni volta che devo farlo, mi lamento rumorosamente. ;-) –

2

Utilizzare la transazione. Alla fine del test - rollback.

+0

Bella idea, ma non riesco ad ottenere la connessione SQL - quindi non c'è modo di controllare la transazione (?). – Robert

5

Esplora la tabella di sistema sys.foreign_key_columns. Ecco un esempio che avevo, che in giro che la volontà, dato un tavolo, si dice che di essa la colonne sono calettati per un altro tavolo:

DECLARE @tableName VARCHAR(255) 
SET @tableName = 'YourTableName' 

SELECT OBJECT_NAME(fkc.constraint_object_id) AS 'FKName', OBJECT_NAME(fkc.[referenced_object_id]) AS 'FKTable', c2.[name] AS 'FKTableColumn', @tableName AS 'Table', c1.[name] AS 'TableColumn' 
    FROM sys.foreign_key_columns as fkc 
     JOIN sys.columns AS c1 ON c1.[object_id] = fkc.[parent_object_id] AND c1.[column_id] = fkc.[parent_column_id] 
     JOIN sys.columns AS c2 ON c2.[object_id] = fkc.[referenced_object_id] AND c2.[column_id] = fkc.[referenced_column_id] 
    WHERE fkc.[parent_object_id] = OBJECT_ID(@tableName) 
    ORDER BY OBJECT_NAME(fkc.constraint_object_id) 

Con questo, o qualche variazione là-di, si potrebbe scoprire la straniera chiavi, rilasciali, fai le tue cose e poi ricrea le chiavi esterne.

Devo aggiungere che so che questo funziona su SQL2005 e SQL2008. Non so davvero se funzionerà su SQL2000/MSDE.

0

Forse prendere in considerazione la possibilità di mantenere un server virtuale con il database nella sua impostazione di test di inizializzazione. Avviare la VM, eseguire i test, quindi eliminare la VM modificata.

+0

Immagino che il ripristino del database sia più rapido del ripristino di una VM. – Robert

+0

No, non c'è alcun ripristino. Ci vorrebbe un minuto o due per avviare la VM quando lo volevi, tutto qui. –