352

I have an MS SQL Server 2008 Express system which contains a database that I would like to 'copy and rename' (for testing purposes) but I am unaware of a simple way to achieve this.

I notice that in the R2 version of SQL Server there is a copy database wizard, but sadly I can't upgrade.

The database in question is around a gig. I attempted to restore a backup of the database I want to copy into a new database, but with no luck.

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
Sergio
  • 9,761
  • 16
  • 60
  • 88
  • 2
    Restoring a backup should work. Can you provide more detail about how that failed? – Ed Harper Sep 30 '10 at 11:23
  • 8
    I realised I made a mistake when restoring from backup. I created a new empty DB first and attempted to restore the backup from there. What I should have done is bring up the restore dialog and type the name of the new database in there instead of creating it first. Doing this cloned the database nicely! – Sergio Oct 01 '10 at 12:53
  • When I tried to restore the database under a different name it just gave me: "Restore of database 'My Database (New)' failed. ... Exclusive access could not be obtained because the database is in use." - the database under its new name doesn't exist so how can it be in use?! – Matt Arnold Apr 28 '21 at 13:12

17 Answers17

480
  1. Install Microsoft SQL Management Studio, which you can download for free from Microsoft's website:

    Version 2008

    Microsoft SQL Management Studio 2008 is part of SQL Server 2008 Express with Advanced Services

    Version 2012

    Click download button and check ENU\x64\SQLManagementStudio_x64_ENU.exe

    Version 2014

    Click download button and check MgmtStudio 64BIT\SQLManagementStudio_x64_ENU.exe

  2. Open Microsoft SQL Management Studio.

  3. Backup original database to .BAK file (db -> Task -> Backup).
  4. Create empty database with new name (clone). Note comments below as this is optional.
  5. Click to clone database and open restore dialog (see image) restore dialog
  6. Select Device and add the backup file from step 3. add backup file
  7. Change destination to test database change destination
  8. Change location of database files, it must be different from the original. You can type directly into text box, just add postfix. (NOTE: Order is important. Select checkbox, then change the filenames.) change location
  9. Check WITH REPLACE and WITH KEEP_REPLICATION with replace
MarredCheese
  • 17,541
  • 8
  • 92
  • 91
