通过C#中的SMO(SQL Server管理对象)进行数据库备份

时间:2011-09-13 15:45:40

标签: c# sql-server-2008 smo

我需要备份数据库(使用SQL Server 2008 R2)。 db的大小约为100 GB,所以我只想要重要表(包含设置)的备份内容,当然还有所有表,视图,触发器等的对象。

例如:

  • db:Products
  • 表格:Food, Clothes, Cars

Cars中的汽车太多,因此我只会备份表格定义(CREATE TABLE ...)并完成FoodClothes(包括其内容)。

请告诉我最好的解决方案。我可能会使用SMO(如果没有更好的解决方案)。我应该使用Backup课吗?还是Scripter上课?或者另一个(如果有的话)?哪个班级可以满足我的要求?

我希望将这些文件备份到*.sql个文件,如果可能,每个表一个。

我很感激代码示例。写在答案或某处(post url),但请确保外部文章完全解决了这类问题。

您可以使用此部分代码

ServerConnection connection = new ServerConnection("SERVER,1234", "User", "User1234");
Server server = new Server(connection);
Database database = server.Databases["DbToBackup"];

4 个答案:

答案 0 :(得分:1)

使用SMO。你必须使用你需要的选项。

StringBuilder sb = new StringBuilder();
using (SqlConnection connection = new SqlConnection("connectionString")) {
    ServerConnection serverConnection = new ServerConnection(connection);
    Server server = new Server(serverConnection);
    Database database = server.Databases["databaseName"];
    Scripter scripter = new Scripter(server);
    scripter.Options.ScriptDrops = false;
    scripter.Options.WithDependencies = true;
    scripter.Options.ScriptData = true;
    Urn[] smoObjects = new Urn[1];
    foreach (Table table in database.Tables) {
        smoObjects[0] = table.Urn;
        if (!table.IsSystemObject) {
            foreach (string s in scripter.EnumScript(smoObjects)) {
                System.Diagnostics.Debug.WriteLine(s);
                sb.AppendLine(s);
            }
        }
    }
}
// Write to *.sql file on disk
File.WriteAllText(@".\backup.sql");

另一种简单的方法是将数据库备份到xml文件。为此,请使用DataTable并调用WriteXml和WriteXmlSchema。 (稍后您需要该模式,因此可以使用相同的方法导入/恢复它)。此方法意味着您要为每个表进行备份。

private bool BackupTable(string connectionString, string tableName, string directory) {
    using (SqlConnection connection = new SqlConnection(connectionString)) {
        try {
            connection.Open();
        }
        catch (System.Data.SqlClient.SqlException ex) {
            // Handle
            return false;
        }
        using (SqlDataAdapter adapter = new SqlDataAdapter(string.Format("SELECT * FROM {0}", tableName), connection)) {
            using (DataTable table = new DataTable(tableName)) {
                adapter.Fill(table);
                try {
                    table.WriteXml(Path.Combine(directory, string.Format("{0}.xml", tableName)));
                    table.WriteXmlSchema(Path.Combine(directory, string.Format("{0}.xsd", tableName)));
                }
                catch (System.UnauthorizedAccessException ex) {
                    // Handle
                    return false;
                }
            }
        }
    }
    return true;
}

稍后您可以使用ReadXmlSchema和ReadXml将这些数据推回到数据库中,使用适配器将表填充并更新到数据库。我假设你在基本的CRUD中是知识渊博的,所以我不需要覆盖那部分。

如果您想使用SMO,这是一篇关于使用备份和还原类来备份和还原数据库的Msdn文章。代码示例我们没有格式化,在VB.NET中,但很容易翻译。

最后,这可能更容易,与IT人员交谈,看看他们是否会让您远程访问或让您自己进行备份。如果您正在编写软件并且这是一个至关重要的步骤,请大声说出并让他们知道您执行此操作的重要性,因为这样可以降低在已有优秀工具时编写自定义工具的成本。特别是因为数据库是100GB,您可以使用您已知的工具。

答案 1 :(得分:1)

