Làm cách nào tôi có thể sao chép cơ sở dữ liệu SQL Server trên cùng một máy chủ trong SQL Server 2008 Express?


272

Tôi có một hệ thống MS SQL Server 2008 Express chứa cơ sở dữ liệu mà tôi muốn 'sao chép và đổi tên' (cho mục đích thử nghiệm) nhưng tôi không biết một cách đơn giản để đạt được điều này.

Tôi nhận thấy rằng trong phiên bản R2 của SQL Server có trình hướng dẫn cơ sở dữ liệu sao chép, nhưng thật đáng buồn là tôi không thể nâng cấp.

Cơ sở dữ liệu trong câu hỏi là khoảng một buổi biểu diễn. Tôi đã cố gắng khôi phục bản sao lưu của cơ sở dữ liệu mà tôi muốn sao chép vào cơ sở dữ liệu mới, nhưng không có may mắn.


2
Khôi phục bản sao lưu sẽ hoạt động. Bạn có thể cung cấp chi tiết hơn về làm thế nào mà thất bại?
Ed Harper

7
Tôi nhận ra tôi đã phạm sai lầm khi khôi phục từ bản sao lưu. Tôi đã tạo một DB trống mới trước tiên và cố gắng khôi phục bản sao lưu từ đó. Những gì tôi nên làm là đưa ra hộp thoại khôi phục và nhập tên của cơ sở dữ liệu mới vào đó thay vì tạo nó trước. Làm điều này nhân bản cơ sở dữ liệu độc đáo!
Sergio

Câu trả lời:


372
  1. Cài đặt Microsoft SQL Management Studio mà bạn có thể tải xuống miễn phí từ trang web của Microsoft:

    Phiên bản 2008

    Microsoft SQL Management Studio 2008 là một phần của SQL Server 2008 Express với các dịch vụ nâng cao

    Phiên bản 2012

    Nhấp vào nút tải xuống và kiểm traENU\x64\SQLManagementStudio_x64_ENU.exe

    Phiên bản 2014

    Nhấp vào nút tải xuống và kiểm tra MgmtStudio64BIT\SQLManagementStudio_x64_ENU.exe

  2. Mở Microsoft SQL Management Studio .

  3. Sao lưu cơ sở dữ liệu gốc vào tệp .BAK (db -> Tác vụ -> Sao lưu).
  4. Tạo cơ sở dữ liệu trống với tên mới (bản sao). Lưu ý ý kiến ​​dưới đây vì đây là tùy chọn.
  5. Nhấn vào đây để sao chép cơ sở dữ liệu và mở hộp thoại khôi phục (xem hình ảnh) khôi phục hộp thoại
  6. Chọn Thiết bị và thêm tệp sao lưu từ bước 3. thêm tập tin sao lưu
  7. Thay đổi đích đến cơ sở dữ liệu thử nghiệm điểm đến thay đổi
  8. Thay đổi vị trí của các tệp cơ sở dữ liệu, nó phải khác với bản gốc. Bạn có thể nhập trực tiếp vào hộp văn bản, chỉ cần thêm postfix. (LƯU Ý: Thứ tự là quan trọng. Chọn hộp kiểm, sau đó thay đổi tên tệp.) thay đổi địa điểm
  9. Kiểm tra với thay thế và với KEEP_REPLICATION với sự thay thế

84
1. Không tạo cơ sở dữ liệu trống và khôi phục tệp .bak trên đó. 2. Sử dụng tùy chọn 'Khôi phục cơ sở dữ liệu' có thể truy cập bằng cách nhấp chuột phải vào nhánh "Cơ sở dữ liệu" của SQL Server Management Studio và cung cấp tên cơ sở dữ liệu trong khi cung cấp nguồn để khôi phục. ref: stackoverflow.com/questions/10204480/ từ
taynguyen

1
Studio quản lý Microsoft SQL - hoàn toàn miễn phí
Tomas Kubes

4
Không hoạt động - "Không thể truy cập độc quyền vì cơ sở dữ liệu đang được sử dụng".
Emanuele Ciriachi

