Jak sklonować bazę danych SQL Server na tym samym serwerze w SQL Server 2008 Express?

271

Mam system MS SQL Server 2008 Express, który zawiera bazę danych, którą chciałbym „skopiować i zmienić nazwę” (do celów testowych), ale nie znam prostego sposobu na osiągnięcie tego.

Zauważam, że w wersji R2 programu SQL Server jest kreator kopii bazy danych, ale niestety nie mogę dokonać aktualizacji.

Baza danych, o której mowa, jest około koncertu. Próbowałem przywrócić kopię zapasową bazy danych, którą chcę skopiować do nowej bazy danych, ale bez powodzenia.

Sergio
źródło
2
Przywracanie kopii zapasowej powinno działać. Czy możesz podać więcej szczegółów na temat tego, jak to się nie udało?
Ed Harper,
7
Zrozumiałem, że popełniłem błąd podczas przywracania z kopii zapasowej. Najpierw utworzyłem nową pustą bazę danych i próbowałem przywrócić z niej kopię zapasową. Powinienem był wywołać okno dialogowe przywracania i wpisać tam nazwę nowej bazy danych, zamiast najpierw ją utworzyć. W ten sposób ładnie sklonowano bazę danych!
Sergio

Odpowiedzi:

372
  1. Zainstaluj Microsoft SQL Management Studio, które możesz bezpłatnie pobrać ze strony Microsoft:

    Wersja 2008

    Microsoft SQL Management Studio 2008 jest częścią SQL Server 2008 Express z zaawansowanymi usługami

    Wersja 2012

    Kliknij przycisk Pobierz i sprawdźENU\x64\SQLManagementStudio_x64_ENU.exe

    Wersja 2014

    Kliknij przycisk Pobierz i sprawdź MgmtStudio64BIT\SQLManagementStudio_x64_ENU.exe

  2. Otwórz Microsoft SQL Management Studio .

  3. Wykonaj kopię zapasową oryginalnej bazy danych do pliku .BAK (db -> Zadanie -> Kopia zapasowa).
  4. Utwórz pustą bazę danych z nową nazwą (klon). Uwaga uwagi poniżej, ponieważ jest to opcjonalne.
  5. Kliknij, aby sklonować bazę danych i otwórz okno dialogowe przywracania (patrz zdjęcie) przywrócić okno dialogowe
  6. Wybierz Urządzenie i dodaj plik kopii zapasowej od kroku 3. dodaj plik kopii zapasowej
  7. Zmień miejsce docelowe na testową bazę danych zmiana miejsca przeznaczenia
  8. Zmień lokalizację plików bazy danych, musi być inna niż oryginalna. Możesz pisać bezpośrednio w polu tekstowym, wystarczy dodać postfiks. (UWAGA: Kolejność jest ważna. Zaznacz pole wyboru, a następnie zmień nazwy plików.) zmień lokalizację
  9. Sprawdź ZA POMOCĄ I ZA POMOCĄ KEEP_REPLICATION z zamiennikiem
Tomas Kubes
źródło
84
1. Nie twórz pustej bazy danych i przywróć do niej plik .bak. 2. Użyj opcji „Przywróć bazę danych” dostępnej po kliknięciu prawym przyciskiem myszy gałęzi „Bazy danych” SQL Server Management Studio i podaj nazwę bazy danych, podając źródło do przywrócenia. ref: stackoverflow.com/questions/10204480/…
taynguyen
1
Microsoft SQL Management Studio - to nic nie kosztuje
Tomas Kubes
4
Nie działa - „Nie można uzyskać dostępu wyłącznego, ponieważ baza danych jest w użyciu”.
Emanuele Ciriachi
5
Musiałem także odznaczyć opcję „Wykonaj kopię zapasową dziennika ogona przed przywróceniem”. Zostało to domyślnie zaznaczone i spowodowało błąd „Nie można uzyskać dostępu wyłącznego, ponieważ baza danych jest w użyciu”.
Rzepa
2
Moja oryginalna baza danych utknęła w „Przywracaniu”
Divi perdomo
113

Kliknij bazę danych prawym przyciskiem myszy, aby sklonować, kliknij Tasks, kliknij Copy Database.... Postępuj zgodnie z kreatorem i gotowe.

