SQL Server 2008 Express'te aynı sunucudaki bir SQL Server veritabanını nasıl klonlayabilirim?


272

'Kopyalamak ve yeniden adlandırmak' (test amacıyla) istiyorum bir veritabanı içeren bir MS SQL Server 2008 Express sistemi var ama bunu başarmak için basit bir yol farkında değilim.

SQL Server R2 sürümünde bir kopya veritabanı sihirbazı olduğunu fark ettim, ama ne yazık ki yükseltme yapamıyorum.

Söz konusu veritabanı bir konser civarında. Yeni bir veritabanına kopyalamak istediğim veritabanının yedeğini geri yüklemeye çalıştım, ama hiç şansı yoktu.


2
Bir yedeğin geri yüklenmesi işe yaramalıdır. Bunun nasıl başarısız olduğu hakkında daha ayrıntılı bilgi verebilir misiniz?
Ed Harper

7
Yedeklemeden geri yüklerken bir hata yaptığımı fark ettim. Önce yeni bir boş DB oluşturdum ve oradan yedeklemeyi geri yüklemeye çalıştım. Ne yapmalıydım geri yükleme iletişim kutusunu getirmek ve ilk oluşturmak yerine orada yeni veritabanı adını yazın. Bunu yapmak veritabanı güzel klonladı!
Sergio

Yanıtlar:


372
  1. Microsoft'un web sitesinden ücretsiz olarak indirebileceğiniz Microsoft SQL Management Studio'yu yükleyin:

    Sürüm 2008

    Microsoft SQL Management Studio 2008, Gelişmiş Hizmetler ile SQL Server 2008 Express'in bir parçasıdır

    Sürüm 2012

    Click indirme düğmesini ve çekENU\x64\SQLManagementStudio_x64_ENU.exe

    Sürüm 2014

    Tıklayın indirme düğmesini ve MgmtStudio kontrol64BIT\SQLManagementStudio_x64_ENU.exe

  2. Açık Microsoft SQL Management Studio'yu .

  3. Özgün veritabanını .BAK dosyasına yedekleyin (db -> Görev -> Yedekleme).
  4. Yeni adla (klon) boş veritabanı oluşturun. Bu isteğe bağlı olduğu için aşağıdaki yorumları not alın.
  5. Veritabanını kopyalamak ve geri yükleme iletişim kutusunu açmak için tıklayın (resme bakın) iletişim kutusunu geri yükle
  6. Aygıt'ı seçin ve 3. adımdan yedekleme dosyasını ekleyin. yedek dosya ekle
  7. Veritabanını test etmek için hedefi değiştirin varış yerini değiştir
  8. Veritabanı dosyalarının konumunu değiştirin, orijinalinden farklı olmalıdır. Doğrudan metin kutusuna yazabilirsiniz, sadece postfix ekleyin. (NOT: Sıralama önemlidir. Onay kutusunu seçin, ardından dosya adlarını değiştirin.) yer değiştir
  9. REPLACE İLE ve KEEP_REPLICATION İLE kontrol edin değiştir

84
1. Boş bir veritabanı oluşturmayın ve .bak dosyasını geri yükleyin. 2. SQL Server Management Studio'nun "Veritabanları" dalını sağ tıklatarak erişilebilen 'Veritabanını Geri Yükle' seçeneğini kullanın ve geri yüklenecek kaynağı sağlarken veritabanı adını girin. ref: stackoverflow.com/questions/10204480/…
taynguyen

1
Microsoft SQL Management Studio - ücretsiz
Tomas Kubes

4
Çalışmıyor - "Veritabanı kullanımda olduğundan Özel Erişim alınamadı".
Emanuele Ciriachi

5
Ayrıca "Geri yüklemeden önce kuyruk günlüğü yedek al" seçeneğinin işaretini kaldırmak zorunda kaldım. Bu, varsayılan olarak işaretlendi ve "Veritabanı kullanımda olduğu için Özel Erişim alınamadı" hatasıyla sonuçlandı.
Şalgam

3
Orijinal veritabanım "Geri
yükleniyor

114

Klonlamak için veritabanına sağ tıklayın, tıklayın Tasks, tıklayın Copy Database.... Sihirbazı takip edin ve işiniz bitti.


