2012-09-18 16 views
11

Mam bazę danych SQL Server 2008, którą chcę skopiować i utworzyć nową bazę danych (z inną nazwą) na serwerze z. Nie dbam o utrzymanie danych, nowa baza danych może zostać utworzona bez danych dla starterów. Co szukam zrobić, jest następujący:skopiuj bazę danych SQL Server 2008 i zmień jej nazwę na

  • Utwórz nową bazę danych zachowując strukturę starej bazy danych
  • Ustaw nazwę nowej bazy danych
  • zmienić wszystkie varchar i char datatypes do nvarchar i nchar
  • Zmień wszystkie typy danych tekstowych do nvarchar (max)

Tak na marginesie, mam 2 więcej pytań, które nie są częścią mojego zadania, ale chciałby, aby rozważyć następujące kwestie:

  • Jak mogę uaktualnić bazę danych serwera SQL SQL Server 2012
  • Czy istnieją jakieś prace przygotowawcze muszę przeprowadzić na bazie danych, aby upewnić się, można łatwo uaktualnić go?

Odpowiedz

29

To naprawdę jest połączenie wielu pytań.


pytania 1 i 2

  • Utwórz nową bazę danych zachowując strukturę starej bazy danych
  • Ustaw nazwę nowej bazy danych

Najprostszym zapasowej komenda byłaby:

BACKUP DATABASE dbname TO DISK = 'C:\some folder\dbname.bak' WITH INIT; 
-- or WITH INIT, COMPRESSION if you are on Enterprise or Developer 

Teraz, aby przywrócić to jako inną bazę danych, musisz znać nazwy plików, ponieważ spróbuje umieścić te same pliki w tym samym miejscu.Więc jeśli uruchomić następujące:

EXEC dbname.dbo.sp_helpfile; 

Powinieneś zobaczyć wyjście zawierający nazwy i ścieżki danych i plików dziennika. Kiedy tworzymy przywrócić, trzeba z nich korzystać, ale zastąpić ścieżki z nazwą nowej bazy danych, np:

RESTORE DATABASE newname FROM DISK = 'C:\some folder\dbname.bak' 
    WITH MOVE 'dbname' TO 'C:\path_from_sp_helpfile_output\newname_data.mdf', 
    MOVE 'dbname_log' TO 'C:\path_from_sp_helpfile_output\newname_log.ldf'; 

Będziesz musiał zastąpić dbname i newname rzeczywistą nazw baz danych, a także C:\some folder i C:\path_from_sp_helpfile_output\ z rzeczywistymi ścieżkami. Nie mogę uzyskać dokładniejszej odpowiedzi, chyba że wiem, co to jest.


Oto pełna repro:

CREATE DATABASE [DB-A]; 
GO 

EXEC [DB-A].dbo.sp_helpfile; 

wyniki cząstkowe:

name  fileid filename 
-------- ------ --------------------------------- 
DB-A  1  C:\Program Files\...\DB-A.mdf 
DB-A_log 2  C:\Program Files\...\DB-A_log.ldf 

Teraz uruchomić kopię zapasową:

BACKUP DATABASE [DB-A] TO DISK = 'C:\dev\DB-A.bak' WITH INIT; 

Oczywiście jeśli cel klon (w tym przypadku DB-B) ady istnieje, będziemy chcieli, aby go nie upuścić:

USE [master]; 
GO 
IF DB_ID('DB-B') IS NOT NULL 
BEGIN 
    ALTER DATABASE [DB-B] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; 
    DROP DATABASE [DB-B]; 
END 
GO 

Teraz to będzie działać z powodzeniem przywrócić, co daje kopię DB-A przemianowany jako DB-B:

RESTORE DATABASE [DB-B] FROM DISK = 'C:\dev\DB-A.bak' 
    WITH MOVE 'DB-A'  TO 'C:\Program Files\...\DB-B.mdf', 
     MOVE 'DB-A_log' TO 'C:\Program Files\...\DB-B_log.ldf'; 

PYTANIA 3 i 4

  • zmienić wszystkie typy danych varchar i char do nvarchar i nchar
  • zmienić wszystkie typy danych tekstowych do nvarchar (max)

Refaktoryzacja jest głównym ból, zwłaszcza jeśli niektóre z tych kolumn udziału w ograniczeniach. W ten sposób możesz zbudować bardzo prosty skrypt, ale będziesz potrzebować czegoś znacznie więcej siły przemysłowej, aby poradzić sobie ze wszystkimi tymi zmiennymi. Zakłada to, że wszystkie kolumny są zerowe i nie uczestniczą w ograniczeniach.

