Member 11298827 Ответов: 2

Резервное копирование и восстановление базы данных SQL с помощью system.data.sqlclient


У меня есть проект Windows Form, в котором я создал локальную базу данных типа SQL. Это файл MDF. Я использую System.Data.SqlClient для открытия базы данных, чтения и записи в нее.

Он работает нормально, за исключением возможности резервного копирования и восстановления.

Моя цель состоит в том, чтобы иметь возможность сделать резервную копию базы данных (в файл MDF), а затем иметь возможность восстановить ее, и все это из моего приложения.

******* ОБНОВЛЕНИЕ ОТ 19 ИЮНЯ **********************************************************

Я делаю некоторый прогресс, но все еще не могу выполнить восстановление. Во-первых, моя строка подключения и код для подключения-это:

String connectString = "Data Source=(LocalDB)\\MSSQLLocalDB; AttachDbFilename = " + startup_dir + "\\TAS_Dbase\\MyDataBase.mdf; Integrated Security = True";
DB_Connection = new SqlConnection(connectString);
DB_Connection.Open();

Код для восстановления:
private void button2_Click(object sender, EventArgs e)
{
    String dbName = getDBname();

    String buPath = "'" + db_path + "\\Backup.bak'";

    sqlString = "RESTORE DATABASE " + dbName + " FROM DISK = " + buPath;

    command = new SqlCommand(sqlString, DB_Connection);
    command.ExecuteNonQuery();
}

Выполнение команды вызывает следующее исключение.

Необработанное исключение типа "System.Data.SqlClient.SqlException" произошло в System.Data.dll

Дополнительная информация: восстановление не может обработать базу данных 'C:\USERS\VICTOR\DOCUMENTS\VISUAL STUDIO 2015\PROJECTS\DB_TEST\DB_TEST\BIN\DEBUG\TAS_DBASE\MYDATABASE.MDF', потому что он используется в этом сеансе. При выполнении этой операции рекомендуется использовать базу данных master.

Восстановление базы данных завершается ненормально.

Открытие базы данных препятствует восстановлению. Есть ли способ подключиться к движку SQL Server, не открывая базу данных (может ли это сработать) ? Что я должен сделать, чтобы избежать этой проблемы?

Что я уже пробовал:

Я попробовал следующее, Где DBname-это имя базы данных. В данном случае это так -

"\"C:\\USERS\\VICTOR\\DOCUMENTS\\VISUAL СТУДИЯ 2015\\ПРОЕКТЫ\\DB_TEST\\DB_TEST\\БИН\\ОТЛАДКИ\\TAS_DBASE\\ДАННЫХ MYDATABASE.МДФ\""
sqlString = "BACKUP DATABASE " + DBname + " TO DISK = '" + path_to_backup;
 command = new SqlCommand(sqlString, DB_Connection);
 command.ExecuteNonQuery();

Резервное копирование, по-видимому, выполняется, и создается файл "Backup.mdf". Однако если я попытаюсь подключиться к файлу резервной копии, то получу следующее исключение:

Необработанное исключение типа "System.Data.SqlClient.SqlException" произошло в System.Data.dll

Дополнительная информация: не удается открыть базу данных "C:\USERS\VICTOR\DOCUMENTS\VISUAL STUDIO 2015\PROJECTS\DB_TEST\DB_TEST\BIN\DEBUG\TAS_DBASE\BACKUP.MDF" запрашивается логином. Ошибка входа в систему.

Не удалось войти в систему для пользователя "Vics_PC\Victor".

Я считаю, что созданный файл резервной копии на самом деле не является файлом типа MDF. Я отметил, что он примерно на 200 кб меньше, чем исходный файл MDF.

Есть ли способ достичь моей цели?

2 Ответов

Рейтинг:
5

OriginalGriff

Вы можете посмотреть здесь: Резервное копирование базы данных SQL на языке C#[^]


Member 11298827