This arcitle足以解决我的问题。这是我的工作解决方案。 我认为脚本所有对象都是一个文件,因为依赖性,它是更好的解决方案。如果每个文件都有一个表,并且还有一些依赖项(例如外键),那么它将编写比所有文件都在一个文件中更多的代码。

我省略了此示例中的部分代码,例如备份错误的数据库备份时备份文件。如果没有这样的系统,所有备份都将编写脚本到一个文件,它将变得混乱

public class DatabaseBackup
{
    private ServerConnection Connection;
    private Server Server;
    private Database Database;
    private ScriptingOptions Options;
    private string FileName;
    private const string NoDataScript = "Cars";

    public DatabaseBackup(string server, string login, string password, string database)
    {
        Connection = new ServerConnection(server, login, password);
        Server = new Server(Connection);
        Database = Server.Databases[database];
    }

    public void Backup(string fileName)
    {
        FileName = fileName;
        SetupOptions();

        foreach (Table table in Database.Tables)
        {
             if (!table.IsSystemObject)
             {
                  if (NoDataScript.Contains(table.Name))
                  {
                       Options.ScriptData = false;
                       table.EnumScript(Options);
                       Options.ScriptData = true;
                  }
                  else
                       table.EnumScript(Options);
              }
         }
    }

    private void SetupOptions()
    {
         Options = new ScriptingOptions();
         Options.ScriptSchema = true;
         Options.ScriptData = true;
         Options.ScriptDrops = false;
         Options.WithDependencies = true;
         Options.Indexes = true;
         Options.FileName = FileName;
         Options.EnforceScriptingOptions = true;
         Options.IncludeHeaders = true;
         Options.AppendToFile = true;
    }
}

答案 2 :(得分:1)

Server databaseServer = default(Server);//DataBase Server Name
databaseServer = new Server("ecrisqlstddev");

string strFileName = @"C:\Images\UltimateSurveyMod_" + DateTime.Today.ToString("yyyyMMdd") + ".sql"; //20120720

if (System.IO.File.Exists(strFileName))
    System.IO.File.Delete(strFileName);

List<SqlSmoObject> list = new List<SqlSmoObject>();
Scripter scripter = new Scripter(databaseServer);

Database dbUltimateSurvey = databaseServer.Databases["UltimateSurvey"];//DataBase Name

// Table scripting Writing
DataTable dataTable1 = dbUltimateSurvey.EnumObjects(DatabaseObjectTypes.Table);

foreach (DataRow drTable in dataTable1.Rows)
{
    // string strTableSchema = (string)drTable["Schema"];
    // if (strTableSchema == "dbo")
    //    continue;
    Table dbTable = (Table)databaseServer.GetSmoObject(new Urn((string)drTable["Urn"]));

    if (!dbTable.IsSystemObject)
        if (dbTable.Name.Contains("SASTool_"))
            list.Add(dbTable);
}

scripter.Server = databaseServer;

scripter.Options.IncludeHeaders = true;
scripter.Options.SchemaQualify = true;
scripter.Options.ToFileOnly = true;
scripter.Options.FileName = strFileName;
scripter.Options.DriAll = true;
scripter.Options.AppendToFile = true;

scripter.Script(list.ToArray());     // Table Script completed

// Stored procedures scripting writing
list = new List<SqlSmoObject>();

DataTable dataTable = dbUltimateSurvey.EnumObjects(DatabaseObjectTypes.StoredProcedure);

foreach (DataRow row in dataTable.Rows)
{
    string sSchema = (string)row["Schema"];

    if (sSchema == "sys" || sSchema == "INFORMATION_SCHEMA")
        continue;

    StoredProcedure sp = (StoredProcedure)databaseServer.GetSmoObject(
               new Urn((string)row["Urn"]));

    if (!sp.IsSystemObject)
        if (sp.Name.Contains("custom_"))
            list.Add(sp);
}

scripter.Server = databaseServer;

scripter.Options.IncludeHeaders = true;
scripter.Options.SchemaQualify = true;
scripter.Options.ToFileOnly = true;
scripter.Options.FileName = strFileName;
scripter.Options.DriAll = true;
scripter.Options.AppendToFile = true;

scripter.Script(list.ToArray());    // Stored procedures script completed

答案 3 :(得分:0)