从远程sql server导出blob并保存到sql server所在磁盘上的文件[C#]

时间:2014-01-31 13:25:53

标签: c# sql-server export blob bcp

我需要做什么: 我正在为我的公司工作备份和恢复工具。备份远程SQL数据库完成没有任何问题。但我在恢复它们时遇到了问题。我目前正在远程SQL上创建一个临时表,其中保存了数据库的二进制文件。

现在我需要将此二进制字段从远程SQL Server导出到需要保存在远程磁盘上的文件。此工具需要在本地计算机上启动,因此无法在远程服务器上运行它。

当前代码部分:

using (SqlConnection conn = new SqlConnection(sqlConnectionString))
            {
                System.Data.SqlClient.SqlCommand commandAdd = new SqlCommand("CREATE TABLE dbo.tempTable (filename char(50), blob image);", conn);
                conn.Open();

                if (commandAdd.ExecuteNonQuery() != 0)
                {
                    byte[] fileBytes = System.IO.File.ReadAllBytes(fileSource);
                    System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand("INSERT INTO dbo.tempTable (blob,filename) values (@blob,@name)", conn);
                    command.Parameters.AddWithValue("blob", fileBytes);
                    command.Parameters.AddWithValue("name", dbName);

                    if (command.ExecuteNonQuery() != 0)
                    {
                        // This is just for testing if i get binary back
                        // string SQL = "SELECT blob FROM dbo.tempTable";
                        // SqlCommand cmd = new SqlCommand(SQL, conn);
                        // byte[] byt = (byte[])cmd.ExecuteScalar();

                        // I think Problem is within this 2 lines..
                        Server server = new Server(new ServerConnection(conn));
                        server.ConnectionContext.ExecuteReader("'bcp.exe \"SELECT blob FROM dbo.tempTable\" queryout " + destinationSource + " -T -c'");

                        Restore restore = new Restore();
                        restore.Database = "_" + dbName;
                        restore.Action = RestoreActionType.Database;
                        restore.ReplaceDatabase = true;
                        restore.Devices.AddDevice(destinationSource, DeviceType.File);
                        restore.ReplaceDatabase = true;
                        restore.NoRecovery = false;
                        Server sqlServer = new Server(new ServerConnection(conn));
                        restore.SqlRestore(sqlServer);
                    }
                }

                SqlCommand commandDelete = new SqlCommand("DROP TABLE dbo.tempTable", conn);
                commandDelete.ExecuteNonQuery();
                conn.Close();
            }

由于

2 个答案:

答案 0 :(得分:1)

好的,我再试一次。 看这里:https://www.simple-talk.com/sql/t-sql-programming/the-tsql-of-text-files/

--then we execute the BCP to save the file
  SELECT  @Command = 'bcp "select BulkCol from ['
          + @MySpecialTempTable + ']'
          + '" queryout '
          + @Filename + ' '
         + CASE WHEN @Unicode=0 THEN '-c' ELSE '-w' END
          + ' -T -S' + @@servername
  EXECUTE @RESULT= MASTER..xp_cmdshell @command, NO_OUTPUT

您可以从c#代码调用执行命令(并保存文件)的xp_cmdshell

答案 1 :(得分:0)

您可以在远程服务器上使用FILESTREAM吗?您可以将备份保存到FILESTREAM列,这会将其保存到磁盘,您可以配置FILESTREAM以使流可用于其他进程(在本例中为SQL Server本身)。

如果FILESTREAM列名为“Backup”,则可以使用Backup.PathName()获取相应的路径,并使用此命令发出RESTORE命令,我认为这对您的问题来说是一个非常优雅的解决方案(不使用xp_cmdshell或类似讨厌的解决方法)。

这种“文件流备份表”的一个简单示例是

CREATE TABLE MyBackup
(
  BackupName VARCHAR(100),                -- To identify the backup
  BackupContent VARBINARY(max) FILESTREAM -- To store the physical backup
);

尝试创建此类表时可能会出错,具体取决于在给定服务器和数据库上是否启用了FILESTREAM功能(默认情况下已禁用)。