5
Tôi cũng phải bỏ chọn "Hãy sao lưu đuôi đăng nhập trước khi khôi phục". Điều này đã được kiểm tra theo mặc định và dẫn đến lỗi "Không thể truy cập độc quyền vì cơ sở dữ liệu đang sử dụng".
Củ cải

3
Cơ sở dữ liệu ban đầu của tôi bị kẹt khi "Khôi phục"
Divi perdomo

114

Bấm chuột phải vào cơ sở dữ liệu để sao chép, bấm Tasks, bấm Copy Database.... Làm theo hướng dẫn và bạn đã hoàn tất.


Tôi nghĩ rằng điều đó chỉ có sẵn trong bản phát hành R2 của SQL Server một cách đáng buồn :-(
Sergio

7
đây là cách nó hoạt động ở tốc: stackoverflow.com/questions/4269450/...
Th 00 mA s

2
Điều này không hoạt động nếu bạn có các đối tượng được mã hóa trong cơ sở dữ liệu của bạn.
cjbarth 17/03/2016

1
Tôi muốn nói rằng, điểm chính thực sự là nơi để làm điều đó? Những gì bạn mô tả là khá trực quan. Tôi đã thử chính xác điều đó trong một số công cụ (0xDBE, Visual Studio SQL Server Object Explorer) trước đây, nhưng không tìm thấy tính năng như vậy ở đó.
David Ferenczy Rogožan

3
Không thể! Nhiệm vụ -> Không có mục menu để sao chép cơ sở dữ liệu
raiserle

95

Bạn có thể thử tách cơ sở dữ liệu, sao chép các tệp vào tên mới tại dấu nhắc lệnh, sau đó đính kèm cả hai DB.

Trong SQL:

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

Tại Dấu nhắc lệnh (Tôi đã đơn giản hóa các đường dẫn tệp vì lợi ích của ví dụ này):

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

Trong SQL một lần nữa:

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

1
hoàn hảo! đây là giải pháp độc đáo phù hợp với tôi cảm ơn rất nhiều!
thiagoh

9
select * from OriginalDB.sys.sysfilesđể tìm vị trí của các tệp DB.
JohnLBevan

Vâng, tôi cũng thích giải pháp này nhất, vì nó không yêu cầu bất kỳ công cụ đặc biệt nào. Nhưng tôi không thể tạo NewDB, nó nói Permission deniedtrong .mdfhồ sơ. Bây giờ tôi không cần nó, tôi chỉ cần một bản sao lưu của DB gốc, vì vậy tôi có thể ghi đè lên DB gốc với nó sau này, tôi chỉ tò mò tại sao tôi lại gặp phải lỗi như vậy.
David Ferenczy Rogožan

2
Bạn không phải tách cơ sở dữ liệu gốc nếu bạn có thể dừng dịch vụ sql, sao chép tệp mdf và ldf, đổi tên chúng cho cơ sở dữ liệu mới của bạn, khởi động lại dịch vụ sql và chỉ chạy lệnh tạo cơ sở dữ liệu cuối cùng theo chủ: USE master ; GO TẠO DỮ LIỆU NewDB ON (FILENAME = 'C: \ NewDB.mdf'), (FILENAME = 'C: \ NewDB.ldf') CHO ATTACH; GO
danpop

1
+1 cho cách nhanh nhất. Ngoài bình luận tuyệt vời @JohnLBevan, bạn cũng có thể sử dụngexec sp_helpdb @dbname='TEMPDB';
jean

30

Hóa ra tôi đã cố khôi phục từ bản sao lưu không chính xác.

Ban đầu tôi đã tạo một cơ sở dữ liệu mới và sau đó cố gắng khôi phục lại bản sao lưu ở đây. Những gì tôi nên làm và cuối cùng là làm gì, để hiển thị hộp thoại khôi phục và nhập tên của cơ sở dữ liệu mới vào trường đích.

Vì vậy, trong ngắn hạn, khôi phục từ một bản sao lưu đã lừa.

Cảm ơn tất cả các phản hồi và đề xuất các chàng trai


Khi tôi thực hiện việc này, hộp thoại cho tôi biết các tệp nằm cùng vị trí với cơ sở dữ liệu mà tôi đã sao lưu ban đầu. Vì vậy, tôi không có can đảm để khôi phục, vì sợ rằng các tập tin sẽ bị ghi đè.
Niels Brinch

2
Neils, các tệp giống nhau, theo mặc định, trong ảnh chụp bạn đã chụp. Bạn có thể thay đổi tên của chúng để tạo tệp mới cho cơ sở dữ liệu mới được đặt tên.
Colin Dabritz

PS: Phương thức này yêu cầu dịch vụ SQL Agent, đảm bảo rằng nó đang chạy trước khi bắt đầu hoạt động sao chép db.
dvdmn

Bây giờ bạn đã giúp tôi ba lần với câu trả lời này. Tôi tiếp tục quên về việc gõ nó thay vì tạo ra nó. + bia
Piotr Kula

Điều này và đổi tên các tệp .mdf và .log trong cửa sổ 'Tệp' hoạt động với tôi.
Wollan

17

Đây là kịch bản tôi sử dụng. Một chút khó khăn nhưng nó hoạt động. Đã thử nghiệm trên 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

2
Trong môi trường của tôi, tên tệp không khớp với tên db (xuất phát từ lần khôi phục khác ) nên tôi cần 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)và một biến riêng cho @sourceDb_data với một truy vấn tương tự (thay thế bằng files.type=0). HTH!
Dan Caseley

