2017-02-20 122 views
0

好的,我想我需要澄清一些关于我的帖子,我忘了以前提到。我在Visual Studio 2010中的“测试应用程序”有一个SQL Server 2008 R2 EXPRESS数据库。但是,从独立的SQL Server Express安装数据库是不是。相反,数据文件,即.mdf和.ldf是在VS“Project \ Add New Item \ Data \ Service-based Database”中选择的。因此我的“BkUp_SMO.mdf”数据文件。如何发送备份或恢复命令到命令窗口

我不确定上述是否有所作为,但我已经尝试了使用Microsoft.SqlServer.Management对象SMO的多个示例,但没有成功。我添加了所需的.DLL,即Microsoft.SqlServer.ConnectionInfo,Microsoft.SqlServer.Management.Sdk.Sfc,Microsoft.SqlServer.Smo,Microsoft.SqlServer.SmoExtended。

在我的代码中,我对Microsoft.SqlServer.Management.Common和Microsoft.SqlServer.Management.Smo都有“using”语句。 我甚至为System.Deployment.Application添加了一个“using”,以便为返回到DB和日志文件所在的ClickOnce部署文件夹的路径设置字符串值,使用String dbPath = ApplicationDeployment.CurrentDeployment.DataDirectory;

除了下面引用的文章中,我也试图从另一篇文章中,即例子,“备份在C#中的SQL数据库” Backing up an SQL Database in C#

它是不可能对视觉进行备份和恢复Studio创建了SQL数据库?

我已经在C#中编写了测试应用程序,目的是通过命令行发送SQL Server备份或恢复命令。我已经根据我的一些代码上的一篇文章题为:备份和从命令行

Backup and Restore Your SQL Server Database from the Command Line

完整的应用程序将是一个user_App,在这里我不希望最终用户恢复您的SQL Server数据库必须打开命令窗口并键入任何内容,因此我试图通过C#代码发送所需的命令,如下所示。我的问题是,代码无异常运行,CMD窗口打开和关闭,但没有发生我的SQL Server 2008 R2数据文件(.mdf)的任何备份。

请提出我在代码中缺少的内容,或者更好的方法来完成此操作。 此外,完整备份是否会自动备份日志文件(.ldf)?

