Резервное копирование базы данных через SMO (SQL Server Management Objects) в C#



Мне нужно создать резервную копию базы данных (используя SQL Server 2008 R2). Размер БД составляет около 100 ГБ, поэтому я хочу резервировать содержимое только важных таблиц (содержащих настройки) и, конечно, объект всех таблиц, представлений, триггеров и т. д.



Например:




  • db: Products

  • таблицы: Food, Clothes, Cars


ВCars слишком много машин, поэтому я буду только резервировать определение таблицы (CREATE TABLE ...) и завершать Food и Clothes (включая ее содержание).



Посоветуйте мне самое лучшее решение, Пожалуйста. Я, вероятно, буду использовать SMO (если нет лучшего решения). Должен ли я использовать класс Backup? Или Scripter класс? Или другой (если таковой имеется)? Какой класс может справиться с моими требованиями?



Я хочу сделать резервную копию этих файлов в файлы *.sql, по одному на таблицу, если это возможно.

Я был бы признателен за образец кода. Написано в ответе или где-то еще (post url), но убедитесь, что внешняя статья имеет решение именно для такого рода проблем.



Вы можете использовать эту часть кода



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

4 ответов:

Использование 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;
}

Вы можете позже затем отправить их обратно в базу данных us с помощью ReadXmlSchema и ReadXml, используя адаптер для заполнения и обновления таблица к базе данных. Я предполагаю, что вы хорошо разбираетесь в основной грязи, так что мне не нужно будет покрывать эту часть.

Если вы хотите использовать SMO, вот статья Msdn об использовании классов Backup и Restore для резервного копирования и восстановления базы данных. Пример кода у нас неформатированный, а в VB.NET, но легко переводимый.

Наконец, что может быть проще, поговорите с ИТ-специалистами и посмотрите, будут ли они позвольте вам удаленно войти или дать вам доступ, чтобы сделать резервную копию самостоятельно. Если вы пишете программное обеспечение, и это важный шаг, говорите и дайте им знать, насколько важно для вас это сделать, так как это снизит затраты на написание пользовательского инструмента, когда уже существуют отличные инструменты. Тем более, что база данных составляет 100 ГБ, вы можете использовать инструменты, которые вы уже знаете, работают.

Этот аркитл был достаточно информативен, чтобы решить мою проблему. Вот мое рабочее решение. Я решил записать все объекты в один файл, это лучшее решение из-за зависимостей, я думаю. Если есть одна таблица на файл, и есть также некоторые зависимости (например, внешние ключи), он будет писать больше кода, чем если бы все было в одном файле.

Я опустил некоторые части кода в этом примере, например резервное копирование файлов резервных копий в случае неправильного резервного копирования базы данных. Если такого нет система, все резервные копии будут записываться в один файл, и это будет грязно

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

Comments

    Ничего не найдено.