11

Không có giải pháp nào được đề cập ở đây có hiệu quả với tôi - Tôi đang sử dụng SQL Server Management Studio 2014.

Thay vào đó, tôi phải bỏ chọn hộp kiểm "Lấy bản sao lưu đuôi trước khi khôi phục" trong màn hình "Tùy chọn": trong phiên bản của tôi, nó được kiểm tra theo mặc định và ngăn không cho hoàn tất thao tác Khôi phục. Sau khi bỏ chọn, thao tác Khôi phục đã tiến hành mà không gặp sự cố.

nhập mô tả hình ảnh ở đây


2
Câu trả lời này đã cứu ngày của tôi.
Dilhan Jayathilake

2
Đã cứu cả ngày của tôi nữa :)
ashilon

1
Khi không làm điều này với SQL Server 2017, cơ sở dữ liệu ban đầu vẫn ở trạng thái "Khôi phục ...". Giải pháp của bạn đã làm được mẹo - cảm ơn bạn!
mu88

9

Sử dụng MS SQL Server 2012, bạn cần thực hiện 3 bước cơ bản:

  1. Đầu tiên, tạo .sqltệp chỉ chứa cấu trúc của DB nguồn

    • nhấp chuột phải vào DB nguồn và sau đó Nhiệm vụ sau đó Tạo tập lệnh
    • làm theo trình hướng dẫn và lưu .sqltệp cục bộ
  2. Thứ hai, thay thế DB nguồn bằng một đích trong .sqltệp

    • Nhấp chuột phải vào tệp đích, chọn Truy vấn mớiCtrl-Hhoặc ( Chỉnh sửa - Tìm và thay thế - Thay thế nhanh )
  3. Cuối cùng, điền dữ liệu

    • Nhấp chuột phải vào DB đích, sau đó chọn Nhiệm vụNhập dữ liệu
    • Trình đơn nguồn dữ liệu được đặt thành " nhà cung cấp dữ liệu khung .net cho máy chủ SQL " + đặt trường văn bản chuỗi kết nối trong DATA ex:Data Source=Mehdi\SQLEXPRESS;Initial Catalog=db_test;User ID=sa;Password=sqlrpwrd15
    • làm tương tự với đích đến
    • đánh dấu vào bảng bạn muốn chuyển hoặc chọn hộp bên cạnh "nguồn: ..." để kiểm tra tất cả chúng

Bạn xong việc rồi.


