什么是复制数据库的最好方法?(What is the best way to copy a data

2019-08-23 00:53发布

当我想要做一个数据库的副本,我总是创建一个新的空数据库,然后恢复现有数据库的备份到它。 不过,我想知道,如果这真的是最不容易出错,最复杂,最有效的方式做到这一点?

Answer 1:

备份和恢复是我所知道的最直接的方式。 你必须在服务器之间小心,因为安全证书不来与恢复的数据库。



Answer 2:

它可以跳过创建空数据库的步骤。 您可以创建新的数据库作为恢复过程的一部分。

其实,这是我知道的最简单,最好的方法克隆数据库。 您可以通过脚本备份消除错误和恢复过程,而不是通过SQL Server Management Studio中运行它

还有,你可以探索其他两个选项:

  1. 分离数据库复制.mdf文件和重新连接。
  2. 使用SQL Server集成服务(SSIS)将所有对象复制过来

我建议用备份坚持和恢复,如有必要自动化。



Answer 3:

下面是一个动态sql脚本我已经在过去使用。 它可以进一步修改,但它会给你的基础知识。 我喜欢它编写脚本,以避免您可以使用Management Studio中的错误:


Declare @OldDB varchar(100)
Declare @NewDB varchar(100)
Declare @vchBackupPath varchar(255)
Declare @query varchar(8000)


/*Test code to implement 
Select @OldDB = 'Pubs'
Select @NewDB = 'Pubs2'
Select @vchBackupPath = '\\dbserver\C$\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Backup\pubs.bak'
*/

SET NOCOUNT ON;

Select @query = 'Create Database ' + @NewDB
exec(@query)

Select @query = '
Declare @vBAKPath varchar(256)
declare @oldMDFName varchar(100)
declare @oldLDFName varchar(100)
declare @newMDFPath varchar(100)
declare @newLDFPath varchar(100)
declare @restQuery varchar(800)

select @vBAKPath = ''' + @vchBackupPath + '''
select @oldLDFName = name from ' + @OldDB +'.dbo.sysfiles where filename like ''%.ldf%''
select @oldMDFName = name from  ' + @OldDB +'.dbo.sysfiles where filename like ''%.mdf%''
select @newMDFPath = physical_name from ' + @NewDB +'.sys.database_files where type_desc = ''ROWS''
select @newLDFPath = physical_name from ' + @NewDB +'.sys.database_files where type_desc = ''LOG''

select @restQuery = ''RESTORE DATABASE ' + @NewDB + 
' FROM DISK = N'' + '''''''' + @vBAKpath + '''''''' + 
'' WITH MOVE N'' + '''''''' + @oldMDFName + '''''''' +  
'' TO N'' + '''''''' + @newMDFPath + '''''''' +  
'', MOVE N'' + '''''''' + @oldLDFName + '''''''' +  
'' TO N'' + '''''''' + @newLDFPath + '''''''' +  
'', NOUNLOAD, REPLACE, STATS = 10''

exec(@restQuery)
--print @restQuery'


exec(@query)







Answer 4:

发布到提供者的功能为我伟大的工作。 见斯科特谷的博客文章 。

如果您需要在展鹏软件的工具,一些真正健壮的外观在这里 ......如果你是做多的SQL可言,这些都是值得的$$。



Answer 5:

::================ BackUpAllMyDatabases.cmd ============= START
::BackUpAllMyDatabases.cmd
:: COMMAND LINE BATCH SCRIPT FOR TAKING BACKUP OF ALL DATABASES 

::RUN THE SQL SCRIPT VIA THE COMMAND LINE WITH LOGGING 
sqlcmd -S localhost -e  -i "BackUpAllMyDatabases.sql" -o Result_Of_BackUpAllMyDatabases.log

::VIEW THE RESULTS
Result_Of_BackUpAllMyDatabases.log

::pause
::================ BackUpAllMyDatabases.cmd ============= END


--=================================================BackUpAllMyDatabases.sql start
DECLARE @DBName varchar(255)

DECLARE @DATABASES_Fetch int

DECLARE DATABASES_CURSOR CURSOR FOR
    select
        DATABASE_NAME   = db_name(s_mf.database_id)
    from
        sys.master_files s_mf
    where
       -- ONLINE
        s_mf.state = 0 

       -- Only look at databases to which we have access
    and has_dbaccess(db_name(s_mf.database_id)) = 1 

        -- Not master, tempdb or model
    --and db_name(s_mf.database_id) not in ('Master','tempdb','model')
    group by s_mf.database_id
    order by 1

OPEN DATABASES_CURSOR

FETCH NEXT FROM DATABASES_CURSOR INTO @DBName

WHILE @@FETCH_STATUS = 0
BEGIN
    declare @DBFileName varchar(256)    
    set @DBFileName = @DbName + '_' + replace(convert(varchar, getdate(), 112), '-', '.') + '.bak'
--REMEMBER TO PUT HERE THE TRAILING \ FOR THE DIRECTORY !!!
    exec ('BACKUP DATABASE [' + @DBName + '] TO  DISK = N''D:\DATA\BACKUPS\' + 
        @DBFileName + ''' WITH NOFORMAT, INIT,  NAME = N''' + 
        @DBName + '-Full Database Backup'', SKIP, NOREWIND, NOUNLOAD,  STATS = 100')

    FETCH NEXT FROM DATABASES_CURSOR INTO @DBName
END

CLOSE DATABASES_CURSOR
DEALLOCATE DATABASES_CURSOR

--BackUpAllMyDatabases==========================end

--======================RestoreDbFromFile.sql start
-- Restore database from file
-----------------------------------------------------------------
use master
go

declare @backupFileName varchar(100), @restoreDirectory varchar(100),
@databaseDataFilename varchar(100), @databaseLogFilename varchar(100),
@databaseDataFile varchar(100), @databaseLogFile varchar(100),
@databaseName varchar(100), @execSql nvarchar(1000)

-- Set the name of the database to restore
set @databaseName = 'ReplaceDataBaseNameHere'
-- Set the path to the directory containing the database backup
set @restoreDirectory = 'ReplaceRestoreDirectoryHere' -- such as 'c:\temp\'

-- Create the backup file name based on the restore directory, the database name and today's date

@backupFileName = @restoreDirectory + @databaseName + '-' + replace(convert(varchar, getdate(), 110), '-', '.') + '.bak'


-- set @backupFileName = 'D:\DATA\BACKUPS\server.poc_test_fbu_20081016.bak'

-- Get the data file and its path
select @databaseDataFile = rtrim([Name]),
@databaseDataFilename = rtrim([Filename])
from master.dbo.sysaltfiles as files
inner join
master.dbo.sysfilegroups as groups
on

files.groupID = groups.groupID
where DBID = (
select dbid
from master.dbo.sysdatabases
where [Name] = @databaseName
)

-- Get the log file and its path
select @databaseLogFile = rtrim([Name]),
@databaseLogFilename = rtrim([Filename])
from master.dbo.sysaltfiles as files
where DBID = (
select dbid
from master.dbo.sysdatabases
where [Name] = @databaseName
)
and
groupID = 0

print 'Killing active connections to the "' + @databaseName + '" database'

-- Create the sql to kill the active database connections
set @execSql = ''
select @execSql = @execSql + 'kill ' + convert(char(10), spid) + ' '
from master.dbo.sysprocesses
where db_name(dbid) = @databaseName
and
DBID <> 0
and
spid <> @@spid
exec (@execSql)

print 'Restoring "' + @databaseName + '" database from "' + @backupFileName + '" with '
print ' data file "' + @databaseDataFile + '" located at "' + @databaseDataFilename + '"'
print ' log file "' + @databaseLogFile + '" located at "' + @databaseLogFilename + '"'

set @execSql = '
restore database [' + @databaseName + ']
from disk = ''' + @backupFileName + '''
with
file = 1,
move ''' + @databaseDataFile + ''' to ' + '''' + @databaseDataFilename + ''',
move ''' + @databaseLogFile + ''' to ' + '''' + @databaseLogFilename + ''',
norewind,
nounload,
replace'

exec sp_executesql @execSql

exec('use ' + @databaseName)
go

-- If needed, restore the database user associated with the database
/*
exec sp_revokedbaccess 'myDBUser'
go

exec sp_grantdbaccess 'myDBUser', 'myDBUser'
go

exec sp_addrolemember 'db_owner', 'myDBUser'
go

use master
go
*/
--======================RestoreDbFromFile.sql


文章来源: What is the best way to copy a database?