Tomas Kubes
  • 23,880
  • 18
  • 111
  • 148
  • 123
    1. Don't create an empty database and restore the .bak file on to it. 2. Use 'Restore Database' option accessible by right clicking the "Databases" branch of the SQL Server Management Studio and provide the database name while providing the source to restore. ref: http://stackoverflow.com/questions/10204480/the-backup-set-holds-a-backup-of-a-database-other-than-the-existing – taynguyen Sep 15 '15 at 13:52
  • I have the same note as for the accepted answer - you're missing (for me the main) point, what software you're using to do that? – David Ferenczy Rogožan Oct 06 '15 at 15:40
  • 1
    Microsoft SQL Management Studio - it is free – Tomas Kubes Oct 06 '15 at 17:04
  • 1
    NOTE: The order in step 8 (I fixed the markdown numbering!) is important. If you change the filenames then click the checkbox your filenames revert. Then everything will appear to succeed but in Management Studio your new DB will have (Restoring...) after it - until you stop SQL, rename or delete the files, restart SQL [as in this answer](http://stackoverflow.com/questions/520967/sql-server-database-stuck-in-restoring-state/837220#837220) then do it all again. – Nick Westgate Mar 29 '17 at 10:56
  • 7
    Doesn't work - "Exclusive Access could not be obtained because the database is in use". – Emanuele Ciriachi May 22 '17 at 17:23
  • 1
    It does work. @EmanueleCiriachi, you need to make sure you've renamed the target files in the Data folder, as explained above. Well it worked for me. I also ticked the Close existing option. – Fandango68 Oct 17 '17 at 06:38
  • 1
    Perfect. You can also chose "Database" on step 6, to make a copy from database directly. – raiserle Feb 19 '18 at 09:40
  • Sometimes the 'Copy Database' option fails due to odd Windows file system permission settings. So this 'Restore Database' is a good workaround. – Terran Apr 03 '18 at 12:31
  • If you do taynguyen's 'Restore Database' method, you don't have to check "overwrite the existing database" in step 9. – pianoJames Jul 30 '18 at 19:24
  • 26
    I also had to uncheck "Take tail-log backup before restore". This was checked by default and resulted in the "Exclusive Access could not be obtained because the database is in use" error. – Turnip Nov 28 '18 at 09:41
  • 5
    My original database got stuck on "Restoring" – dvgrape Dec 26 '18 at 19:37
  • I was unable to get around the "database is in use" error that @EmanueleCiriachi mentioned. – Grant Birchmeier Feb 22 '21 at 23:41
  • Make also sure that Tail-Log backup is unticked with its sub options to avoid destroying source db ! – abdelgrib May 12 '21 at 14:14
  • @Turnip's comment was super helpful. I knew how to do the thing in general, but was stuck on "database is in use" [this comment](https://stackoverflow.com/questions/3829271/how-can-i-clone-an-sql-server-database-on-the-same-server-in-sql-server-2008-exp/3833723#comment93901548_26265624) – RoboticRenaissance Oct 07 '21 at 17:36
126

Right-click the database to clone, click Tasks, click Copy Database.... Follow the wizard and you're done.

user3071284
  • 6,955
  • 6
  • 43
  • 57
DForck42
  • 19,789
  • 13
  • 59
  • 84
  • I think that is only available in the R2 release of SQL Server sadly :-( – Sergio Oct 01 '10 at 12:51
  • umm... no? it should be available in 2005+, cause i'm looking at 2008, and i'm fairly certain it was available in 2005. it might not be available in express though. – DForck42 Oct 01 '10 at 13:12
  • 8
    here is how it works in express: http://stackoverflow.com/questions/4269450/copy-a-database-within-sql-server-express – Th 00 mÄ s May 02 '13 at 20:13
  • 2
    This doesn't work if you have encrypted objects in your database. – cjbarth Mar 17 '14 at 21:09
  • 1
    I would say, that the main point is actually where to do it? What you described is pretty intuitive. I have tried exactly that in some tools (0xDBE, Visual Studio SQL Server Object Explorer) before, but didn't find such feature there. – David Ferenczy Rogožan Oct 06 '15 at 15:35
  • Doesn't work - "Exclusive Access could not be obtained because the database is in use". – Emanuele Ciriachi May 22 '17 at 17:23
  • This worked for me, using the "Use the detach and attach method" in the wizard. – ashilon Jun 19 '17 at 09:39
  • @ThomasS the solution ("restore as" ; change .mdf and .ldf) is there https://stackoverflow.com/a/9991507/2375207 – nicolallias Oct 13 '17 at 08:56
  • 5
    Not possible! Tasks -> No menu item to copy database – raiserle Feb 19 '18 at 09:38
  • @raiserle You need to create an empty db with the same name on the target server and right-click on that. – Alan B Nov 12 '18 at 09:14
  • Did NOT work for me, ended up with source database in single-user mode and no new database (same result with or without "detach and attach method"). I followed https://stackoverflow.com/a/26265624/5526708 instead, and it worked! – flo5783 Nov 20 '18 at 17:00
  • 1
    You need SQL Server Agent on the destination server. – Jan Sep 23 '22 at 22:07
113

You could try to detach the database, copy the files to new names at a command prompt, then attach both DBs.

In SQL:

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

At Command prompt (I've simplified the file paths for the sake of this example):

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

In SQL again:

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
RMalke
  • 4,048
  • 29
  • 42
Joe Stefanelli
  • 132,803
  • 19
  • 237
  • 235
  • 10
    `select * from OriginalDB.sys.sysfiles` to find the location of the DB's files. – JohnLBevan Jul 23 '14 at 00:39
  • Yeah, I also like this solution the most, since it doesn't require any special tools. But I wasn't able to create a NewDB, it says `Permission denied` on `.mdf` file. I don't need it now, I just needed a backup of the original DB, so I can overwrite the original DB with it later, I'm just curious why I'm getting such error. – David Ferenczy Rogožan Oct 06 '15 at 16:02
  • 3
    You don't have to detach the original database if you can stop the sql service, copy the mdf and ldf file, rename them for your new database, start the sql service again and just run the last create database command under master: USE master; GO CREATE DATABASE NewDB ON (FILENAME = 'C:\NewDB.mdf'), (FILENAME = 'C:\NewDB.ldf') FOR ATTACH; GO – danpop Dec 06 '17 at 14:35
36

It turns out that I had attempted to restore from a backup incorrectly.

Initially I created a new database and then attempted to restore the backup here. What I should have done, and what worked in the end, was to bring up the restore dialog and type the name of the new database in the destination field.

So, in short, restoring from a backup did the trick.

Thanks for all the feedback and suggestions guys

Sergio
  • 9,761
  • 16
  • 60
  • 88
  • When I do this, the dialog tells me the files are in the same location as the database I originally backed up from. So I don't have the guts to restore, fearing that the files will be overwritten. – Niels Brinch Nov 08 '12 at 13:14
  • 2
    Neils, the files are the same, by default, in the snapshot you took. You can change the names of them to create new files for the newly named database. – Colin Dabritz May 01 '14 at 19:35
  • PS: This method requires SQL Agent service, make sure it is running before starting the db copy operation. – dvdmn Aug 21 '14 at 16:38
  • You have now helped me three times with this answer. I keep forgetting about typing it in instead of creating it. +beer – Piotr Kula Oct 29 '14 at 15:21
  • This and renaming the .mdf and .log files in the 'Files' window worked for me. – Wollan Mar 16 '16 at 10:47
27

This is the script I use. A bit tricky but it works. Tested on 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:\DB SQL\MSSQL11.MSSQLSERVER\MSSQL\Backup\' + @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
bluish
  • 26,356
  • 27
  • 122
  • 180
  • 2
    In my environment, the filenames didn't match the db name (having come from _another_ restore) so I needed `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)` and a separate variable for @sourceDb_data with a similar query (substituting in `files.type=0`). HTH! – Dan Caseley Sep 14 '16 at 10:05
  • Getting an error: `Msg 137, Level 15, State 2, Line 25 Must declare the scalar variable "@destDb".` Turns out I had put a `GO` statement between variable declaration and its usage, we can't do that, see: https://stackoverflow.com/a/55347161/6184866 – Raman Sinclair Jan 19 '21 at 05:20
  • 1
    Very use(r)full script indeed... ;) One small syntax correction: Just put a `'@'` on variable at line 11: `SET @backupPath = 'E:\tmp\' + @sourceDb + '.bak' --ATTENTION: file must already exist and SQL Server must have access to it.` In addition you can set the backup folder on: ` E:\DB SQL\MSSQL11.MSSQLSERVER\MSSQL\Backup\ ` to avoid setting security access rights. – Andreas Venieris Apr 02 '21 at 09:30
18

From SSMS :

1 - Backup original database to .BAK file (your_source_db -> Task -> Backup).

2 - Right clicking the "Databases" and 'Restore Database'

3 - Device > ... (button) > Add > select the your_source_db.bak

4 - In 'General' tab, in 'Destination' section, rename in 'Database' your_source_db to new_name_db

5 - In 'Files' tab, tick 'Relocate all files to folder',

  • Rename in 'Restore As' column the two lignes to keep consistency with new_name_db (.mdf, _log.ldf)

6 - In 'Options' tab, in 'Restore options' section, tick two fist options ('Overwrite...', 'Preserve...') and for 'Recovery state' : 'RESTORE WITH RECOVERY'

  • Make also sure that in 'Tail-Log backup' section options are unticked to avoid keeping source db in 'restoring state' !

enter image description here

Vy Do
  • 46,709
  • 59
  • 215
  • 313
abdelgrib
  • 843
  • 7
  • 11
15

None of the solutions mentioned here worked for me - I am using SQL Server Management Studio 2014.

Instead I had to uncheck the "Take tail-log backup before restore" checkbox in the "Options" screen: in my version it is checked by default and prevents the Restore operation to be completed. After unchecking it, the Restore operation proceeded without issues.

enter image description here

Emanuele Ciriachi
  • 2,216
  • 2
  • 26
  • 39
11

Using MS SQL Server 2012, you need to perform 3 basic steps:

  1. First, generate .sql file containing only the structure of the source DB

    • right click on the source DB and then Tasks then Generate Scripts
    • follow the wizard and save the .sql file locally
  2. Second, replace the source DB with the destination one in the .sql file

    • Right click on the destination file, select New Query and Ctrl-H or (Edit - Find and replace - Quick replace)
  3. Finally, populate with data

    • Right click on the destination DB, then select Tasks and Import Data
    • Data source drop down set to ".net framework data provider for SQL server" + set the connection string text field under DATA ex: Data Source=Mehdi\SQLEXPRESS;Initial Catalog=db_test;User ID=sa;Password=sqlrpwrd15
    • do the same with the destination
    • check the table you want to transfer or check box besides "source: ..." to check all of them

You are done.

David Ferenczy Rogožan
  • 23,966
  • 9
  • 79
  • 68
Mehdi Benkirane
  • 437
  • 4
  • 7
7

In SQL Server 2008 R2, back-up the database as a file into a folder. Then chose the restore option that appears in the "Database" folder. In the wizard enter the new name that you want in the target database. And choose restore frrom file and use the file you just created. I jsut did it and it was very fast (my DB was small, but still) Pablo.

pabloelustondo
  • 2,196
  • 3
  • 19
  • 23
7

If the database is not very large, you might look at the 'Script Database' commands in SQL Server Management Studio Express, which are in a context menu off the database item itself in the explorer.

You can choose what all to script; you want the objects and the data, of course. You will then save the entire script to a single file. Then you can use that file to re-create the database; just make sure the USE command at the top is set to the proper database.

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
  • 1
    Thanks, the database is quite large however, (around a gig) so I think bad things may happen :-) – Sergio Sep 30 '10 at 09:57
  • 2
    Right; that's not the best way then. Instead, you could use the Script Database to just create the structure in the new database, and then Import/Export to move the data. Just be sure you do the Script Database first; Import/Export will create the tables if they don't exist, and you may not like how it does it. – Andrew Barber Sep 30 '10 at 10:02
6

Another way that does the trick by using import/export wizard, first create an empty database, then choose the source which is your server with the source database, and then in the destination choose the same server with the destination database (using the empty database you created at first), then hit finish

It will create all tables and transfer all the data into the new database,

LearnByReading
  • 1,813
  • 4
  • 21
  • 43
Mohanad Kaleia
  • 793
  • 1
  • 9
  • 22
6

The solution, based on this comment: https://stackoverflow.com/a/22409447/2399045 . Just set settings: DB name, temp folder, db files folder. And after run you will have the copy of DB with Name in "sourceDBName_yyyy-mm-dd" format.

-- 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
  • 491
  • 7
  • 14
  • 1
    Pavel, thank you for this answer. If you don't mind, I would add dynamic SQL so it could rename Logical file name: `DECLARE @DynamicSQL [nvarchar](2000);` `SET @DynamicSQL = CONCAT('ALTER DATABASE [', @DestinationDBName, '] MODIFY FILE (NAME = ''', @SourceDBName, ''', NEWNAME = ''', @DestinationDBName, ''');');` `SET @DynamicSQL = CONCAT(@DynamicSQL, 'ALTER DATABASE [', @DestinationDBName, '] MODIFY FILE (NAME = ''', CONCAT(@SourceDBName, '_log'), ''', NEWNAME = ''', CONCAT(@DestinationDBName, '_log'), ''');');` `EXECUTE (@DynamicSQL);` – GenTech Dec 14 '20 at 23:19
5

Script based on Joe answer (detach, copy files, attach both).

  1. Run Managment Studio as Administrator account.

It's not necessary, but maybe access denied error on executing.

  1. Configure sql server for execute xp_cmdshel
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
  1. Run script, but type your db names in @dbName and @copyDBName variables before.
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
Jean
  • 4,911
  • 3
  • 29
  • 50
Evgeny Ivanov
  • 504
  • 6
  • 14
4

You could just create a new database and then go to tasks, import data, and import all the data from the database you want to duplicate to the database you just created.

4

This program copies a database to the same server under a different name. I relied on examples given on this site with some improvements.

-- Copies a database to the same server
-- Copying the database is based on backing up the original database and restoring with a different name

DECLARE @sourceDb nvarchar(50);    
DECLARE @destDb nvarchar(50);
DECLARE @backupTempDir nvarchar(200)

SET @sourceDb =  N'Northwind'         -- The name of the source database
SET @destDb =    N'Northwind_copy'    -- The name of the target database
SET @backupTempDir = N'c:\temp'       -- The name of the temporary directory in which the temporary backup file will be saved
-- --------- ---

DECLARE @sourceDb_ROWS nvarchar(50);  
DECLARE @sourceDb_LOG nvarchar(50);
DECLARE @backupPath nvarchar(400); 
DECLARE @destMdf nvarchar(100);
DECLARE @destLdf nvarchar(100);
DECLARE @sqlServerDbFolder nvarchar(100);

Declare @Ret as int = -1
Declare @RetDescription nvarchar(200) = ''

-- Temporary backup file name
SET @backupPath = @backupTempDir+ '\TempDb_' + @sourceDb + '.bak'    

-- Finds the physical location of the files on the disk
set @sqlServerDbFolder = (SELECT top(1) physical_name as dir
                           FROM sys.master_files where DB_NAME(database_id) = @sourceDb  );

-- Clears the file name and leaves the directory name
set @sqlServerDbFolder = REVERSE(SUBSTRING(REVERSE(@sqlServerDbFolder), CHARINDEX('\', REVERSE(@sqlServerDbFolder)) + 1, LEN(@sqlServerDbFolder))) + '\'

-- Finds the logical name for the .mdf file
set @sourceDb_ROWS = (SELECT f.name LogicalName FROM sys.master_files f INNER JOIN sys.databases d ON d.database_id = f.database_id
                      where d.name = @sourceDb  and   f.type_desc = 'ROWS' )

-- Finds the logical name for the .ldf file
set @sourceDb_LOG = (SELECT f.name LogicalName FROM sys.master_files f INNER JOIN sys.databases d ON d.database_id = f.database_id
                      where d.name = @sourceDb  and   f.type_desc = 'LOG' )

-- Composes the names of the physical files for the new database  
SET @destMdf = @sqlServerDbFolder + @destDb + N'.mdf'
SET @destLdf = @sqlServerDbFolder + @destDb + N'_log' + N'.ldf'

-- If the source name is the same as the target name does not perform the operation
if @sourceDb <> @destDb      
    begin 

    -- Checks if the target database already exists
    IF Not EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = @destDb)
    begin 
        -- Checks if the source database exists
        IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = @sourceDb) and (@sqlServerDbFolder is not null)
        begin 

            -- Opens the permission to run xp_cmdshell
            EXEC master.dbo.sp_configure 'show advanced options', 1
            RECONFIGURE WITH OVERRIDE
            EXEC master.dbo.sp_configure 'xp_cmdshell', 1
            RECONFIGURE WITH OVERRIDE
         
            -- If the temporary backup directory does not exist it creates it
            declare @md as nvarchar(100) = N'if not exist ' + @backupTempDir + N' md ' +@backupTempDir  
            exec xp_cmdshell  @md,  no_output

            -- Creates a backup to the source database to the temporary file
            BACKUP DATABASE @sourceDb TO DISK = @backupPath 

            -- Restores the database with a new name
            RESTORE DATABASE @destDb FROM DISK = @backupPath
            WITH REPLACE, 
            MOVE @sourceDb_ROWS TO @destMdf, 
            MOVE @sourceDb_LOG TO  @destLdf

            -- Deletes the temporary backup file
            declare @del as varchar(100) = 'if exist ' + @backupPath +' del ' +@backupPath 
            exec xp_cmdshell  @del ,  no_output

            -- Close the permission to run xp_cmdshell
            EXEC master.dbo.sp_configure 'xp_cmdshell', 0
            RECONFIGURE WITH OVERRIDE
            EXEC master.dbo.sp_configure 'show advanced options', 0
            RECONFIGURE WITH OVERRIDE
         
            set @ret = 1
            set @RetDescription = 'The ' +@sourceDb + ' database was successfully copied to ' + @destDb 
        
        end
        else
        begin
          set @RetDescription = 'The source database '''+ @sourceDb + ''' is not exists.'
          set @ret = -3
        end

    end
    else
    begin
      set @RetDescription = 'The target database '''+ @destDb + ''' already exists.'
      set @ret = -4
    end
end
else
begin
  set @RetDescription = 'The target database ''' +@destDb + ''' and the source database '''+ @sourceDb + ''' have the same name.'
  set @ret = -5
end

select @ret as Ret, @RetDescription as RetDescription
Dror Cohen
  • 41
  • 3
1

<!doctype html>

<head>
    <title>Copy Database</title>
</head>

<body>
    
    <?php
    
    $servername = "localhost:xxxx";
    $user1 = "user1";
    $pw1 = "pw1";
    $db1 = "db1";
    
    $conn1 = new mysqli($servername,$user1,$pw1,$db1);
    
    if($conn1->connect_error) {
        die("Conn1 failed: " . $conn1->connect_error);
    }
    
    $user2 = "user2";
    $pw2 = "pw2";
    $db2 = "db2";
    
    $conn2 = new mysqli($servername,$user2,$pw2,$db2);
    
    if($conn2->connect_error) {
        die("Conn2 failed: " . $conn2->connect_error);
    }
    
    $sqlDB1 = "SELECT * FROM table1";
    $resultDB1 = $conn1->query($sqlDB1);
    
    if($resultDB1->num_rows > 0) {
        while($row = $resultDB1->fetch_assoc()) {
            $sqlDB2 = "INSERT INTO table2 (col1, col2) VALUES ('" . $row["tableRow1"] . "','" . $row["tableRow2"] . "')";
            $resultDB2 = $conn2->query($sqlDB2);
        }
    }else{
        echo "0 results";
    }
    
    $conn1->close();
    $conn2->close();
    
    ?>
    
</body>
  • 1
    Welcome to stack-overflow .... please read help center, section `how to ask good question` here https://stackoverflow.com/help/how-to-ask and you can get tour and give one badge here https://stackoverflow.com/tour – Amirhossein Oct 11 '21 at 10:16
0

If you are MS SQL 2014 and newer;

DBCC CLONEDATABASE (CurrentDBName, NewDBName)
GO

Details;

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
  • 3
    CLONEDATABASE Generates a schema-only clone of a database. This answer does not solve the problem of the question. – Alvimar Dec 19 '22 at 12:59
  • 1
    @Alvimar I've tried this solution and did not care about the comment. After that I truncated the tables of source Database to make them clean! Then I've saw that destination database is empty. So I downvote this question since it is misleading. – VSB May 30 '23 at 08:34
  • 1
    When you run this `CLONEDATABASE` it shows the alert that destination database can be used for diagnostic and it is not suitable for production use. – VSB May 30 '23 at 08:35