First code attempt 
private void btnChoose_Click(object sender, EventArgs e) 
{ 
    if (optBkupCMD.Checked) 
    { 
     StringBuilder bkup = new StringBuilder(); 
     bkup.Append("SqlCmd -E -S "); 
     bkup.Append(Environment.MachineName);//servername appears to be same as computer name. 
     bkup.Append(" –Q “BACKUP DATABASE [BkUp_SMO.mdf] TO DISK=’C:\\Backups\\BkUp_SMO.bak'”"); 
     string theBackup = bkup.ToString(); 

    using (Process process = new Process()) 
    { 
     process.StartInfo.FileName = "cmd.exe"; 
     process.StartInfo.RedirectStandardInput = true; 
     process.StartInfo.RedirectStandardOutput = true; 
     process.StartInfo.CreateNoWindow = false; 
     process.StartInfo.UseShellExecute = false; 
     process.StartInfo.Arguments = @"/C"; 
     process.Start(); 
     process.StandardInput.WriteLine(theBackup); 
     process.StandardInput.Flush(); 
     process.StandardInput.Close(); 
     process.WaitForExit(); 
     Console.WriteLine(process.StandardOutput.ReadToEnd()); 
    } 
else if (optRestoreCMD.Checked) 
{ 
    StringBuilder rstr = new StringBuilder(); 
    rstr.Append("SqlCmd -E -S "); 
    rstr.Append(Environment.MachineName); 
    rstr.Append(" –Q “RESTORE DATABASE [BkUp_SMO.mdf] FROM DISK=’C:\\Backups\\BkUp_SMO.bak'”"); 
    string restore = rstr.ToString(); 

    using (Process process = new Process()) 
    { 
     process.StartInfo.FileName = "cmd.exe"; 
     process.StartInfo.RedirectStandardInput = true; 
     process.StartInfo.RedirectStandardOutput = true; 
     process.StartInfo.CreateNoWindow = false; 
     process.StartInfo.UseShellExecute = false; 
     process.StartInfo.Arguments = @"/C"; 
     process.Start(); 
     process.StandardInput.WriteLine(restore); 
     process.StandardInput.Flush(); 
     process.StandardInput.Close(); 
     process.WaitForExit(); 
     Console.WriteLine(process.StandardOutput.ReadToEnd()); 
    } 
} 

}

My 2nd code attempt. 
using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Data.SqlClient; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Threading; 
using Microsoft.Win32; 
using System.Deployment.Application; 
using System.Diagnostics; 
using System.IO; 
using Microsoft.SqlServer.Management.Smo; 
using Microsoft.SqlServer.Management.Common; 

namespace DB_Bkup_using_SMO 
{ 
    public partial class Bkup_in_CSharp : Form 
    { 
     public Bkup_in_CSharp() 
     { 
      InitializeComponent(); 
     } 

    private void btnBkViaCsharp_Click(object sender, EventArgs e) 
    { 
     string filePath = ApplicationDeployment.CurrentDeployment.DataDirectory; 
     BackupDatabase(filePath); 
    } 

    private void btnRestViaCsharp_Click(object sender, EventArgs e) 
    { 
     string filePath = ApplicationDeployment.CurrentDeployment.DataDirectory; 
     RestoreDatabase(filePath); 
    } 

    ///<summary> 
    ///Backup a whole database to the specified file. 
    ///</summary> 
    ///<remarks> 
    ///The database must not be in use when backing up. 
    ///The folder holding the file must have appropriate permissions given 
    ///</remarks> 
    ///<param name="backupFile">Full path to file to hold the backup</param> 
    public static void BackupDatabase(string backupFile) 
    { 
     try 
     { 
      ServerConnection con = new ServerConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\BkUp_SMO.mdf;Integrated Security=True;User Instance=True"); 

      Server server = new Server(con); 
      Backup source = new Backup(); 
      source.Database = "BkUp_SMO.mdf"; 
      source.Action = BackupActionType.Database; 

      source.LogTruncation = BackupTruncateLogType.Truncate; 
      BackupDeviceItem destination = new BackupDeviceItem(backupFile, DeviceType.File); 
      source.Devices.Add(destination); 

      source.SqlBackup(server); 
      con.Disconnect(); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message + " " + ex.InnerException); 
     } 
    } 

    ///<summary> 
    ///Restore a whole database from a backup file. 
    ///</summary> 
    ///<remarks> 
    ///The database must be in use when backing up. 
    ///The folder holding the file must have appropriate permissions given. 
    ///</remarks> 
    ///<param name="backupFile">Full path to file to holding the backup</param> 
    public static void RestoreDatabase(string backupFile) 
    { 
     try 
     { 
      ServerConnection con = new ServerConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\BkUp_SMO.mdf;Integrated Security=True;User Instance=True"); 

      Server server = new Server(con); 
      Restore destination = new Restore(); 
      destination.Database = "BkUp_SMO.mdf"; 
      destination.Action = RestoreActionType.Database; 
      destination.Action = RestoreActionType.Log; 
      BackupDeviceItem source = new BackupDeviceItem(backupFile, DeviceType.File); 
      destination.Devices.Add(source); 
      destination.ReplaceDatabase = true; 
      destination.SqlRestore(server); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message + " " + ex.InnerException); 
     } 

    } 
} 
} 
+0

您是否需要'显示'黑色的命令行界面?如果不是,就像我一样,有一种比较简单的备份方法。 –

+0

你好李凯。不,我不需要看命令窗口。它必须为最终用户提供一种轻松执行备份还原的方法。请分享您的方法或代码示例。 – CodeMann

