TL; DR - я хочу, чтобы сервер делал резервную копию, а не мое приложение, потому что сервер настроен для этого, и мое приложение не будет иметь доступа.
Фон
Моя компания создала программное обеспечение для клиентов 20 лет go, написанное в Delphi 7 / Pascal. Я переписываю программное обеспечение в C#. В рамках переписывания я создал новые серверные базы данных Firebird, Oracle и SQL. Федеральное регулирование требует, чтобы все существующие данные были сохранены, поэтому я создал инструмент модификации / преобразования базы данных, чтобы перейти от старой структуры базы данных к новой.
Прежде чем начать вносить изменения, мне нужно сделать резервную копию существующей базы данных. Технический специалист, который будет запускать этот инструмент, не имеет доступа к своей локальной файловой структуре и не имеет ручного доступа к удаленному серверу, на котором размещена база данных. Инструмент обращается к зашифрованному .ini
-подобному файлу в локальной системе, чтобы проанализировать компоненты строки подключения и создать объект подключения. Затем я использую этот объект подключения для подключения к той же базе данных, к которой настроен компьютер техников. Эта часть все работает
Если я оставлю путь резервного копирования по умолчанию в одиночку, он попытается выполнить резервное копирование на путь по умолчанию, но на локальном компьютере (у техников нет доступа к созданию, и мы не делаем в любом случае, чтобы технический специалист имел доступ к .bak) Если я изменю путь резервного копирования по умолчанию, чтобы он был сетевым путем, взятым из строки подключения, я получу
SmoException: System.Data.SqlClient.SqlError : Невозможно открыть устройство резервного копирования Ошибка операционной системы 67 (Сетевое имя не найдено.).
, поскольку путь к файлу не является сетевым ресурсом (и не будет), а учетные данные пользователя базы данных не могут получить доступ этот путь извне SQL Server.
Итак, вопрос: как сделать резервную копию удаленного пути по умолчанию, как если бы я был на сервере?
Вот код, который генерирует ошибку выше (это нулевой регистр для удаленного).
public static void FullSqlBackup (Connection oldProactiveSql)
{
String sqlServerLogin = oldProactiveSql.UserName;
String password = oldProactiveSql.PassWord;
String instanceName = oldProactiveSql.InstanceName;
String remoteSvrName = oldProactiveSql.Ip + "," + oldProactiveSql.Port;
Server srv2;
Server srv3;
string device;
switch (oldProactiveSql.InstanceName)
{
case null:
ServerConnection srvConn2 = new ServerConnection(remoteSvrName);
srvConn2.LoginSecure = false;
srvConn2.Login = sqlServerLogin;
srvConn2.Password = password;
srv3 = new Server(srvConn2);
srv2 = null;
Console.WriteLine(srv3.Information.Version);
if (srv3.Settings.DefaultFile is null)
{
device = srv3.Information.RootDirectory + "\\DATA\\";
device = device.Substring(2);
device = oldProactiveSql.Ip + device;
}
else device = srv3.Settings.DefaultFile;
device = device.Substring(2);
device = string.Concat("\\\\", oldProactiveSql.Ip, device);
break;
default:
ServerConnection srvConn = new ServerConnection();
srvConn.ServerInstance = @".\" + instanceName;
srvConn.LoginSecure = false;
srvConn.Login = sqlServerLogin;
srvConn.Password = password;
srv2 = new Server(srvConn);
srv3 = null;
Console.WriteLine(srv2.Information.Version);
if (srv2.Settings.DefaultFile is null)
{
device = srv2.Information.RootDirectory + "\\DATA\\";
}
else device = srv2.Settings.DefaultFile;
break;
}
Backup bkpDbFull = new Backup();
bkpDbFull.Action = BackupActionType.Database;
bkpDbFull.Database = oldProactiveSql.DbName;
bkpDbFull.Devices.AddDevice(device, DeviceType.File);
bkpDbFull.BackupSetName = oldProactiveSql.DbName + " database Backup";
bkpDbFull.BackupSetDescription = oldProactiveSql.DbName + " database - Full Backup";
bkpDbFull.Initialize = true;
bkpDbFull.PercentComplete += CompletionStatusInPercent;
bkpDbFull.Complete += Backup_Completed;
switch (oldProactiveSql.InstanceName)
{
case null:
try
{
bkpDbFull.SqlBackup(srv3);
}
catch (Exception e)
{
Console.WriteLine (e);
Console.WriteLine(e.InnerException.Message);
throw;
}
break;
default:
try
{
bkpDbFull.SqlBackup(srv2);
}
catch (Exception e)
{
Console.WriteLine(e);
Console.WriteLine(e.InnerException.Message);
throw;
}
break;
}
}
Любая помощь будет оценена, так как я сейчас бегаю кругами.
Из комм. Ниже я попытаюсь - 1. Динамически создать хранимую процедуру [BackupToDefault] в базе данных, а затем запустить ее. 2. Если это не удалось, свяжите базу данных с самим собой. 3. Попробуйте - Exe c [BackupToDefault] На [LinkedSelfSynonmym]
Wi sh мне повезет, хотя это кажется запутанным и долгий путь, я надеюсь, что это работает.