Резервное копирование базы данных через SMO (объекты управления SQL Server) в C # - PullRequest
2 голосов
/ 13 сентября 2011

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

Например:

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

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

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

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

Буду признателен за пример кода. Написано в ответе или где-то (пост URL), но убедитесь, что внешняя статья имеет решение именно для такого рода проблем.

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

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

Ответы [ 4 ]

1 голос
/ 27 июля 2012
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
1 голос
/ 13 сентября 2011

Использование 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 об использовании классов Backup and Restore для резервного копирования и восстановления базы данных. Пример кода используется неформатированным и в VB.NET, но легко переводимым.

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

1 голос
/ 14 сентября 2011

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

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

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;
    }
}
0 голосов
/ 13 сентября 2011

То, что вы описываете, на самом деле не является резервной копией, но я понимаю, какова ваша цель:

Для «резервного копирования» данных вы можете загрузить содержимое таблицы через Reader в DataTable и сохранить результат в виде XML ...

...