DForck42
źródło
Myślę, że jest to niestety dostępne tylko w wersji R2 programu SQL Server :-(
Sergio
7
oto jak to działa w trybie ekspresowym: stackoverflow.com/questions/4269450/...
00 00
2
To nie działa, jeśli masz zaszyfrowane obiekty w bazie danych.
cjbarth
1
Powiedziałbym, że najważniejsze jest to, gdzie to zrobić? To, co opisałeś, jest dość intuicyjne. Próbowałem już tego dokładnie w niektórych narzędziach (0xDBE, Visual Studio SQL Server Object Explorer), ale nie znalazłem tam takiej funkcji.
David Ferenczy Rogožan,
3
Niemożliwe! Zadania -> Brak pozycji menu do skopiowania bazy danych
raiserle
95

Możesz spróbować odłączyć bazę danych, skopiować pliki do nowych nazw w wierszu polecenia, a następnie dołączyć obie bazy danych.

W SQL:

USE master;
GO 
EXEC sp_detach_db
    @dbname = N'OriginalDB';
GO

W wierszu polecenia (uprościłem ścieżki plików na potrzeby tego przykładu):

copy c:\OriginalDB.mdf c:\NewDB.mdf
copy c:\OriginalDB.ldf c:\NewDB.ldf

Znowu w SQL:

USE master;
GO
CREATE DATABASE OriginalDB
    ON (FILENAME = 'C:\OriginalDB.mdf'),
       (FILENAME = 'C:\OriginalDB.ldf')
    FOR ATTACH;
GO
CREATE DATABASE NewDB
    ON (FILENAME = 'C:\NewDB.mdf'),
       (FILENAME = 'C:\NewDB.ldf')
    FOR ATTACH;
GO
Joe Stefanelli
źródło
1
idealny! to unikalne rozwiązanie, które działało dla mnie! wielkie dzięki!
thiagoh
9
select * from OriginalDB.sys.sysfilesznaleźć lokalizację plików bazy danych.
JohnLBevan
Tak, najbardziej podoba mi się również to rozwiązanie, ponieważ nie wymaga żadnych specjalnych narzędzi. Ale nie udało mi się utworzyć NewDB, jak wynika Permission deniedz .mdfakt. Nie potrzebuję go teraz, potrzebowałem tylko kopii zapasowej oryginalnej DB, więc mogę później nadpisać oryginalną DB, jestem ciekawy, dlaczego otrzymuję taki błąd.
David Ferenczy Rogožan
2
Nie musisz odłączać oryginalnej bazy danych, jeśli możesz zatrzymać usługę sql, skopiować plik mdf i ldf, zmienić nazwę dla nowej bazy danych, ponownie uruchomić usługę sql i po prostu uruchomić ostatnią komendę tworzenia bazy danych w master: USE master ; GO UTWÓRZ BAZY DANYCH NewDB ON (NAZWA PLIKU = 'C: \ NewDB.mdf'), (NAZWA PLIKU = 'C: \ NewDB.ldf') DLA ZAŁĄCZENIA; GO
danpop,
1
+1 za najszybszy sposób. Oprócz doskonałego komentarza @JohnLBevan możesz także użyćexec sp_helpdb @dbname='TEMPDB';
jean
30

Okazuje się, że próbowałem przywrócić z kopii zapasowej niepoprawnie.

Początkowo utworzyłem nową bazę danych, a następnie próbowałem przywrócić kopię zapasową tutaj. To, co powinienem był zrobić i co zadziałało, to wywołanie okna dialogowego przywracania i wpisanie nazwy nowej bazy danych w polu docelowym.

Krótko mówiąc, przywrócenie z kopii zapasowej załatwiło sprawę.

Dziękujemy za wszystkie opinie i sugestie

Sergio
źródło
Gdy to zrobię, okno dialogowe mówi mi, że pliki znajdują się w tej samej lokalizacji, co baza danych, z której utworzyłem kopię zapasową. Więc nie mam odwagi przywrócić, boję się, że pliki zostaną nadpisane.
Niels Brinch,
2
Neils, pliki są domyślnie takie same w zrobionej migawce. Możesz zmienić ich nazwy, aby utworzyć nowe pliki dla nowo nazwanej bazy danych.
Colin Dabritz
PS: Ta metoda wymaga usługi agenta SQL, upewnij się, że jest uruchomiona przed rozpoczęciem operacji kopiowania db.
dvdmn,
Trzy razy pomogłeś mi w tej odpowiedzi. Ciągle zapominam o wpisywaniu go zamiast tworzenia. + piwo
Piotr Kula
To i zmiana nazwy plików .mdf i .log w oknie „Pliki” zadziałało dla mnie.
Wollan,
17

To jest skrypt, którego używam. Trochę trudne, ale działa. Testowane na SQL Server 2012.

DECLARE @backupPath nvarchar(400);
DECLARE @sourceDb nvarchar(50);
DECLARE @sourceDb_log nvarchar(50);
DECLARE @destDb nvarchar(50);
DECLARE @destMdf nvarchar(100);
DECLARE @destLdf nvarchar(100);
DECLARE @sqlServerDbFolder nvarchar(100);

SET @sourceDb = 'db1'
SET @sourceDb_log = @sourceDb + '_log'
SET @backupPath = 'E:\tmp\' + sourceDb + '.bak' --ATTENTION: file must already exist and SQL Server must have access to it
SET @sqlServerDbFolder = 'E:\DB SQL\MSSQL11.MSSQLSERVER\MSSQL\DATA\'
SET @destDb = 'db2'
SET @destMdf = @sqlServerDbFolder + @destDb + '.mdf'
SET @destLdf = @sqlServerDbFolder + @destDb + '_log' + '.ldf'

BACKUP DATABASE @sourceDb TO DISK = @backupPath

RESTORE DATABASE @destDb FROM DISK = @backupPath
WITH REPLACE,
   MOVE @sourceDb     TO @destMdf,
   MOVE @sourceDb_log TO @destLdf
niebieskawy
źródło
2
W moim środowisku nazwy plików nie pasowały do ​​nazwy db (pochodzącej z innego przywracania), więc potrzebowałem SET @sourceDb_log = (SELECT files.name FROM sys.databases dbs INNER JOIN sys.master_files files ON dbs.database_id=files.database_id WHERE dbs.name=@sourceDb AND files.type=1)osobnej zmiennej dla @sourceDb_data z podobnym zapytaniem (podstawianie w files.type=0). HTH!
Dan Caseley,
11

Żadne z wymienionych tutaj rozwiązań nie działało dla mnie - używam SQL Server Management Studio 2014.

Zamiast tego musiałem odznaczyć pole wyboru „Wykonaj kopię zapasową dziennika ogona przed przywróceniem” na ekranie „Opcje”: w mojej wersji jest domyślnie zaznaczone i uniemożliwia zakończenie operacji przywracania. Po odznaczeniu operacji przywracania przebiegła bez problemów.

wprowadź opis zdjęcia tutaj

Emanuele Ciriachi
źródło
2
Ta odpowiedź uratowała mi dzień.
Dilhan Jayathilake,
2
Zaoszczędziłem też mój dzień :)
ashilon
1
Gdy nie robi to z SQL Server 2017, oryginalna baza danych pozostała w „Przywracaniu ...”. Twoje rozwiązanie załatwiło sprawę - dziękuję!
mu88
9

