0

因此,我在类似领域搜索并找到了很多信息,但没有什么能完全解决我遇到的问题。

我在测试环境中工作,需要从同一个 SQL 数据库备份 (.bak) 恢复到 SQL 服务器的许多命名实例。所有 sql 实例都已预先安装并正在运行。

我尝试了不同的想法,但使用 sqlcmd 的批处理文件似乎最适合这项工作。

所以我创建了一个批处理文件 (.bat),它询问启动和停止实例编号,然后应该从备份恢复到每个 SQL 命名实例,并在此过程中增加实例编号。

当它运行时,sqlcmd 似乎工作正常。最后打印出来

RESTORE DATABASE successfully processed X pages in Y seconds 

文件(.mdf、.ndf、.ldf)也按预期在目录中,然后移至下一个。

问题是当它移动到下一个时,刚刚恢复的文件从目录中消失了。

如果有人有任何想法,那肯定会受到赞赏。

这里是批...

ECHO OFF
ECHO Enter starting instance number for restore db
SET /P _IntStart=


ECHO Enter number of last instance for restore db
SET /P _IntStop=
SET /a _IntStop=_IntStop+1



:RestoreDb
If %_IntStart% GEQ %_IntStop% goto:EOF

ECHO Display Instance Number... IntStart = %_IntStart%

sqlcmd -e -s localhost\instance%_IntStart% -d master -U user -P password -Q "Use [master]; RESTORE DATABASE DBName1 FROM DISK = 'C:\DBName1.bak'WITH REPLACE, MOVE 'DBName1' TO 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE%_IntStart%\MSSQL\DATA\DBName1.mdf', MOVE 'DBName1_log' TO 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE%_IntStart%\MSSQL\DATA\DBName1_log.LDF', MOVE 'ftrow_DBName1Catalog' TO 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE%_IntStart%\MSSQL\DATA\DBName1_1.ndf';"

SET /a _IntStart=_IntStart+1


GOTO:RestoreDb

PAUSE
EXIT

==========================================

来自 SQL 管理。工作室我也试过下面的。如果我注释掉循环并在每次手动增加实例号时运行它,它就会起作用。它将创建数据库和文件的单独副本。这里的问题是 SQLCMD 似乎不喜欢 Mgmt 中的连接。Studio,因此我无法增加 :CONNECT 中的实例编号。它最终尝试连接到 localhost\instance$(SCintnum)。

Declare @intnum int
Set @intnum = 1

Declare @intstr NVARCHAR(255)
Set @intstr = @intnum

Declare @PathName1 NVARCHAR(255)
Declare @PathName2 NVARCHAR(255)
Declare @PathName3 NVARCHAR(255)

Set @PathName1 = 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE' + @intstr + '\MSSQL\DATA\DBName1.mdf'
Set @PathName2 = 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE' + @intstr + '\MSSQL\DATA\DBName1_log.LDF'
Set @PathName3 = 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE' + @intstr + '\MSSQL\DATA\DBName1_1.ndf'

 While @intnum < 51

:SETVAR SCintnum 1
:CONNECT localhost\instance$(SCintnum) -U user -P password

Use [master];
RESTORE DATABASE DBName1 FROM DISK = 'C:\DBName1.bak'
WITH REPLACE, 
MOVE 'DBName1'              TO @PathName1,
MOVE 'DBName1_log'          TO @PathName2,
MOVE 'ftrow_DBName1Catalog' TO @PathName3;

:SETVAR SCintnum $(SCintum)+1
Set @intnum = @intnum+1
Set @intstr = @intnum
Set @PathName1 = 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE' + @intstr + '\MSSQL\DATA\DBName1.mdf'
Set @PathName2 = 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE' + @intstr + '\MSSQL\DATA\DBName1_log.LDF'
Set @PathName3 = 'E:\Microsoft SQL Server\MSSQL10_50.INSTANCE' + @intstr + '\MSSQL\DATA\DBName1_1.ndf'

==================================================== ==================

这是我最终在 c# 中使用的示例.....

///Set SQL Connection
SqlConnection myConnection = new SqlConnection("user id=sa;" + 
                                   "password="+ sapassword+";server="+servername+"\\instance"+currentinstancenum+";" + 
                                   "Trusted_Connection=yes;" + 
                                   "database=master; " + 
                                   "connection LifeTime=0; connection Timeout=30");
///Set SQL Command

string thesqlcommand = "USE [master]; RESTORE DATABASE " + dbname + " FROM DISK = '" + backuplocation + "' WITH REPLACE, MOVE '" + dbname + "' TO " + @PathName1 + ", MOVE '" + dbname + "_log' TO " + @PathName2 + ", MOVE 'ftrow_" + dbname + "Catalog' TO " + @PathName3 + ";";



SqlCommand myCommand = new SqlCommand(thesqlcommand, myConnection);



///Set SQL Command TimeOut, open connection, execute command, close command
myCommand.CommandTimeout = 180;
myCommand.Connection.Open();
myCommand.ExecuteNonQuery();
myConnection.Close();
4

2 回答 2

0

最终在 C# 中创建了一个小实用程序来执行此操作。希望我从那里开始,因为它要简单得多。我在原始帖子的底部添加了一个示例。

于 2013-05-21T21:58:06.197 回答
0

它正在按照您的要求执行... MOVE 'DBName1' 和 MOVE 'DBName1_log'

于 2013-05-16T09:42:39.267 回答