Ne yazık ki sadece SQL Server R2 sürümünde kullanılabilir olduğunu düşünüyorum :-(
Sergio

7
ekspres olarak şu şekilde çalışır: stackoverflow.com/questions/4269450/…
Th 00 mÄ s

2
Veritabanınızda şifrelenmiş nesneler varsa bu çalışmaz.
cjbarth

1
Ana nokta aslında nerede yapılacağını söyleyebilirim? Açıkladığınız şey oldukça sezgisel. Daha önce bazı araçlarda (0xDBE, Visual Studio SQL Server Nesne Gezgini) denedim, ancak böyle bir özellik bulamadım.
David Ferenczy Rogožan

3
Mümkün değil! Görevler -> Veritabanını kopyalamak için menü öğesi yok
raiserle

95

Veritabanını ayırmayı, komut isteminde dosyaları yeni adlara kopyalamayı ve her iki DB'yi de eklemeyi deneyebilirsiniz.

SQL'de:

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

Komut isteminde (Bu örnek uğruna dosya yollarını basitleştirdim):

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

SQL'de tekrar:

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
mükemmel! bu benim için çalışan eşsiz bir çözüm! çok teşekkürler!
thiagoh

9
select * from OriginalDB.sys.sysfilesDB dosyalarının yerini bulmak için.
JohnLBevan

Evet, bu çözümü en çok seviyorum, çünkü herhangi bir özel alet gerektirmiyor. Ama NewDB oluşturmak mümkün değildi, diyor Permission deniedüzerine .mdfdosyaya. Şimdi buna ihtiyacım yok, sadece orijinal DB'nin bir yedeğine ihtiyacım vardı, bu yüzden daha sonra orijinal DB'nin üzerine yazabilirim, neden böyle bir hata aldığımı merak ediyorum.
David Ferenczy Rogožan

2
Sql hizmetini durdurabilir, mdf ve ldf dosyasını kopyalayabilir, yeni veritabanınız için yeniden adlandırabilir, sql hizmetini yeniden başlatabilir ve master altında son oluştur veritabanı komutunu çalıştırırsanız orijinal veritabanını ayırmanız gerekmez. ; BAŞLANGIÇ İÇİN GO CLEATE DATABASE NewDB (FILENAME = 'C: \ NewDB.mdf'), (FILENAME = 'C: \ NewDB.ldf'); GO
danpop

1
En hızlı yol için +1. @JohnLBevan mükemmel yorumuna ek olarak, kullanabilirsinizexec sp_helpdb @dbname='TEMPDB';
jean

30

Bir yedeklemeden yanlış bir şekilde geri yüklemeye çalıştığım ortaya çıktı.

Başlangıçta yeni bir veritabanı oluşturdum ve ardından yedeği buraya geri yüklemeye çalıştım. Ne yapmalıydım ve sonunda işe yarayan şey, geri yükleme iletişim kutusunu açmak ve hedef alana yeni veritabanının adını yazmaktı.

Kısacası, bir yedeklemeden geri yükleme hile yaptı.

Tüm geri bildirim ve önerileriniz için teşekkürler


Bunu yaptığımda, iletişim kutusu bana dosyaların yedeklediğim veritabanıyla aynı konumda olduğunu söylüyor. Bu yüzden dosyaların üzerine yazılacağından korkan geri yükleme cesaretim yok.
Niels Brinch

2
Neils, dosyalar varsayılan olarak, çektiğiniz anlık görüntü ile aynıdır. Yeni adlandırılmış veritabanı için yeni dosyalar oluşturmak üzere bunların adlarını değiştirebilirsiniz.
Colin Dabritz

Not: Bu yöntem SQL Agent hizmeti gerektirir, db kopyalama işlemine başlamadan önce çalıştığından emin olun.
dvdmn

Şimdi bu cevapla bana üç kez yardım ettin. Onu yazmak yerine yazmakta olduğumu unutmaya devam ediyorum. + bira
Piotr Kula

Bu ve 'Dosyalar' penceresindeki .mdf ve .log dosyalarını yeniden adlandırmak benim için çalıştı.
Wollan

17

Bu benim kullandığım script. Biraz zor ama işe yarıyor. SQL Server 2012'de test edilmiştir.

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
Benim ortamda, dosya adları ( başka bir geri yükleme geliyor) db adıyla eşleşmedi, bu yüzden gerekli 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)ve @sourceDb_data için benzer bir sorgu ile (içinde yerine files.type=0) ayrı bir değişken . HTH!
Dan Caseley

11

Burada bahsedilen çözümlerin hiçbiri benim için çalışmadı - SQL Server Management Studio 2014 kullanıyorum.

Bunun yerine, "Seçenekler" ekranındaki "Geri yüklemeden önce kuyruk kaydı yedeklemesini al" onay kutusunun işaretini kaldırmak zorunda kaldım: sürümümde varsayılan olarak işaretlidir ve Geri Yükleme işleminin tamamlanmasını engeller. İşaretini kaldırdıktan sonra, Geri Yükleme işlemi sorunsuz devam etti.

resim açıklamasını buraya girin


2
Bu cevap günümü kurtardı.
Dilhan Jayathilake

2
Çok günümü de
kurtardım

1
Bunu SQL Server 2017 ile yapmadığınızda, orijinal veritabanı "Geri yükleniyor ..." içinde kaldı. Çözümünüz hile yaptı - teşekkürler!
mu88