Korzystając z MS SQL Server 2012, musisz wykonać 3 podstawowe kroki:

  1. Najpierw wygeneruj .sqlplik zawierający tylko strukturę źródłowej bazy danych

    • kliknij prawym przyciskiem myszy źródłową bazę danych, a następnie Zadania, a następnie Wygeneruj skrypty
    • postępuj zgodnie z instrukcjami kreatora i zapisz .sqlplik lokalnie
  2. Po drugie, zamień źródłową bazę danych na docelową w .sqlpliku

    • Kliknij prawym przyciskiem myszy plik docelowy, wybierz Nowe zapytanie i Ctrl-Hlub ( Edytuj - Znajdź i zamień - Szybka zamiana )
  3. Na koniec zapełnij danymi

    • Kliknij docelową bazę danych prawym przyciskiem myszy, a następnie wybierz Zadania i importuj dane
    • Lista rozwijana źródła danych ustawiona na „ Dostawca danych .NET Framework dla serwera SQL ” + ustaw pole tekstowe ciągu połączenia w obszarze DANE np .:Data Source=Mehdi\SQLEXPRESS;Initial Catalog=db_test;User ID=sa;Password=sqlrpwrd15
    • zrób to samo z miejscem docelowym
    • zaznacz tabelę, którą chcesz przenieść, lub zaznacz pole „Źródło: ...”, aby zaznaczyć wszystkie