回答

0

这是我的代码来备份SQL也Server 2008 R2的。

如果您尝试搜索,这种基本的示例代码是很多地方。

只是尝试,但没有必要将此标记为一个答案,因为它是很多在这里。

string masterdb_ConnectionString = string.Format(@"Data Source={0};Initial Catalog=Master;Connect Timeout=79;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False;Integrated Security=True;", System.Environment.MachineName); 

using (SqlConnection masterdbConn = new SqlConnection()) 
{ 
    masterdbConn.ConnectionString = mastedb_rConnectionString; 
    masterdbConn.Open(); 

    using (SqlCommand multiuser_rollback_dbcomm = new SqlCommand()) 
    { 
     multiuser_rollback_dbcomm.Connection = masterdbConn; 
     multiuser_rollback_dbcomm.CommandText= @"ALTER DATABASE yourdbname SET MULTI_USER WITH ROLLBACK IMMEDIATE"; 
     multiuser_rollback_dbcomm.CommandTimeout = 79; 

     multiuser_rollback_dbcomm.ExecuteNonQuery(); 
    } 
    masterdbConn.Close(); 
} 

SqlConnection.ClearAllPools(); 

string yourdb_ConnectionString= "connectionstring for yourdb here"; 

using (SqlConnection backupConn = new SqlConnection()) 
{ 
    backupConn.ConnectionString = yourdb_ConnectionString; 
    backupConn.Open(); 

    using (SqlCommand backupcomm = new SqlCommand()) 
    { 
     backupcomm.Connection = backupConn; 
     backupcomm.CommandText = string.Format(@"BACKUP DATABASE yourdbname TO DISK='c:\yourdbname.bak'", DateTime.Today.ToString("yyyy/MM/dd")); 
     backupcomm.CommandTimeout = 79; 

     backupcomm.ExecuteNonQuery(); 
    } 
    backupConn.Close(); 
} 

更新 - 是否有将是SQL Server 2008的客户(用户)的电脑安装R2?

您已经在使用'Integrated Security = True',这意味着使用此连接字符串的用户将具有所有(完整)权限作为管理员。连接到主数据库显然没有问题。

关于IMMEDIATE ROLLBACK,这完成了所有未完成的事务,就像'在我们备份之前从数据库中取出'一样。换句话说,在我们关闭一家餐厅之前,如果我们没有宣布这家餐厅将要关闭,如果我们突然关闭了餐厅,那么一些客户在餐厅关门时可能仍然会有食物。

看一看,ALTER DATABASE IMMEDIATE ROLLBACK, Technet

This example uses the termination option WITH ROLLBACK IMMEDIATE in the first ALTER DATABASE statement. All incomplete transactions will be rolled back and any other connections to the AdventureWorks2008R2 sample database will be immediately disconnected.

,最后,看来你与SMO尝试。我经历了几天的困难,但最终失败了,并以另一种方式。

+0

你好凯。我不太了解你的代码示例。它看起来像连接到MASTER数据库,而不是我的数据库。从我读过的,这可能需要提升用户凭据。另外,不理解您对“multiuser_rollback”或ALTER db语句的引用。这是一个分布式的“单用户”最终用户应用程序。请参考我上面关于这个Visual Studio创建的SQL Express数据文件的编辑,而不是独立的SQL Express安装。谢谢 – CodeMann

+0

@CodeMann,看到我更新的答案。对不起,我没有太多时间,由于我的重要工作..希望这有助于.. –

+0

凯,我试过你的代码示例,并在执行代码时,它抛出以下异常:网络相关或实例特定的错误在建立与SQL Server的连接时发生。服务器未找到或无法访问。验证实例名称是否正确,并将SQL Server配置为允许远程连接。 (提供程序:命名管道提供程序,错误:40 - 无法打开到SQL Server的连接)System.ComponentModel.Win32Exception(0x80004005):系统找不到指定的文件。 – CodeMann