OriginalGriff, Спасибо, что опубликовал это. Вопрос: требует ли этот код установки Microsoft SQL Express? Насколько я знаю (но я могу быть совершенно неправ), код, который я использую до сих пор, не нуждается в SQL Express, он просто использует .net Framework. Я действительно не знаю, потому что я очень новичок в этом. Я хотел бы, чтобы это приложение было как можно более портативным, поэтому, если я смогу сделать это без SQL Express, это будет лучше всего.

OriginalGriff

Не обязательно экспресс-версия, но ... вам нужно где-то установить SQL Server, чтобы вообще использовать базу данных SQL, так что я думаю, что у вас все равно есть к ней доступ!

Member 11298827

О'Грифф,

Еще раз спасибо за ответ. Да, у меня действительно установлен SQL Server, но я не знал, используется ли он приложением. Мне нужно иметь возможность установить его на другие машины, но в настоящее время у меня нет доступа ни к одному другому компьютеру, чтобы попробовать его.
Reading through your article, I'm a little daunted about trying it. Seems like there are a lot of stumbling blocks. My alternate plan is to just copy the .mdf file to a subdirectory (actually a different drive would be safer). I can to this before I connect to the database, but while connected, the mdf file is locked, and can't be copied. Also it seems the mdf file is not updated until the application closes. Is there a way to get SQL Server to update and release the file after connecting to it? For instance can I disconnect from the database to release the file for copying, and then reconnect to it? By the way, the database is very small and should never grow to more than 10MB or so. I sure appreciate your help.

OriginalGriff

Серьезно, просто вставьте резервный код в приложение, измените имена в соответствии с вашей системой и попробуйте - это намного проще, чем пытаться заставить SQL server "отпустить" БД, а затем "забрать ее обратно", когда вы ее скопировали.

Member 11298827

О'Грифф,

Я последовал твоему совету и попробовал твой код. Кажется, это работает!!! У меня есть еще тесты, чтобы сделать, и, возможно, больше вопросов для вас.

Member 11298827

О'Грифф,

Пока все хорошо. Вопрос: ваш код объявляет и присваивает значение ConnectionString, но я не вижу, где оно используется. Я закомментировал эту строку, и она все еще работает (по крайней мере, функция восстановления, еще не пробовала резервное копирование, так как она уже работала в моем коде). Так нужна ли эта переменная?

public static readonly string ConnectionString = @"источник данных=GRIFFPC\SQLEXPRESS;начальный каталог=AudioMaster;Интегрированная безопасность=True";

OriginalGriff

- Нужна ли эта переменная?"
Нет - это "похмелье" от кода, который был абстрагирован, и я забыл его удалить. :румянец:

Member 11298827

О'Грифф, спасибо, что сообщил мне об этом! Все тестирование завершено, и все работает хорошо. Одна вещь, которую я хочу упомянуть -

Похоже, что имя базы данных-это просто полный путь к файлу .mdf. В своем коде вы жестко кодируете имя базы данных, например -

источник.Database = "MyDataBaseName";

В моем случае это не работает, потому что имя базы данных (путь к файлу MDF) будет меняться в зависимости от компьютера, на котором работает приложение . Поэтому я изменил методы RestoreDatabase и BackupDatabase, чтобы передать строку, содержащую путь. Надеюсь, это имеет смысл, не знаю, что еще я мог бы сделать.

Еще раз спасибо за вашу помощь. Я отмечаю ваше решение как принятое.

Рейтинг:
20

MadMyche

То Backup используется для создания резервной копии базы данных; не копии ее, а результирующего файла должен используйте расширение файла BAK.

Резервная копия базы данных должна иметь Restore команда, используемая в нужном файле для монтирования базы данных.
Восстановление (Transact-SQL) - SQL Server | Microsoft Docs[^]


Member 11298827

Мадмыч, большое спасибо за ваш ответ. Это имеет смысл, и я попробую это сделать и вернусь к вам.

MadMyche

Пожалуйста