Gotowe.

Mehdi Benkirane
źródło
Nawiasem mówiąc, myślę, że import danych może tworzyć tabele, jeśli nie są obecne w tabelach docelowych. Proste rozwiązanie +1
Khurram Ishaque
6

W SQL Server 2008 R2 wykonaj kopię zapasową bazy danych jako plik w folderze. Następnie wybierz opcję przywracania, która pojawia się w folderze „Baza danych”. W kreatorze wprowadź nową nazwę, którą chcesz w docelowej bazie danych. I wybierz przywróć z pliku i użyj właśnie utworzonego pliku. Po prostu to zrobiłem i to było bardzo szybkie (moje DB było małe, ale nadal) Pablo.

pabloelustondo
źródło
4

Jeśli baza danych nie jest bardzo duża, możesz spojrzeć na polecenia „Baza danych skryptów” w SQL Server Management Studio Express, które znajdują się w menu kontekstowym poza samym elementem bazy danych w eksploratorze.

Możesz wybrać wszystko, co chcesz napisać; oczywiście chcesz obiektów i danych. Następnie zapiszesz cały skrypt w jednym pliku. Następnie możesz użyć tego pliku do odtworzenia bazy danych; po prostu upewnij się, że USEpolecenie u góry jest ustawione na odpowiednią bazę danych.

Andrew Barber
źródło
1
Dzięki, baza danych jest jednak dość duża (wokół koncertu), więc myślę, że mogą się zdarzyć złe rzeczy :-)
Sergio
2
Dobrze; to nie jest najlepszy sposób. Zamiast tego możesz użyć bazy danych skryptów, aby po prostu utworzyć strukturę w nowej bazie danych, a następnie importować / eksportować, aby przenieść dane. Upewnij się tylko, że najpierw wykonujesz Bazę Skryptów; Import / Eksport utworzy tabele, jeśli nie istnieją, i może ci się nie podobać.
Andrew Barber,
4

Rozwiązanie oparte na tym komentarzu: https://stackoverflow.com/a/22409447/2399045 . Wystarczy ustawić ustawienia: nazwa bazy danych, folder tymczasowy, folder plików db. A po uruchomieniu będziesz mieć kopię DB o nazwie w formacie „sourceDBName_rrrr-mm-dd”.

-- Settings --
-- New DB name will have name = sourceDB_yyyy-mm-dd
declare @sourceDbName nvarchar(50) = 'MyDbName';
declare @tmpFolder nvarchar(50) = 'C:\Temp\'
declare @sqlServerDbFolder nvarchar(100) = 'C:\Databases\'

--  Execution --
declare @sourceDbFile nvarchar(50);
declare @sourceDbFileLog nvarchar(50);
declare @destinationDbName nvarchar(50) = @sourceDbName + '_' + (select convert(varchar(10),getdate(), 121))
declare @backupPath nvarchar(400) = @tmpFolder + @destinationDbName + '.bak'
declare @destMdf nvarchar(100) = @sqlServerDbFolder + @destinationDbName + '.mdf'
declare @destLdf nvarchar(100) = @sqlServerDbFolder + @destinationDbName + '_log' + '.ldf'

SET @sourceDbFile = (SELECT top 1 files.name 
                    FROM sys.databases dbs 
                    INNER JOIN sys.master_files files 
                        ON dbs.database_id = files.database_id 
                    WHERE dbs.name = @sourceDbName
                        AND files.[type] = 0)

SET @sourceDbFileLog = (SELECT top 1 files.name 
                    FROM sys.databases dbs 
                    INNER JOIN sys.master_files files 
                        ON dbs.database_id = files.database_id 
                    WHERE dbs.name = @sourceDbName
                        AND files.[type] = 1)

BACKUP DATABASE @sourceDbName TO DISK = @backupPath

RESTORE DATABASE @destinationDbName FROM DISK = @backupPath
WITH REPLACE,
   MOVE @sourceDbFile     TO @destMdf,
   MOVE @sourceDbFileLog  TO @destLdf
Pavel Samoylenko
źródło
3

Skrypt oparty na odpowiedzi Joe ( odłącz, skopiuj pliki, załącz oba ).

  1. Uruchom Managment Studio jako konto administratora.

Nie jest to konieczne, ale może błąd odmowy dostępu podczas wykonywania.

  1. Skonfiguruj serwer SQL dla wykonania xp_cmdshel
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
  1. Uruchom skrypt, ale wcześniej wpisz nazwy db @dbNamei @copyDBNamezmienne.
USE master;
GO 

DECLARE @dbName NVARCHAR(255) = 'Products'
DECLARE @copyDBName NVARCHAR(255) = 'Products_branch'

-- get DB files
CREATE TABLE ##DBFileNames([FileName] NVARCHAR(255))
EXEC('
    INSERT INTO ##DBFileNames([FileName])
    SELECT [filename] FROM ' + @dbName + '.sys.sysfiles')

-- drop connections
EXEC('ALTER DATABASE ' + @dbName + ' SET OFFLINE WITH ROLLBACK IMMEDIATE')

EXEC('ALTER DATABASE ' + @dbName + ' SET SINGLE_USER')

-- detach
EXEC('EXEC sp_detach_db @dbname = ''' + @dbName + '''')

-- copy files
DECLARE @filename NVARCHAR(255), @path NVARCHAR(255), @ext NVARCHAR(255), @copyFileName NVARCHAR(255), @command NVARCHAR(MAX) = ''
DECLARE 
    @oldAttachCommand NVARCHAR(MAX) = 
        'CREATE DATABASE ' + @dbName + ' ON ', 
    @newAttachCommand NVARCHAR(MAX) = 
        'CREATE DATABASE ' + @copyDBName + ' ON '

DECLARE curs CURSOR FOR 
SELECT [filename] FROM ##DBFileNames
OPEN curs  
FETCH NEXT FROM curs INTO @filename
WHILE @@FETCH_STATUS = 0  
BEGIN
    SET @path = REVERSE(RIGHT(REVERSE(@filename),(LEN(@filename)-CHARINDEX('\', REVERSE(@filename),1))+1))
    SET @ext = RIGHT(@filename,4)
    SET @copyFileName = @path + @copyDBName + @ext

    SET @command = 'EXEC master..xp_cmdshell ''COPY "' + @filename + '" "' + @copyFileName + '"'''
    PRINT @command
    EXEC(@command);

    SET @oldAttachCommand = @oldAttachCommand + '(FILENAME = "' + @filename + '"),'
    SET @newAttachCommand = @newAttachCommand + '(FILENAME = "' + @copyFileName + '"),'

    FETCH NEXT FROM curs INTO @filename
END
CLOSE curs 
DEALLOCATE curs

-- attach
SET @oldAttachCommand = LEFT(@oldAttachCommand, LEN(@oldAttachCommand) - 1) + ' FOR ATTACH'
SET @newAttachCommand = LEFT(@newAttachCommand, LEN(@newAttachCommand) - 1) + ' FOR ATTACH'

-- attach old db
PRINT @oldAttachCommand
EXEC(@oldAttachCommand)

-- attach copy db
PRINT @newAttachCommand
EXEC(@newAttachCommand)

DROP TABLE ##DBFileNames
Jewgienij Iwanow
źródło
3

Możesz po prostu utworzyć nową bazę danych, a następnie przejść do zadań, zaimportować dane i zaimportować wszystkie dane z bazy danych, którą chcesz zduplikować do właśnie utworzonej bazy danych.

Techie Philosopher
źródło
2

Innym sposobem jest załatwienie sprawy za pomocą kreatora importu / eksportu , najpierw utwórz pustą bazę danych, a następnie wybierz źródło, którym jest serwer ze źródłową bazą danych, a następnie w miejscu docelowym wybierz ten sam serwer z docelową bazą danych (używając pustej bazy danych utworzyłeś na początku), a następnie kliknij przycisk Zakończ

Stworzy wszystkie tabele i przeniesie wszystkie dane do nowej bazy danych,

Mohanad Kaleia
źródło