简体   繁体   English

如何将备份或还原命令发送到命令窗口

[英]How to Send Backup or Restore command to Command Window

OK, I think I need to clarify something about my post that I forgot to mention previously. 好的,我想我需要澄清一下我以前忘记提及的帖子。 My "test application" in Visual Studio 2010 has a SQL Server 2008 R2 EXPRESS database. 我在Visual Studio 2010中的“测试应用程序”具有一个SQL Server 2008 R2 EXPRESS数据库。 However, the database is Not from a stand-alone SQL Server Express install. 但是,该数据库不是来自独立的SQL Server Express安装。 Rather, the data file, ie, .mdf and .ldf are from selecting in VS "Project\\Add New Item\\Data\\Service-based Database". 而是,数据文件(即.mdf和.ldf)是从VS中的“项目\\添加新项\\数据\\基于服务的数据库”中选择的。 Thus my "BkUp_SMO.mdf" data file. 因此是我的“ BkUp_SMO.mdf”数据文件。

I'm not sure if the above makes a difference, but I've tried multiple examples of using Microsoft.SqlServer.Management objects, SMO, but without success. 我不确定以上内容是否有所不同,但是我尝试了使用Microsoft.SqlServer.Management对象,SMO的多个示例,但均未成功。 I have added the required .DLLs, ie, Microsoft.SqlServer.ConnectionInfo, Microsoft.SqlServer.Management.Sdk.Sfc, Microsoft.SqlServer.Smo, Microsoft.SqlServer.SmoExtended. 我添加了必需的.DLL,即Microsoft.SqlServer.ConnectionInfo,Microsoft.SqlServer.Management.Sdk.Sfc,Microsoft.SqlServer.Smo,Microsoft.SqlServer.SmoExtended。

In my code I have "using" statements for both Microsoft.SqlServer.Management.Common and Microsoft.SqlServer.Management.Smo. 在我的代码中,Microsoft.SqlServer.Management.Common和Microsoft.SqlServer.Management.Smo都具有“ using”语句。 I have even added a "using" for System.Deployment.Application in order to set a string value for the path back to the ClickOnce deployment folder where the DB and log file resides, using String dbPath = ApplicationDeployment.CurrentDeployment.DataDirectory; 我甚至为System.Deployment.Application添加了一个“使用”,以便使用String dbPath = ApplicationDeployment.CurrentDeployment.DataDirectory;设置返回数据库和日志文件所在的ClickOnce部署文件夹的路径的字符串值。

In addition to the article referenced below, I have also tried examples from another article, ie, "Backing up an SQL Database in C#" Backing up an SQL Database in C# 除了下面引用的文章之外,我还尝试了另一篇文章中的示例,例如,“使用C# 备份SQL数据库”。

Is it not possible to perform a Backup and Restore on a Visual Studio created SQL database? 是否无法在Visual Studio创建的SQL数据库上执行备份和还原?

I have written a test application in C#, with the intent of sending a SQL Server Backup or Restore command via a Command Line. 我已经用C#编写了一个测试应用程序 ,目的是通过命令行发送SQL Server Backup或Restore命令。 I have based some of my code on an article titled: Backup and Restore Your SQL Server Database from the Command Line 我的一些代码基于标题为:从命令行备份和还原SQL Server数据库的文章。

Backup and Restore Your SQL Server Database from the Command Line 从命令行备份和还原SQL Server数据库

The full application will be a user_App, where I don't want the end-user to have to open a command window and type in anything, hence I'm trying to send the required commands by C# code as shown below. 完整的应用程序将是一个user_App,我不希望最终用户必须打开命令窗口并键入任何内容,因此,我试图通过C#代码发送所需的命令,如下所示。 My problem is that, the code runs without an exception, the CMD window opens and closes, but without any backup of my SQL Server 2008 R2 data file (.mdf) taking place. 我的问题是,代码无例外地运行,CMD窗口打开和关闭,但是没有对我的SQL Server 2008 R2数据文件(.mdf)进行任何备份。

Please suggest what I'm missing in my code, or a better way to accomplish this. 请提出我在代码中缺少的内容,或者提出一种更好的方法来完成此操作。 Also, will a Full backup automatically backup the log file (.ldf) as well? 另外,完全备份还会自动备份日志文件(.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);
        }

    }
}
}

This is my code to backup also SQL Server 2008 R2. 这是我要备份SQL Server 2008 R2的代码。

This kind of basic example codes are manywhere if you try to search. 如果您尝试搜索,则此类基本示例代码在很多地方。

Just try but no need to mark this as an answer becuase it's many out here. 只需尝试,但无需将其标记为答案,因为这里有很多。

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();
}

Update- Is there going to be SQL Server 2008 R2 installed on clients'(users') computer? 更新-客户端(用户)计算机上是否将安装SQL Server 2008 R2?

You're already using 'Integrated Security=True' which means the user using this connectionstring will have all(full) permissions as Administrator. 您已经在使用'Integrated Security = True',这意味着使用此连接字符串的用户将具有作为管理员的所有(完全)权限。 Connecting to Master Database is obviously no problem at all. 连接到Master数据库显然根本没有问题。

Regarding IMMEDIATE ROLLBACK, this finishes all the un-finished transactions finished just like 'hands off from the DB before we backup'. 关于立即回滚,这将完成所有未完成的事务,就像“在备份之前从数据库移交”一样。 In other word to say, Before we close a restaurant, if we don't announce that this restaurant is going to be closed, if we suddenly close the restaurant, some customers might remain still having foods eventhough the restaurant is closing. 换句话说,在关闭餐厅之前,如果我们不宣布该餐厅将要关闭,那么如果我们突然关闭餐厅,那么即使餐厅关闭了,有些顾客可能仍然会食用食物。

Have a look at, ALTER DATABASE IMMEDIATE ROLLBACK, Technet 看看, ALTER DATABASE立即回滚,Technet

This example uses the termination option WITH ROLLBACK IMMEDIATE in the first ALTER DATABASE statement. 本示例在第一个ALTER DATABASE语句中使用终止选项WITH ROLLBACK IMMEDIATE。 All incomplete transactions will be rolled back and any other connections to the AdventureWorks2008R2 sample database will be immediately disconnected. 所有未完成的事务都将回滚,并且到AdventureWorks2008R2示例数据库的任何其他连接将立即断开。

And at last, It seems you're trying with SMO. 最后,看来您正在尝试使用SMO。 I experienced difficulty for days with it but finally failed and went another way. 我经历了数天的困难,但最终失败了,换了另一种方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM