C#SQL Server将远程数据库备份到远程默认备份位置,而不直接访问远程位置?

C#SQL Server将远程数据库备份到远程默认备份位置,而不直接访问远程位置?,c#,sql-server,default,remote-server,remote-backup,C#,Sql Server,Default,Remote Server,Remote Backup,TL;DR-我希望服务器进行备份,而不是我的应用程序,因为服务器已设置为进行备份,而我的应用程序将无法访问 背景 我的公司在20年前为客户创建了用Delphi 7/Pascal编写的软件。我正在用C重新编写软件。作为重写的一部分,我创建了新的Firebird、Oracle和SQL Server数据库。联邦法规要求维护所有现有数据,因此我创建了一个数据库修改/转换工具,以便从旧数据库结构更改为新数据库结构 在开始进行更改之前,我需要备份现有数据库。运行此工具的技术人员无法访问其本地文件结构,也无法

TL;DR-我希望服务器进行备份,而不是我的应用程序,因为服务器已设置为进行备份,而我的应用程序将无法访问

背景

我的公司在20年前为客户创建了用Delphi 7/Pascal编写的软件。我正在用C重新编写软件。作为重写的一部分,我创建了新的Firebird、Oracle和SQL Server数据库。联邦法规要求维护所有现有数据,因此我创建了一个数据库修改/转换工具,以便从旧数据库结构更改为新数据库结构

在开始进行更改之前,我需要备份现有数据库。运行此工具的技术人员无法访问其本地文件结构,也无法手动访问数据库所在的远程服务器。该工具访问本地系统上加密的
.ini
-like文件,以解析连接字符串的组件并创建连接对象。然后,我使用该连接对象连接到计算机设置要连接的同一数据库此部分全部工作正常

如果我不使用默认备份路径,它会尝试备份到默认路径,但在本地计算机上(技术人员无权创建,我们也不希望技术人员能够访问.bak)。如果我将默认备份路径修改为从连接字符串获取的网络路径,我会

SmoException:System.Data.SqlClient.SqlError:无法打开备份设备操作系统错误67(找不到网络名称)

因为文件路径不是网络共享(将来也不会),并且数据库用户凭据无法从SQL Server外部访问该路径

因此,问题是:如何像在服务器上一样备份到远程默认路径

下面是生成上述错误的代码(对于remote,为空)

任何帮助都将不胜感激,因为我现在只是在兜圈子

从下面的评论中,我将尝试- 1.在数据库上动态创建存储过程[BackupDefault],然后运行它。 2.如果失败,将数据库链接到自身。 3.在[LinkedSelfSynonym]处尝试-Exec[backupDefault]


祝我好运吧,尽管它看起来很复杂,我希望它能奏效。

为了获得灵感。。。备份分为3个文件,每个文件位于不同的目录(sql实例备份目录和sql实例默认目录以及数据库主目录)

///编译时使用:
///r:Microsoft.SqlServer.Smo.dll
///r:Microsoft.SqlServer.SmoExtended.dll
///r:Microsoft.SqlServer.ConnectionInfo.dll
使用制度;
使用系统数据;
使用Microsoft.SqlServer.Management.Smo;
使用Microsoft.SqlServer.Management.Common;
命名空间备份
{
班级计划
{
静态void Main()
{
//对于远程连接,需要指定远程服务器名称/ServerInstance
ServerConnection srvConn2=新的ServerConnection(“machinename”/*谢谢@SeanLange

在这种情况下,您肯定需要使用动态sql。然后,路径将与执行sql的位置相关

我将代码更改为添加:

 private static void WriteBackupSp (Server remoteServer, string dbName, out string storedProcedure)
      {
           var s = "CREATE PROCEDURE [dbo].[ProactiveDBBackup]\n";
           s += "AS\n";
           s += "BEGIN\n";
           s += "SET NOCOUNT ON\n";
           s += "BACKUP DATABASE " + dbName + " TO DISK = \'" + string.Concat (remoteServer.BackupDirectory,@"\", dbName, ".bak") + "\'\n";
           s += "END\n";
           storedProcedure = s;
      }
然后将最后一个开关更改为:

switch (oldProactiveSql.InstanceName)
           {
                case null:
                     try
                     {
                          WriteBackupSp (srv3, oldProactiveSql.DbName, out var storedProcedure);
                          ConnectionToolsUtility.GenerateSqlConnectionString (oldProactiveSql, out var cs);

                          using (SqlConnection connection = new SqlConnection (cs))
                          {
                               using (SqlCommand command = new SqlCommand (storedProcedure, connection))
                               {
                                    connection.Open ();
                                    command.ExecuteNonQuery ();
                                    connection.Close ();
                               }
                          }
                          var execBackup = "EXEC [dbo].[ProactiveDBBackup]\n";
                          using (SqlConnection connection = new SqlConnection (cs))
                          {
                               using (SqlCommand command = new SqlCommand (execBackup, connection))
                               {
                                    connection.Open ();
                                    command.ExecuteNonQuery ();
                                    connection.Close ();
                               }
                          }
                     }
                     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;
           }

这使我可以通过连接字符串将数据库备份到默认备份位置,而无需具有访问网络路径位置的凭据。

不完全确定您在这里进行了什么操作。但是运行sql server的服务帐户需要访问文件夹位置才能写入备份这不是SA sql用户…但在这样一个安全的情况下,你为什么要使用SA帐户???我没有使用实际的SA帐户(SA已被删除)但是原始程序的安全连接字符串中的帐户,如果我通过服务器上的ssms登录到sql server,则已验证此帐户具有执行数据库备份的权限。即,如果我以原始连接字符串中的用户身份登录服务器,则我可以执行与默认备份相当的备份位置。如果我尝试从本地计算机执行备份,我会得到一个错误,即我看不到远程网络名称。从本地计算机执行备份是什么意思?意味着你正在运行一个连接到本地sql实例的应用程序?或者完全是其他什么?我无法了解你在这里尝试执行的操作。我是wr正在运行将在本地计算机上运行的应用程序。此应用程序连接到远程SQL server。此应用程序需要将连接的数据库备份到默认备份位置(通过Microsoft.SqlServer.Management.Smo.server.Settings.DefaultFile检索)在连接的服务器上。如果我在服务器上运行应用程序,则该应用程序将按预期运行,但如果我远程运行,则该应用程序将返回以下信息:SmoException:System.Data.SqlClient.SqlError:无法打开备份设备操作系统错误67(找不到网络名称)@Sean Lange客户端不愿意打开其服务器以远程使用默认路径,因此我需要一种方法从远程执行此服务器路径备份,但看起来它来自服务器,因此默认备份位置可用。
 private static void WriteBackupSp (Server remoteServer, string dbName, out string storedProcedure)
      {
           var s = "CREATE PROCEDURE [dbo].[ProactiveDBBackup]\n";
           s += "AS\n";
           s += "BEGIN\n";
           s += "SET NOCOUNT ON\n";
           s += "BACKUP DATABASE " + dbName + " TO DISK = \'" + string.Concat (remoteServer.BackupDirectory,@"\", dbName, ".bak") + "\'\n";
           s += "END\n";
           storedProcedure = s;
      }
switch (oldProactiveSql.InstanceName)
           {
                case null:
                     try
                     {
                          WriteBackupSp (srv3, oldProactiveSql.DbName, out var storedProcedure);
                          ConnectionToolsUtility.GenerateSqlConnectionString (oldProactiveSql, out var cs);

                          using (SqlConnection connection = new SqlConnection (cs))
                          {
                               using (SqlCommand command = new SqlCommand (storedProcedure, connection))
                               {
                                    connection.Open ();
                                    command.ExecuteNonQuery ();
                                    connection.Close ();
                               }
                          }
                          var execBackup = "EXEC [dbo].[ProactiveDBBackup]\n";
                          using (SqlConnection connection = new SqlConnection (cs))
                          {
                               using (SqlCommand command = new SqlCommand (execBackup, connection))
                               {
                                    connection.Open ();
                                    command.ExecuteNonQuery ();
                                    connection.Close ();
                               }
                          }
                     }
                     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;
           }