如何将Azure VM中SQL Server的Varbinary(PDF)数据导出至Azure Blob
将Azure VM上SQL Server的Varbinary类型PDF导出至Azure Blob存储
当然可以实现,你原来的sp_OACreate+ADODB.Stream方案仅支持本地文件系统写入,无法直接指向Azure Blob路径,需要替换为以下几种可行方案:
方案1:使用SQL Server内置的Blob存储外部数据源(推荐,无需外部工具)
该方案利用SQL Server的外部数据源功能直接将Varbinary数据写入Azure Blob,适用于SQL Server 2017及以上版本。
步骤1:配置存储凭据与外部数据源
-- 创建数据库主密钥(若未存在) CREATE MASTER KEY ENCRYPTION BY PASSWORD = '你的强密码'; GO -- 创建数据库范围凭据(使用SAS令牌,无需暴露存储账户密钥) CREATE DATABASE SCOPED CREDENTIAL BlobStorageCredential WITH IDENTITY = 'SHARED ACCESS SIGNATURE', SECRET = '你的SAS令牌(注意不要包含开头的?)'; GO -- 创建指向Blob容器的外部数据源 CREATE EXTERNAL DATA SOURCE BlobStorageDS WITH ( TYPE = BLOB_STORAGE, LOCATION = 'https://你的存储账户名.blob.core.windows.net/你的容器名', CREDENTIAL = BlobStorageCredential ); GO
步骤2:导出Varbinary数据至Blob
假设你的数据存储在Documents表,包含DocumentID(主键)和Document(Varbinary(MAX))列:
DECLARE @Document VARBINARY(MAX); DECLARE @BlobPath NVARCHAR(255) = 'pdfs/目标文件名.pdf'; -- Blob中的存储路径(含文件名) -- 从表中获取PDF的Varbinary数据 SELECT @Document = Document FROM Documents WHERE DocumentID = 1; -- 将数据写入Azure Blob INSERT INTO OPENROWSET( BULK @BlobPath, DATA_SOURCE = 'BlobStorageDS', SINGLE_BLOB ) VALUES (@Document); GO
方案2:使用CLR存储过程(灵活扩展)
通过编写.NET CLR存储过程,直接调用Azure Blob存储SDK上传数据,适合复杂业务场景。
步骤1:启用CLR集成
sp_configure 'show advanced options', 1; RECONFIGURE; sp_configure 'clr enabled', 1; RECONFIGURE; GO
步骤2:编写并部署CLR存储过程
编写C#代码(需引用Azure.Storage.Blobs NuGet包):
using Microsoft.Azure.Storage; using Microsoft.Azure.Storage.Blob; using System.Data.SqlClient; using System.Data.SqlTypes; using Microsoft.SqlServer.Server; public class BlobUploader { [SqlProcedure] public static void UploadToBlob(SqlString connectionString, SqlString containerName, SqlString blobName, SqlBinary documentData) { CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString.Value); CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); CloudBlobContainer container = blobClient.GetContainerReference(containerName.Value); container.CreateIfNotExists(); CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName.Value); blockBlob.UploadFromByteArray(documentData.Value, 0, documentData.Value.Length); } }
编译为DLL后,部署到SQL Server:
CREATE ASSEMBLY BlobUploadAssembly FROM 'C:\你的DLL路径\BlobUploader.dll' WITH PERMISSION_SET = UNSAFE; -- 需访问外部资源 CREATE PROCEDURE UploadToBlob @ConnectionString NVARCHAR(MAX), @ContainerName NVARCHAR(255), @BlobName NVARCHAR(255), @DocumentData VARBINARY(MAX) AS EXTERNAL NAME BlobUploadAssembly.BlobUploader.UploadToBlob; GO
步骤3:调用存储过程
DECLARE @Document VARBINARY(MAX); SELECT @Document = Document FROM Documents WHERE DocumentID = 1; EXEC UploadToBlob @ConnectionString = '你的存储账户连接字符串', @ContainerName = '你的容器名', @BlobName = 'pdfs/目标文件名.pdf', @DocumentData = @Document; GO
方案3:使用PowerShell批量导出
适合一次性批量导出场景,从SQL Server读取数据后直接上传至Blob:
# 1. 从SQL Server获取Varbinary数据 $sqlConn = New-Object System.Data.SqlClient.SqlConnection("Server=你的SQL服务器地址;Database=你的数据库名;Integrated Security=True;") $sqlConn.Open() $sqlCmd = New-Object System.Data.SqlClient.SqlCommand("SELECT Document FROM Documents WHERE DocumentID = 1", $sqlConn) $docData = $sqlCmd.ExecuteScalar() $sqlConn.Close() # 2. 上传至Azure Blob $storageAccount = "你的存储账户名" $container = "你的容器名" $blobName = "pdfs/目标文件名.pdf" $sasToken = "你的SAS令牌" $blobUri = "https://$storageAccount.blob.core.windows.net/$container/$blobName?$sasToken" $webClient = New-Object System.Net.WebClient $webClient.UploadData($blobUri, $docData)
内容的提问来源于stack exchange,提问作者ALdo
相关产品推荐
相关产品推荐

