Abbiamo affrontato una situazione in cui abbiamo bisogno di trasformare i dati da una tabella in altri durante la distribuzione del progetto di database. Ovviamente è un problema utilizzare il progetto DB a causa della pre-distribuzione che la tabella di destinazione (colonna) non esiste ancora, ma nello script post-distribuzione la tabella di origine (colonna) è già assente.
per trasformare i dati da Tabella A a TableB abbiamo usato la seguente idea (Questo approccio può essere utilizzato per qualsiasi modifica dei dati):
- Developer aggiunge tabella di destinazione (dbo.TabellaB) nel progetto DB e distribuirlo sul DB locale (senza impegnarsi in un SVN)
- Lui o lei crea uno script di trasformazione pre-distribuzione. Il trucco è che lo script inserisce i dati dei risultati in una tabella temporanea: #TabellaB
- Lo sviluppatore elimina il dbo.TableA nel progetto DB. Si presume che la tabella verrà eliminata durante l'esecuzione dello script generato principale.
- Lo sviluppatore scrive uno script post-distribuzione che copia il modulo dati #TableB in dbo.TableB appena creato dallo script principale.
- Tutte le modifiche vengono confermate in SVN.
In questo modo non è necessario lo script di pre-distribuzione perché archiviamo i dati intermedi nella tabella temporanea.
Vorrei dire che l'approccio che utilizza lo script di pre-distribuzione ha gli stessi dati intermedi (temporanei), tuttavia è archiviato non in tabelle temporanee ma in tabelle reali. Accade tra pre-pre-distribuzione e pre-distribuzione. Dopo l'esecuzione dello script di pre-distribuzione, questi dati intermedi scompaiono.
Per di più, l'approccio con l'utilizzo di tabelle temporanee ci permette di affrontare la seguente situazione complicata ma reale: Immaginiamo che abbiamo due trasformazioni nel nostro progetto DB:
- TableA -> TableB
- TableB -> TableC
a parte che abbiamo due banche dati:
- DatabaeA che hanno il TableA
- DatabaeB in cui il TableA è già stato trasformato in TableB. Il TableA è assente nel DatabaseB.
Tuttavia possiamo affrontare questa situazione. Abbiamo bisogno solo di una nuova azione nella pre-distribuzione. Prima della trasformazione, proviamo a copiare i dati dal dbo.TableA in #TableA. E lo script di trasformazione funziona solo con tabelle temporanee.
Lascia che ti mostri come funziona questa idea in DatabaseA e DatabaseB. Si presume che il progetto DB abbia due coppie di script pre e post distribuzione: "TabellaA -> TabellaB" e "TabellaB -> TabellaC".
Di seguito è riportato l'esempio degli script per la trasformazione "TabellaB -> TabellaC".
pre-distribuzione di script script di
----[The data preparation block]---
--We must prepare to possible transformation
--The condition should verufy the existance of necessary columns
IF OBJECT_ID('dbo.TableB') IS NOT NULL AND
OBJECT_ID('tempdb..#TableB') IS NULL
BEGIN
CREATE TABLE #TableB
(
[Id] INT NOT NULL PRIMARY KEY,
[Value1] VARCHAR(50) NULL,
[Value2] VARCHAR(50) NULL
)
INSERT INTO [#TableB]
SELECT [Id], [Value1], [Value2]
FROM dbo.TableB
END
----[The data transformation block]---
--The condition of the transformation start
--It is very important. It must be as strict as posible to ward off wrong executions.
--The condition should verufy the existance of necessary columns
--Note that the condition and the transformation must use the #TableA instead of dbo.TableA
IF OBJECT_ID('tempdb..#TableB') IS NOT NULL
BEGIN
CREATE TABLE [#TableC]
(
[Id] INT NOT NULL PRIMARY KEY,
[Value] VARCHAR(50) NULL
)
--Data transformation. The source and destimation tables must be temporary tables.
INSERT INTO [#TableC]
SELECT [Id], Value1 + ' '+ Value2 as Value
FROM [#TableB]
END
post-distribuzione
Nel DatabaseA lo script di pre-distribuzione ha già creato il #TableA. Pertanto il blocco di preparazione dei dati non verrà eseguito a causa della mancanza di dbo.TableB nel database. Tuttavia la trasformazione dei dati verrà eseguita perché c'è il #TableA nel database che è stato creato dal blocco di trasformazione di "TableA -> TableB".
Nel DatabaseB i blocchi di preparazione e trasformazione dei dati per lo script "TabellaA -> TabellaB" non verranno eseguiti. Tuttavia abbiamo già i dati trasformati nel dbo.TableB. Quindi i blocchi di preparazione e trasformazione dei dati per "TableB -> TableC" verranno eseguiti senza alcun problema.
I nomi devono essere gestiti in modo nativo se si utilizza la funzione Refactor. Anche le tabelle che cadono sono supportate nel progetto. Tuttavia, il suggerimento di Ed è valido per le volte in cui la funzionalità nativa non funzionerà. Che cosa stai cercando di eliminare/rinominare/eseguire ciò che deve essere fatto prima della comparazione dello schema? –
In questo caso particolare, sto facendo cadere una chiave esterna modificando la colonna FK da BIGINT a INT e puntando l'FK su una tabella diversa che viene a sua volta rielaborata. La distribuzione fallisce la prima esecuzione perché il confronto degli schemi viene eseguito prima di queste modifiche. Si schiera alla seconda manche. – Metaphor