Nhân tiện, tôi đoán Nhập dữ liệu có thể tạo bảng nếu không có trong bảng đích .. giải pháp đơn giản +1
Khurram Ishaque

6

Trong SQL Server 2008 R2, sao lưu cơ sở dữ liệu dưới dạng tệp vào một thư mục. Sau đó chọn tùy chọn khôi phục xuất hiện trong thư mục "Cơ sở dữ liệu". Trong trình hướng dẫn nhập tên mới mà bạn muốn trong cơ sở dữ liệu đích. Và chọn khôi phục tập tin frrom và sử dụng tập tin bạn vừa tạo. Tôi đã làm điều đó và nó rất nhanh (DB của tôi nhỏ, nhưng vẫn vậy) Pablo.


4

Nếu cơ sở dữ liệu không lớn lắm, bạn có thể xem các lệnh 'Cơ sở dữ liệu tập lệnh' trong SQL Server Management Studio Express, nằm trong menu ngữ cảnh ngoài chính mục cơ sở dữ liệu trong trình thám hiểm.

Bạn có thể chọn tất cả những gì để kịch bản; bạn muốn các đối tượng và dữ liệu, tất nhiên. Sau đó, bạn sẽ lưu toàn bộ tập lệnh vào một tệp. Sau đó, bạn có thể sử dụng tệp đó để tạo lại cơ sở dữ liệu; chỉ cần đảm bảo USElệnh ở trên cùng được đặt thành cơ sở dữ liệu thích hợp.


1
Cảm ơn, cơ sở dữ liệu khá lớn, tuy nhiên, (khoảng một buổi biểu diễn) vì vậy tôi nghĩ những điều tồi tệ có thể xảy ra :-)
Sergio

2
Đúng; Đó không phải là cách tốt nhất sau đó. Thay vào đó, bạn có thể sử dụng Cơ sở dữ liệu Tập lệnh để chỉ tạo cấu trúc trong cơ sở dữ liệu mới, sau đó Nhập / Xuất để di chuyển dữ liệu. Chỉ cần chắc chắn rằng bạn làm cơ sở dữ liệu Script trước; Nhập / Xuất sẽ tạo các bảng nếu chúng không tồn tại và bạn có thể không thích cách thực hiện.
Andrew Barber

4

Giải pháp, dựa trên nhận xét này: https://stackoverflow.com/a/22409447/2399045 . Chỉ cần đặt cài đặt: Tên DB, thư mục tạm thời, thư mục tệp db. Và sau khi chạy, bạn sẽ có bản sao DB với Tên ở định dạng "sourceDBName_yyyy-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

3

Kịch bản dựa trên câu trả lời của Joe ( tách ra, sao chép tệp, đính kèm cả hai ).

  1. Chạy Management Studio làm tài khoản Administrator.

Nó không cần thiết, nhưng có thể truy cập bị từ chối lỗi khi thực thi.

  1. Định cấu hình máy chủ sql để thực thi xp_cmdshel
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
  1. Chạy script, nhưng nhập tên db của bạn vào @dbName@copyDBNamecác biến trước đó.
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

3

Bạn chỉ có thể tạo một cơ sở dữ liệu mới và sau đó đi đến các tác vụ, nhập dữ liệu và nhập tất cả dữ liệu từ cơ sở dữ liệu bạn muốn sao chép vào cơ sở dữ liệu bạn vừa tạo.


2

Một cách khác để thực hiện thủ thuật bằng cách sử dụng trình hướng dẫn nhập / xuất , trước tiên hãy tạo cơ sở dữ liệu trống, sau đó chọn nguồn là máy chủ của bạn với cơ sở dữ liệu nguồn, sau đó ở đích chọn cùng một máy chủ với cơ sở dữ liệu đích (sử dụng cơ sở dữ liệu trống bạn đã tạo lúc đầu), sau đó nhấn kết thúc

Nó sẽ tạo tất cả các bảng và chuyển tất cả dữ liệu vào cơ sở dữ liệu mới,

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.