Я пытаюсь интегрировать программное обеспечение SQLBackup Pro от Red Gate в мое собственное программное обеспечение для резервного копирования, написанное на C#. Естественный способ сделать это - через их Extended Stored Procedure. Проблема в том, что она вызывается в формате, которого я никогда раньше не видел:
master..sqlbackup '-SQL "BACKUP DATABASE pubs TO DISK = [C:\Backups\pubs.sqb]"'
Это прекрасно работает при запуске через SSMS. Я столкнулся с проблемой, когда пытаюсь вызвать ее из C# (используя .NET 4 и Dapper Dot Net).
Моя первая попытка не срабатывает, поскольку интерпретирует всю строку cmd
как имя хранимой процедуры и выдает ошибку "Cannot find stored procedure ''":
var cmd = "master..sqlbackup '-SQL \"BACKUP DATABASE pubs TO DISK = [C:\\Backups\\pubs.sqb]\"'";
connection.Execute(cmd, commandType: CommandType.StoredProcedure, commandTimeout: 0);
Моя вторая попытка возвращается немедленно и кажется (для C#) успешной, но на самом деле резервная копия не делается (это также не подходит для параметризации):
var cmd = "master..sqlbackup";
var p = new DynamicParameters();
p.Add("", "'-SQL \"BACKUP DATABASE pubs TO DISK = [C:\\Backups\\pubs.sqb]\"'");
connection.Execute(cmd, p, commandType: CommandType.StoredProcedure, commandTimeout: 0);
Моя третья попытка также кажется успешной, но резервная копия не делается:
var cmd = "master..sqlbackup '-SQL \"BACKUP DATABASE pubs TO DISK = [C:\\Backups\\pubs.sqb]\"'";
connection.Execute(cmd, commandTimeout: 0);
Что я упускаю?
UPDATE 1:
Я пропустил документацию Red Gate, в которой говорится, что хранимая процедура на самом деле не вызывает ошибку SQL, она просто возвращает ошибки в выходную таблицу. Слик. Это может объяснить, почему я получал молчаливые сбои во втором и третьем тестах выше: какая-то базовая проблема, и они не собирают вывод, чтобы показать, почему.
Вот где я сейчас:
var cmd = "master..sqlbackup";
var p = new DynamicParameters();
p.Add("", "'-SQL \"BACKUP DATABASE pubs TO DISK = [C:\\Backups\\pubs.sqb]\"'");
p.Add("@exitcode", DbType.Int32, direction: ParameterDirection.Output);
p.Add("@sqlerrorcode", DbType.Int32, direction: ParameterDirection.Output);
connection.Execute(cmd, p, commandType: CommandType.StoredProcedure, commandTimeout: 0);
Когда я запускаю этот тест и проверяю выходные параметры, я получаю Exit Code 870:
No command passed to SQL Backup.
Команда пуста.
Значит, он не видит параметр с пустым именем.
Обновление 2:
Захват вышеприведенного в трассировке показывает, что пустая строка параметра заменяется на @Parameter1=
, что объясняет, почему хранимая процедура не видит ее.