DECLARE @sql NVARCHAR(MAX) = N''; 

SELECT @sql += ' 
    ALTER TABLE ' + 
    QUOTENAME(OBJECT_SCHEMA_NAME(c.[object_id])) 
    + '.' + QUOTENAME(OBJECT_NAME(c.[object_id])) 
    + ' ALTER COLUMN ' + QUOTENAME(c.name) + ' ' 
    + CASE t.name WHEN N'text' 
    THEN N'nvarchar(max)' 
    ELSE N'n' + t.name + '(' + RTRIM(c.max_length) + ')' 
    END + ';' 
FROM sys.columns AS c 
INNER JOIN sys.types AS t 
ON c.user_type_id = t.user_type_id 
WHERE c.system_type_id IN (35, 167, 175) 
AND OBJECTPROPERTY(c.[object_id], 'IsMsShipped') = 0; 

PRINT @sql; 
-- EXEC sp_executesql @sql; 

Można użyć wydruków do sprawdzenia pierwszego 8K skryptu, a kiedy myślisz, że wygląda dobrze, odkomentuj EXEC.

Po zakończeniu konfiguracji należy przebudować wszystkie indeksy.

Powiedział, skryptów bazy danych jak sugeruje Tony (lub za pomocą narzędzia jak Red Gate's SQL Compare - lub one of its many alternatives - przeciwko pustej bazy danych) prawdopodobnie będzie znacznie łatwiejsze, szczególnie gdy niektóre z tych kolumn udziału w ograniczeniach - które mogą wymagać zostać usunięte i ponownie utworzone w celu zmiany typów.


pytania 5 i 6

  • Jak mogę uaktualnić bazy danych serwera SQL SQL Server 2012
  • Czy istnieją jakieś prace przygotowawcze muszę przeprowadzić na bazie danych w celu zapewnienia Mogę z łatwością go uaktualnić?

Nie można zaktualizować pojedynczej bazy danych w 2008 roku. Aktualizujesz się na miejscu lub konfigurujesz nową instancję (tak jak opisał Tony), a następnie przeprowadzasz migrację bazy danych (najlepiej przy użyciu funkcji tworzenia kopii zapasowych/przywracania - wiele osób powie Ci, aby odłączyć/dołączyć, ale jest to o wiele mniej bezpieczne). Prace przygotowawcze należy obejmują:

i po aktualizacji zechcesz:

  • ustaw poziom zgodności na 110
  • zaktualizuj wszystkie statystyki
+1

Jednym słowem, beautimus! Dzięki. – MikeMalter

+0

wow ... heck odpowiedzi !!! – SFun28

-1

Hmmm używać serwera sql do skryptowania struktury bazy danych, a następnie wykonaj wyszukiwanie i zastąp zmiany. Zainstaluj 2012 i uruchom skrypt.

Nie jestem świadomy czegokolwiek w 2008 roku, który nie zadziała w 2012 roku. Jeśli Twój 2008 db został skonfigurowany tak, aby był nadal kompatybilny 2000, to jest kilka problemów, ale skryptowanie w 2008 roku powinno obejść je od razu.

Jeśli chodzi o aktualizację, nigdy nie miałem zbyt dużo czasu na uaktualnienie na miejscu, poza wszystkim, co jest destrukcyjne, więc każdy, kto jest mało rozsądny, i tak wykonałby pełną kopię zapasową serwera. Nie słuchaj nikogo, kto twierdzi, że jest to mało prawdopodobne, z mojego doświadczenia wynika, że ​​prawdopodobnie jesteś nieszczęśliwym człowiekiem, dla którego się nie udał, ponieważ nie przesadziłeś wystarczająco mocno palcami ..

Osobiście 'd zainstalował 2012 (najlepiej na innej maszynie) i po prostu przywrócił kopię danych z 2008 roku. Następnie ustaw poziomy zgodności, napraw użytkownika/loginy i inne.

Jeśli zdecydujesz się na miejsce, nie możesz zmienić bitness. tj. od 32bit 2008 do 64 bitów 2012. Aby to zrobić, musisz najpierw przejść na 64-bitową wersję 2008, co jest kolejnym powodem, dla którego wolałbym pierwszą propozycję.

0

Źródło dla script that copies a database.

USE master; 

DECLARE 
    @SourceDatabaseName AS SYSNAME = '<SourceDB>', 
    @TargetDatabaseName AS SYSNAME = '<TargetDB>' 



-- ============================================ 
-- Define path where backup will be saved 
-- ============================================ 
IF NOT EXISTS (SELECT 1 FROM sys.databases WHERE name = @SourceDatabaseName) 
    RAISERROR ('Variable @SourceDatabaseName is not set correctly !', 20, 1) WITH LOG  

DECLARE @SourceBackupFilePath varchar(2000) 
SELECT @SourceBackupFilePath = BMF.physical_device_name 
FROM 
    msdb.dbo.backupset B 
    JOIN msdb.dbo.backupmediafamily BMF ON B.media_set_id = BMF.media_set_id 
WHERE B.database_name = @SourceDatabaseName 
ORDER BY B.backup_finish_date DESC 

SET @SourceBackupFilePath = REPLACE(@SourceBackupFilePath, '.bak', '_clone.bak') 

IF @SourceBackupFilePath IS NULL 
     RAISERROR ('Could not determine file path for backup file!', 16, 1) WITH LOG 



-- ============================================ 
-- Backup source database 
-- ============================================ 
DECLARE @Sql NVARCHAR(MAX) 
SET @Sql = 'BACKUP DATABASE @SourceDatabaseName TO DISK = ''@SourceBackupFilePath''' 
SET @Sql = REPLACE(@Sql, '@SourceDatabaseName', @SourceDatabaseName) 
SET @Sql = REPLACE(@Sql, '@SourceBackupFilePath', @SourceBackupFilePath) 
SELECT 'Performing backup...', @Sql as ExecutedSql 
EXEC (@Sql) 



-- ============================================ 
-- Automatically compose database files (.mdf and .ldf) paths 
-- ============================================ 
DECLARE 
      @LogicalDataFileName as NVARCHAR(MAX) 
     , @LogicalLogFileName as NVARCHAR(MAX) 
     , @TargetDataFilePath as NVARCHAR(MAX) 
     , @TargetLogFilePath as NVARCHAR(MAX) 

SELECT 
     @LogicalDataFileName = name, 
     @TargetDataFilePath = SUBSTRING(physical_name,1,LEN(physical_name)-CHARINDEX('\',REVERSE(physical_name))) + '\' + @TargetDatabaseName + '.mdf' 
FROM sys.master_files 
WHERE 
     database_id = DB_ID(@SourceDatabaseName)   
     AND type = 0   -- datafile file 

SELECT 
     @LogicalLogFileName = name, 
     @TargetLogFilePath = SUBSTRING(physical_name,1,LEN(physical_name)-CHARINDEX('\',REVERSE(physical_name))) + '\' + @TargetDatabaseName + '.ldf' 
FROM sys.master_files 
WHERE 
     database_id = DB_ID(@SourceDatabaseName)   
     AND type = 1   -- log file  

SELECT 
    @LogicalDataFileName as LogicalDataFileName, 
    @LogicalLogFileName as LogicalLogFileName, 
    @TargetDataFilePath as TargetDataFilePath, 
    @TargetLogFilePath as TargetLogFilePath     

IF @TargetDataFilePath IS NULL OR @TargetLogFilePath IS NULL 
    RAISERROR ('Could not determine target paths!', 16, 1) WITH LOG 



-- ============================================ 
-- Restore target database 
-- ============================================ 
IF EXISTS (SELECT 1 FROM sys.databases WHERE name = @TargetDatabaseName) 
    RAISERROR ('A database with the same name already exists!', 20, 1) WITH LOG   

SET @Sql = 'RESTORE DATABASE @TargetDatabaseName 
FROM DISK = ''@SourceBackupFilePath'' 
WITH MOVE ''@LogicalDataFileName'' TO ''@TargetDataFilePath'', 
MOVE ''@LogicalLogFileName'' TO ''@TargetLogFilePath''' 
SET @Sql = REPLACE(@Sql, '@TargetDatabaseName', @TargetDatabaseName) 
SET @Sql = REPLACE(@Sql, '@SourceBackupFilePath', @SourceBackupFilePath) 
SET @Sql = REPLACE(@Sql, '@LogicalDataFileName', @LogicalDataFileName) 
SET @Sql = REPLACE(@Sql, '@TargetDataFilePath', @TargetDataFilePath) 
SET @Sql = REPLACE(@Sql, '@LogicalLogFileName', @LogicalLogFileName) 
SET @Sql = REPLACE(@Sql, '@TargetLogFilePath', @TargetLogFilePath) 
SELECT 'Restoring...', @Sql as ExecutedSql 
EXEC (@Sql) 
Powiązane problemy