9

MS SQL Server 2012'yi kullanarak 3 temel adım gerçekleştirmeniz gerekir:

  1. İlk olarak, .sqlyalnızca kaynak DB'nin yapısını içeren dosya oluşturun

    • doğrudan kaynağa DB tıklayın ve ardından Görevler sonra kodları oluştur
    • sihirbazı takip edin ve .sqldosyayı yerel olarak kaydedin
  2. İkinci olarak, kaynak DB'yi .sqldosyadaki hedef olanla değiştirin

    • Hedef dosya üzerinde sağ tıklayın, seçmek Yeni Sorgu ve Ctrl-H(veya Düzen - Bul ve değiştir - Hızlı yerine )
  3. Son olarak, verilerle doldurun

    • Hedef DB'ye sağ tıklayın, ardından Görevler ve Verileri İçe Aktar'ı seçin
    • Veri kaynağı açılır listesi " SQL sunucusu için .net framework veri sağlayıcısı " olarak ayarlandı + DATA ex altında bağlantı dizesi metin alanını ayarlayın:Data Source=Mehdi\SQLEXPRESS;Initial Catalog=db_test;User ID=sa;Password=sqlrpwrd15
    • hedef ile aynı şeyi yap
    • transfer etmek istediğiniz tabloyu işaretleyin veya tümünü işaretlemek için "source: ..."

Bitirdiniz.


Bu arada, sanırım İthalat Veri hedef tablolarda yoksa tablolar oluşturabilirsiniz .. basit çözüm +1
Khurram Ishaque

6

SQL Server 2008 R2'de, veritabanını bir dosya olarak bir klasöre yedekleyin. Sonra "Veritabanı" klasöründe görünen geri yükleme seçeneğini seçin. Sihirbazda, hedef veritabanında istediğiniz yeni adı girin. Ve frrom dosyasını geri yükle'yi seçin ve yeni oluşturduğunuz dosyayı kullanın. Ben jsut yaptı ve çok hızlı (benim DB küçük, ama yine de) Pablo.


4

Veritabanı çok büyük değilse, SQL Server Management Studio Express'teki 'Script Database' komutlarına, explorer'daki veritabanı öğesinin kendisinin bağlam menüsündedir.

Ne yazılacağını seçebilirsiniz; elbette nesneleri ve verileri istiyorsunuz. Daha sonra komut dosyasının tamamını tek bir dosyaya kaydedersiniz. Sonra veritabanını yeniden oluşturmak için bu dosyayı kullanabilirsiniz; USEüstteki komutun uygun veritabanına ayarlandığından emin olun .


1
Teşekkürler, veritabanı ancak oldukça büyük, (bir konser etrafında) bu yüzden kötü şeyler olabilir :-)
Sergio

2
Sağ; o zaman bu en iyi yol değil. Bunun yerine, yeni veritabanında yapıyı oluşturmak için Komut Dosyası Veritabanını ve ardından verileri taşımak için İçe / Dışa Aktar komutunu kullanabilirsiniz. Önce Komut Dosyası Veritabanını yaptığınızdan emin olun; İçe / Dışa Aktar tabloları yoksa oluşturur ve nasıl yaptığını beğenmeyebilirsiniz.
Andrew Barber

4

Bu yoruma dayanan çözüm: https://stackoverflow.com/a/22409447/2399045 . Sadece ayarları yapın: DB adı, geçici klasör, db dosyaları klasörü. Ve çalıştırdıktan sonra "sourceDBName_yyyy-aa-gg" biçiminde Ad ile DB kopyasına sahip olacaksınız.

-- 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

Joe yanıtına dayalı komut dosyası ( ayırma, dosyaları kopyalama, her ikisini de ekleme ).

  1. Managment Studio'yu Yönetici hesabı olarak çalıştırın.

Gerekli değil, ancak erişim yürütülürken erişim reddedildi.

  1. SQL sunucusunu xp_cmdshel yürütmek için yapılandırma
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
  1. Komut dosyasını çalıştırın, ancak db adlarınızı @dbNameve @copyDBNamedeğişkenlerinizi daha önce yazın.
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

Yeni bir veritabanı oluşturabilir ve sonra görevlere gidebilir, verileri içe aktarabilir ve yeni oluşturduğunuz veritabanına çoğaltmak istediğiniz veritabanındaki tüm verileri alabilirsiniz.


2

İçe / dışa aktarma sihirbazını kullanarak hile yapan başka bir yol , önce boş bir veritabanı oluşturun, ardından kaynak veritabanına sahip sunucunuz olan kaynağı seçin ve sonra hedefte hedef veritabanıyla aynı sunucuyu seçin (boş veritabanını kullanarak) önce oluşturdunuz), ardından bitir

Tüm tabloları oluşturacak ve tüm verileri yeni veritabanına aktaracak,

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.