I have a problem. I tried the code like belov. But i am getting exception. and the exception is :
"Restore failed for Server 'SMART0090\SQL2008RR2'." FailedOperationException. .... the error is at "restore.SqlRestore(server);" line
What do you think about the problem? The code is :
public void RestoreToDatabase(string NewDatabaseName, string BackUpFile, string ServerName, string UserName, string Password)
{
ServerConnection connection = new ServerConnection(ServerName, UserName, Password);
Server sqlServer = new Server(connection);
Microsoft.SqlServer.Management.Smo.Server server = new Microsoft.SqlServer.Management.Smo.Server(connection);
Database database = new Database(server, NewDatabaseName);
database.Create();
database.Refresh();
Restore restore = new Restore();
restore.NoRecovery = false;
restore.Action = RestoreActionType.Database;
BackupDeviceItem bdi = default(BackupDeviceItem);
bdi = new BackupDeviceItem(BackUpFile, DeviceType.File);
restore.Devices.Add(bdi);
restore.Database = NewDatabaseName;
restore.ReplaceDatabase = true;
restore.PercentCompleteNotification = 10;
restore.SqlRestore(server);
database.Refresh();
database.SetOnline();
server.Refresh();
}
EDIT : All exception message is just this :
Thanks For your advice....
Finally I found a solution. The error is : when you restore a *.bak file, the *.mdf and *.ldf files are copied to a special directory. Forexample : when I restore a *.bak file my *.mdf and *.ldf files copied under "C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL2008RR2\MSSQL\DATA\". So : If there is same name for *.mdf or *.ldf file, you can get exception like i did. And I solve it with change *.mdf and *.ldf files path. I write belov code and it's working.
The C# code is :
/// <summary>
/// Var olan backup ın restore edilmesini sağlar
/// </summary>
/// <param name="NewDatabaseName">new database name</param>
/// <param name="BackUpFile">backup file path</param>
/// <param name="ServerName">server name</param>
/// <param name="UserName">user name</param>
/// <param name="Password">password</param>
public void RestoreToDatabase(string NewDatabaseName, string BackUpFile, string ServerName, string UserName, string Password, string restorePath)
{
string provider = "Server =" + ServerName +
";Database =" + "master" +
";User Id =" + UserName +
";password =" + Password +
"; Connect Timeout=2" +
";Trusted_Connection=False";
SqlConnection conn = new SqlConnection(provider);
try
{
string ConnectionString = @"Data Source= " + ServerName + ";Initial Catalog=AudioMaster;Integrated Security=True";
ServerConnection ServerConn = null;
if (UserName == "" && Password == "")
{
ServerConn = new ServerConnection(ServerName);
}
else if (UserName != "" && Password != "")
{
ServerConn = new ServerConnection(ServerName, UserName, Password);
}
Server server = null;
RegistryKey rk = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Microsoft SQL Server");
String[] instances = (String[])rk.GetValue("InstalledInstances");
server = new Server(ServerConn);
first:
foreach (Microsoft.SqlServer.Management.Smo.Database db in server.Databases)
{
if (NewDatabaseName == db.Name)
{
UpdateScreen("> Same database name detected", Color.Red);
NewDatabaseName = Microsoft.VisualBasic.Interaction.InputBox(NewDatabaseName + " database allready exist. Please enter new database name ",
"Database owerride error", "Enter a name");
UpdateScreen("> New database name : " + NewDatabaseName, Color.Green);
goto first;
}
}
}
catch (Exception ex)
{
WriteError(ex);
UpdateScreen("> An error ocurred when database names searching operation. Details : " + ex.Message, Color.Red);
}
try
{
conn.Open();
top :
FileInfo file = new FileInfo(Path.Combine(dirDebug, "scriptTry.txt"));
string mdfName = String.Empty;
SqlCommand cmd = new SqlCommand();
cmd.CommandText = file.OpenText().ReadToEnd();
cmd.Connection = conn;
cmd.Parameters.Add("@Path", BackUpFile);
cmd.Parameters.Add("@RestorePath", restorePath);
cmd.Parameters.Add("@databaseName", NewDatabaseName);
mdfName = cmd.ExecuteScalar().ToString();
string[] names = Directory.GetFiles(restorePath, "*.mdf");
int sayac = 0;
for(int i=0; i<names.GetLength(0); i++)
{
if (mdfName == GetSubPath(names[i].Replace(".mdf", "")))
sayac++;
}
if (sayac !=0)
{
MessageBox.Show("Please enter new directory for database *.mdf and *.ldf file", "Database owerride error",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
try
{
UpdateScreen("> Same path detected for *.mdf and *.ldf file.", Color.Red);
FolderBrowserDialog fbd = new FolderBrowserDialog();
fbd.ShowDialog();
if (fbd.SelectedPath == "")
return;
else
{
restorePath = fbd.SelectedPath + "\\";
}
UpdateScreen("> Selected new path for *.mdf and *.ldf file : " + fbd.SelectedPath, Color.Green);
goto top;
}
catch (Exception exx)
{
WriteError(exx);
UpdateScreen("> An error ocurred when database restore. Details : " + exx.Message, Color.Red);
}
}
file = new FileInfo(Path.Combine(dirDebug, "backup script.txt"));
cmd = new SqlCommand();
cmd.CommandText = file.OpenText().ReadToEnd();
cmd.Connection = conn;
cmd.Parameters.Add("@Path", BackUpFile);
cmd.Parameters.Add("@RestorePath", restorePath);
cmd.Parameters.Add("@databaseName", NewDatabaseName);
cmd.ExecuteNonQuery();
conn.Close();
}
catch (Exception ex)
{
WriteError(ex);
}
}
The "scriptTry.txt" SQL Code is :
use master
--DECLARE @Path VARCHAR(1000)= 'C:\bekap.bak',
-- @RestorePath NVARCHAR(max) = 'C:\New folder\',
-- @databaseName VARCHAR(1000)= 'isim'
DECLARE @Table TABLE
(
LogicalName VARCHAR(128) ,
[PhysicalName] VARCHAR(128) ,
[Type] VARCHAR ,
[FileGroupName] VARCHAR(128) ,
[Size] VARCHAR(128) ,
[MaxSize] VARCHAR(128) ,
[FileId] VARCHAR(128) ,
[CreateLSN] VARCHAR(128) ,
[DropLSN] VARCHAR(128) ,
[UniqueId] VARCHAR(128) ,
[ReadOnlyLSN] VARCHAR(128) ,
[ReadWriteLSN] VARCHAR(128) ,
[BackupSizeInBytes] VARCHAR(128) ,
[SourceBlockSize] VARCHAR(128) ,
[FileGroupId] VARCHAR(128) ,
[LogGroupGUID] VARCHAR(128) ,
[DifferentialBaseLSN] VARCHAR(128) ,
[DifferentialBaseGUID] VARCHAR(128) ,
[IsReadOnly] VARCHAR(128) ,
[IsPresent] VARCHAR(128) ,
[TDEThumbprint] VARCHAR(128)
)
DECLARE @LogicalNameData VARCHAR(128) ,
@LogicalNameLog VARCHAR(128)
INSERT INTO @table
EXEC ( '
RESTORE FILELISTONLY
FROM DISK=''' + @Path + '''
'
)
DECLARE @restoreScript NVARCHAR(max)='RESTORE DATABASE [' + @databaseName + '] FROM DISK =''' + @Path + ''' WITH FILE = 1 '
SELECT @restoreScript +=CHAR(10) + ' ,MOVE ''' + LogicalName + ''' TO ''' +
@RestorePath + LogicalName + RIGHT(PhysicalName,4) + ''''
FROM @Table
WHERE Type = 'D'
SELECT @restoreScript += ' ,MOVE ''' + LogicalName + ''' TO ''' + @RestorePath + LogicalName + '.ldf'''
FROM @Table
WHERE Type = 'L'
SET @restoreScript += ' , NOUNLOAD, REPLACE, STATS = 10 '
--SELECT @restoreScript
select LogicalName from @Table
--EXEC (@restoreScript)
The "backup script.txt" SQL Code is :
use master
--DECLARE @Path VARCHAR(1000),
-- @RestorePath NVARCHAR(max),
-- @databaseName VARCHAR(1000)
DECLARE @Table TABLE
(
LogicalName VARCHAR(128) ,
[PhysicalName] VARCHAR(128) ,
[Type] VARCHAR ,
[FileGroupName] VARCHAR(128) ,
[Size] VARCHAR(128) ,
[MaxSize] VARCHAR(128) ,
[FileId] VARCHAR(128) ,
[CreateLSN] VARCHAR(128) ,
[DropLSN] VARCHAR(128) ,
[UniqueId] VARCHAR(128) ,
[ReadOnlyLSN] VARCHAR(128) ,
[ReadWriteLSN] VARCHAR(128) ,
[BackupSizeInBytes] VARCHAR(128) ,
[SourceBlockSize] VARCHAR(128) ,
[FileGroupId] VARCHAR(128) ,
[LogGroupGUID] VARCHAR(128) ,
[DifferentialBaseLSN] VARCHAR(128) ,
[DifferentialBaseGUID] VARCHAR(128) ,
[IsReadOnly] VARCHAR(128) ,
[IsPresent] VARCHAR(128) ,
[TDEThumbprint] VARCHAR(128)
)
DECLARE @LogicalNameData VARCHAR(128) ,
@LogicalNameLog VARCHAR(128)
INSERT INTO @table
EXEC ( '
RESTORE FILELISTONLY
FROM DISK=''' + @Path + '''
'
)
DECLARE @restoreScript NVARCHAR(max)='RESTORE DATABASE [' + @databaseName + '] FROM DISK =''' + @Path + ''' WITH FILE = 1 '
SELECT @restoreScript +=CHAR(10) + ' ,MOVE ''' + LogicalName + ''' TO ''' +
@RestorePath + LogicalName + RIGHT(PhysicalName,4) + ''''
FROM @Table
WHERE Type = 'D'
SELECT @restoreScript += ' ,MOVE ''' + LogicalName + ''' TO ''' + @RestorePath + LogicalName + '.ldf'''
FROM @Table
WHERE Type = 'L'
SET @restoreScript += ' , NOUNLOAD, REPLACE, STATS = 10 '
--SELECT @restoreScript
EXEC (@restoreScript)