stanęliśmy sytuacji, kiedy musimy przekształcić dane z jednej tabeli w inne podczas wdrażania projektu bazy danych. Oczywiście problemem jest korzystanie z projektu bazy danych, ponieważ w fazie przedinstalacyjnej tabela docelowa (kolumna) nadal nie istnieje, ale w skrypcie po wdrożeniu tabela źródłowa (kolumna) jest już nieobecna.
Aby przekształcić dane z TableA do TableB użyliśmy następujące pojęcia (To podejście może być stosowany do wszelkich modyfikacji danych):
- Developer dodaje tabeli docelowej (dbo.Tabela B) do projektu DB i wdraża go w lokalnej bazie danych (bez wykonywania usługi SVN).
- Tworzy skrypt transformacji przed rozmieszczeniem. Sztuczka polega na tym, że skrypt umieścił dane wynikowe w tabeli tymczasowej: #TableB
- Deweloper usuwa dbo.TableA w projekcie DB. Zakłada się, że tabela zostanie usunięta podczas wykonywania głównego wygenerowanego skryptu.
- Deweloper pisze skrypt po wdrożeniu, który kopiuje formularz danych # TableB do dbo.TableB, który został właśnie utworzony przez główny skrypt.
- Wszystkie zmiany zostały zatwierdzone w SVN.
W ten sposób nie potrzebujemy skryptu sprzed złożenia, ponieważ przechowujemy dane pośrednie w tabeli tymczasowej.
Chciałbym powiedzieć, że podejście, które używa skryptu sprzed złożenia wstępnego, zawierało te same dane pośrednie (tymczasowe), jednak nie jest przechowywane w tabelach tymczasowych, ale w rzeczywistych tabelach. Dzieje się to między wstępnym wdrożeniem a wstępnym wdrożeniem. Po wykonaniu skryptu pre-deployment dane pośrednie znikają.
Co więcej, podejście z wykorzystaniem tabel tymczasowych pozwala nam zmierzyć się następujące skomplikowany ale rzeczywistą sytuację: Wyobraźmy sobie, że mamy dwie przemiany w naszym projekcie DB:
- TABLEA -> TableB
- TableB -> TableC
Oprócz tego mamy dwie bazy danych:
- DatabaeA, które mają tablicę danych, gdzie Tabela A została już przekształcona w TableB. Tabela A jest nieobecna w DatabaseB.
Mimo to możemy poradzić sobie z taką sytuacją. Potrzebujemy tylko jednej nowej akcji przed rozmieszczeniem. Przed transformacją próbujemy skopiować dane z dbo.TableA do #TableA. A skrypt transformacji działa tylko z tabelami tymczasowymi.
Pozwól mi pokazać, jak ten pomysł działa w DatabaseA i DatabaseB. Zakłada się, że projekt DB ma dwie pary skryptów przed i po instalacji: "TableA -> TableB" i "TableB -> TableC".
Poniżej znajduje się przykład skryptów dla transformacji "TableB -> TableC".
przedwdrożeniowa skrypt skrypt
----[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
po wysunięciu
W DatabaseA skrypt pre-rozmieszczenia już stworzył #TableA. Dlatego blok przygotowania danych nie zostanie wykonany, ponieważ w bazie danych nie ma dbo.TableB. Jednak transformacja danych zostanie wykonana, ponieważ istnieje #TableA w bazie danych, która została utworzona przez blok transformacji "TableA -> TableB".
W DatabaseB bloki przygotowania i transformacji danych dla skryptu "TableA -> TableB" nie zostaną wykonane. Jednak mamy już przekształcone dane w dbo.TableB. W związku z tym bloki przygotowania i transformacji danych dla "TableB -> TableC" zostaną wykonane bez żadnego problemu.
Zmiana nazwy powinna odbywać się w trybie natywnym, jeśli używana jest funkcja Refactor. Zrzucanie tabel jest również obsługiwane w projekcie. Jednak sugestia Ed jest ważna w czasach, gdy natywna funkcjonalność nie będzie działać. Co próbujesz upuścić/zmienić nazwę/osiągnąć, co należy zrobić przed porównaniem schematu? –
W tym konkretnym przypadku upuszczam klucz obcy zmieniający kolumnę FK z BIGINT na INT i wskazując FK na inną tabelę, która sama jest ponownie uwzględniana. Wdrożenie nie powiedzie się po pierwszym uruchomieniu, ponieważ porównywanie schematu jest wykonywane przed tymi zmianami. Rozmieszcza się przy drugim uruchomieniu. – Metaphor