Sql server 将SQL Server数据库复制到测试数据库的最简单方法?
获取SQL Server数据库并制作其测试副本的最简单方法是什么 我已经浏览了一些现有的主题,但不确定是否有更简单的方法。我有一个数据库发布者。我希望能够将这两个数据库保持在同一台服务器上Sql server 将SQL Server数据库复制到测试数据库的最简单方法?,sql-server,database,sql-server-2008,Sql Server,Database,Sql Server 2008,获取SQL Server数据库并制作其测试副本的最简单方法是什么 我已经浏览了一些现有的主题,但不确定是否有更简单的方法。我有一个数据库发布者。我希望能够将这两个数据库保持在同一台服务器上 更新:我使用MicrosoftSQLServer发布向导来编写文件脚本、创建新数据库、添加“UseDB”并执行脚本。这似乎很管用。不建议附加/分离,因为如果它是全文搜索数据库或日志丢失,它会将链接保留回原始位置。删除数据库(意味着使其脱机),复制mdf文件,然后重新附加原始和副本。我只会创建数据库,然后使用“
更新:我使用MicrosoftSQLServer发布向导来编写文件脚本、创建新数据库、添加“UseDB”并执行脚本。这似乎很管用。不建议附加/分离,因为如果它是全文搜索数据库或日志丢失,它会将链接保留回原始位置。删除数据库(意味着使其脱机),复制mdf文件,然后重新附加原始和副本。我只会创建数据库,然后使用“导入数据”在SS Mgmt Studio中执行任务,以复制数据。或者您可以备份生产数据库并将其恢复到测试数据库中
也许不是最简单的方法,但是很低调。您还可以将数据写入一个文件,并将其回放到一个新的数据库中——这需要一段时间,但对于版本控制之类的事情来说,它很方便,而且它是人类可读的(嗯,“开发人员”)。我总是先备份它,然后恢复到不同的名称/文件集;
或者您可以创建一个空数据库&使用恢复“向导”启用覆盖和更改恢复文件路径。我经常使用完全相同架构的测试和实时数据库。它们通常具有存储过程,根据开发更改的状态进行更改。所以我不能总是备份和恢复。我编写了一个查询,它遍历数据库中的所有表,删除数据。然后再次循环并从实时数据库插入。 在下面的示例中,我的测试数据库称为WorkflowTest,而我的live称为Workflow,但您只需替换变量中的数据库名称即可。只需确保连接到测试数据库即可 但是表名和列是完全任意的。 我循环多次,因为我不想担心外键约束。某些删除/插入操作将失败,因为它希望数据存在于另一个表中 我发现我的所有45个左右的表都在大约2-3个循环中完全重新填充 在Insert循环期间,它首先通过尝试打开identity_Insert来检查表是否具有标识列。如果这没有失败,那么它将构建一个insert语句,前面的标识为On,后面的标识为off。它必须在同一个EXEC语句中执行,因为EXEC中的命令在执行后会超出范围 事后看来,我想我本可以把所有的测试存储过程都写成alter语句,从活动数据库的备份中恢复测试数据库,然后执行alter语句。但我发现用户安全设置无法正确恢复,所以有时这也会带来麻烦
--获取测试数据库中所有表的列表
--第一个循环遍历它们并删除所有记录。
--如果遇到错误,它不会从#tablesNeedingCopy中删除该表,因此将重试。
--这是因为我们不知道删除的顺序,可能会遇到外键约束。
--它通常会在大约2个循环后从所有表中删除所有记录。
--第二步几乎相同,但它插入了数据
声明@CopyToDatabase varchar(100)
声明@CopyFromDatabase varchar(100)
set@CopyToDatabase='WorkflowTest'
设置@CopyFromDatabase='Workflow'
使用WorkflowTest--[连接到要复制到的数据库]
声明@sqlCommand varchar(最大值)
声明@columnNames varchar(最大值)
声明@tableName为NVARCHAR(100);
将@tableNameCursor声明为游标;
创建表#表需要复制
(
表_Name varchar(100)
)
插入到需要复制的表中
(表格名称)
选择表格名称
来自信息\u SCHEMA.TABLES
其中TABLE_TYPE='基表'
表名称与“sys%”不同
将@hasTableError声明为char(1)
声明@remaingtablecount int
声明@loopcontrolint
设置@loopControl=0
选择@remaingtablecount=count(*)
从#表需要复制
而(@remainingTableCount>0且@loopControl<10)
开始
设置@loopControl=@loopControl+1
设置@tableNameCursor=用于
选择表格名称
从#表需要复制
打开@tableNameCursor;
将下一步从@tableNameCursor提取到@tableName;
而@@FETCH\u STATUS=0
开始
set@hasTableError='N'
SET@sqlCommand='Delete from'+@tableName
打印@sqlCommand
开始尝试
exec(@sqlCommand)
结束尝试
开始捕捉
set@hasTableError='Y'
打印错误消息()
端接
如果(@hasTableError='N')
开始
--否则就把桌子留在里面
从#表中删除需要复制
其中Table_Name=@tableName
结束
将下一步从@tableNameCursor提取到@tableName;
结束
关闭@tableNameCursor;
取消分配@tableNameCursor;
选择@remaingtablecount=count(*)
从#表需要复制
结束
选择@remaingtablecount=count(*)
从#表需要复制
如果(@rema
-- Gets a list of all tables in the Test database
-- first loops through them and deletes all records.
-- if it encounters an error, it does not remove that table from #tablesNeedingCopy so it will try again.
-- this is because we don't know the order to delete and may encounter foreign key constraints.
-- It usually deletes all records from all tables after 2 or so loops.
-- the 2nd step is nearly identical, but instead it inserts the data
Declare @CopyToDatabase varchar(100)
declare @CopyFromDatabase varchar(100)
set @CopyToDatabase = 'WorkflowTest'
set @CopyFromDatabase = 'Workflow'
use WorkflowTest -- [Connect to Database that you want to copy to]
DECLARE @sqlCommand varchar(max)
declare @columnNames varchar(max)
DECLARE @tableName as NVARCHAR(100);
DECLARE @tableNameCursor as CURSOR;
create table #tablesNeedingCopy
(
Table_Name varchar(100)
)
insert into #tablesNeedingCopy
(Table_Name)
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
and Table_Name not like 'sys%'
declare @hasTableError as char(1)
declare @remainingTableCount int
declare @loopControl int
set @loopControl = 0
select @remainingTableCount = count(*)
from #tablesNeedingCopy
while (@remainingTableCount > 0 And @loopControl < 10)
begin
set @loopControl = @loopControl + 1
SET @tableNameCursor = CURSOR FOR
SELECT TABLE_NAME
FROM #tablesNeedingCopy
OPEN @tableNameCursor;
FETCH NEXT FROM @tableNameCursor INTO @tableName;
WHILE @@FETCH_STATUS = 0
BEGIN
set @hasTableError = 'N'
SET @sqlCommand = 'Delete from ' + @tableName
print @sqlCommand
begin try
exec (@sqlCommand)
end try
begin catch
set @hasTableError = 'Y'
print ERROR_MESSAGE()
end catch
if (@hasTableError = 'N')
begin
-- otherwise leave the table in
delete from #tablesNeedingCopy
where Table_Name = @tableName
end
FETCH NEXT FROM @tableNameCursor INTO @tableName;
END
CLOSE @tableNameCursor;
DEALLOCATE @tableNameCursor;
select @remainingTableCount = count(*)
from #tablesNeedingCopy
end -- end while
select @remainingTableCount = count(*)
from #tablesNeedingCopy
if (@remainingTableCount > 0)
begin
select Table_Name as DeleteTableNames
from #tablesNeedingCopy
end
delete from #tablesNeedingCopy
-------
insert into #tablesNeedingCopy
(Table_Name)
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
and Table_Name not like 'sys%'
declare @hasIdentityColumn as char(1)
set @loopControl = 0
select @remainingTableCount = count(*)
from #tablesNeedingCopy
while (@remainingTableCount > 0 And @loopControl < 10)
begin
set @loopControl = @loopControl + 1
SET @tableNameCursor = CURSOR FOR
SELECT TABLE_NAME
from #tablesNeedingCopy
OPEN @tableNameCursor;
FETCH NEXT FROM @tableNameCursor INTO @tableName;
WHILE @@FETCH_STATUS = 0
BEGIN
set @hasTableError = 'N'
set @hasIdentityColumn = 'Y'
SET @sqlCommand = 'SET IDENTITY_INSERT ' + @CopyToDatabase + '.dbo.' + @tableName + ' ON;' -- Database to copy to
begin try
print @sqlCommand
exec (@sqlCommand)
end try
begin catch
--print ERROR_MESSAGE()
set @hasIdentityColumn = 'N'
end catch
if (@hasTableError = 'N')
begin
SELECT top 1 @columnNames =
STUFF((SELECT N', ' + Column_Name
FROM INFORMATION_SCHEMA.COLUMNS AS t2
WHERE t2.TABLE_NAME=t.TABLE_NAME
FOR XML PATH,TYPE).value(N'.','nvarchar(max)'),1,2,'')
FROM INFORMATION_SCHEMA.COLUMNS t
WHERE TABLE_NAME = @tableName
order by ORDINAL_POSITION
set @sqlCommand = 'Insert into ' + @CopyToDatabase + '.dbo.' + @tableName + ' (' + @columnNames + ') select ' + @columnNames + ' from ' + @CopyFromDatabase + '.dbo.' + @tableName
if (@hasIdentityColumn = 'Y')
begin
set @sqlCommand = 'SET IDENTITY_INSERT ' + @CopyToDatabase + '.dbo.' + @tableName + ' ON; ' + @sqlCommand + ' SET IDENTITY_INSERT ' + @CopyToDatabase + '.dbo.' + @tableName + ' OFF;'
end
print @sqlCommand
begin try
exec (@sqlCommand)
end try
begin catch
set @hasTableError = 'Y'
print ERROR_MESSAGE()
end catch
end
if (@hasTableError = 'N')
begin
-- otherwise leave the table in
delete from #tablesNeedingCopy
where Table_Name = @tableName
end
FETCH NEXT FROM @tableNameCursor INTO @tableName;
END
CLOSE @tableNameCursor;
DEALLOCATE @tableNameCursor;
select @remainingTableCount = count(*)
from #tablesNeedingCopy
end -- end while
select @remainingTableCount = count(*)
from #tablesNeedingCopy
if (@remainingTableCount > 0)
begin
select Table_Name as InsertTableNames
from #tablesNeedingCopy
end
drop table #tablesNeedingCopy