Ostatnio uczestniczyłem w przenoszeniu bazy z SQL 2008 na SQL 2005. Proste backup i restore w tym przypadku nie zadziała. Do przeniesienia struktury wykorzystałem narzędzie GENERATE SCRIPTS, a do transferu danych EXPORT DATA.
Cały proces przeszedł bez problemu... (tak mi się tylko wydawało).
Napotkałem w sumie na dwa problemy. Pierwszy polegał na tym, że niektóre obiekty, głównie klucze i defaulty. W tych miejscach gdzie te obiekty nie miały nadanej konkretnej nazwy, a została ona wygenerowana przez SQL serwer (dostaje ona wtedy dziwny numerek na końcu nazwy), na nowym serwerze nazwa ta też została wygenerowana. Czyli na kolumnie była zdefiniowana wartość domyślna ale constraint miał inny numerek w nazwie.
Drugi problem polegał na przeniesieniu danych. Okazało się, że nie przeniosły się one jeden w jeden. W moim przypadki problem był w kolumnach, które miały ustawioną wartość domyślną, ale dopuszczały NULL. Jeżeli na bazie źródłowej w kolumnie takiej był NULL to w bazie docelowej w tym samym polu pojawiła się wartość domyślna.
Napisałem skrypciorka, który pokazał mi w jakich tabelach zmieniły się dane.
USE ADVENTUREWORKSLT2008; -- DEKLARACJA ZMIENNYCH DECLARE @TABLE_ID INT -- ID TABELI , @TABLE_NAME VARCHAR(50) -- NAZWA TABELI , @SCHEMA_NAME VARCHAR(50) -- NAZWA SCHEMATU , @COLUMN_NAME VARCHAR(MAX) -- NAZWY KOLUMN , @S_SERVER_NAME VARCHAR(100) -- SERWER ŹRÓDŁOWY , @D_SERVER_NAME VARCHAR(100) -- SERWER DOCELOWY , @S_DB_NAME VARCHAR(100) -- BAZA ŹRÓDŁOWA , @D_DB_NAME VARCHAR(100) -- BAZA DOCELOWA , @MYSQL VARCHAR(MAX) , @MYSQL_EXT VARCHAR(MAX); -- PRZYPISANIE WARTOŚCI ZMIENNYM SET @S_SERVER_NAME = '[SQL2008]'; SET @D_SERVER_NAME = '[SQL2005]'; SET @S_DB_NAME = 'ADVENTUREWORKSLT2008'; SET @D_DB_NAME = 'ADVENTUREWORKSLT2005'; DECLARE TABLE_CURSOR CURSOR FOR -- DEKLARACJA KURSORA DO POBIERANIA INFORMACJI O TABELACH SELECT [OBJECT_ID] , SCHEMA_NAME(SCHEMA_ID) AS SCH_NAME , NAME FROM SYS.TABLES ORDER BY NAME ASC; OPEN TABLE_CURSOR; FETCH NEXT FROM TABLE_CURSOR INTO @TABLE_ID , @SCHEMA_NAME , @TABLE_NAME; WHILE @@FETCH_STATUS = 0 BEGIN SET @COLUMN_NAME = ''; SET @MYSQL = ''; SET @MYSQL_EXT = ''; -- ZŁOŻENIE KOLUMN TABELI SELECT @COLUMN_NAME = @COLUMN_NAME + ',[' + C.NAME + ']' FROM SYS.COLUMNS AS C INNER JOIN SYS.TYPES AS T ON C.SYSTEM_TYPE_ID = T.SYSTEM_TYPE_ID WHERE C.[OBJECT_ID] = @TABLE_ID AND T.NAME NOT IN ('IMAGE', 'TEXT', 'NTEXT', 'XML') -- NIE WSZYSTKIE DANE ZA POMOCĄ EXCEPT DA SIĘ PORÓWNAĆ ORDER BY C.COLUMN_ID ASC; SET @COLUMN_NAME = STUFF(@COLUMN_NAME, 1, 1, '') -- USUNIĘCIE PRZECINKA Z POCZĄTKU STRINGA -- ZŁOŻENIE ZAPYTANIE SET @MYSQL_EXT = @SCHEMA_NAME + '.' + @TABLE_NAME; SET @MYSQL = 'SELECT ' + @COLUMN_NAME + ' FROM ' + @S_SERVER_NAME + '.' + @S_DB_NAME + '.' + @SCHEMA_NAME + '.' + @TABLE_NAME + ' EXCEPT ' + 'SELECT ' + @COLUMN_NAME + ' FROM ' + @D_SERVER_NAME + '.' + @D_DB_NAME + '.' + @SCHEMA_NAME + '.' + @TABLE_NAME; EXEC ('SELECT ''' + @MYSQL_EXT + '''') -- TABELA ANALIZOWANA EXEC (@MYSQL); -- ANALIZA DANYCH FETCH NEXT FROM TABLE_CURSOR INTO @TABLE_ID , @SCHEMA_NAME , @TABLE_NAME; END CLOSE TABLE_CURSOR; DEALLOCATE TABLE_CURSOR;
Aby nie mieć problemów z wartościami NULL w kolumnach z wartością domyślną nie należy generować ich za pomocą GENERATE SCRIPTS przed wstawieniem danych.
Co do pierwszego problemu to obejścia dalej szukam. ;))
Brak komentarzy:
Prześlij komentarz