如何在Azure SQL的Stored Procedure中以blob形式读写Blob Storage
Azure SQL/SQL Server 原始二进制形式读写Azure Blob Storage实现方案
你提到的公开资料大多只覆盖OPENROWSET/BULK INSERT解析CSV/Excel等结构化文件的场景,确实很少提及原始Blob二进制流的读写方式,两个核心问题的可行性和具体实现如下:
问题1:存储过程内读取指定URL的Blob,输出varbinary(max)格式原始数据
结论:完全可行,全版本Azure SQL Database、SQL Server 2017及以上版本原生支持
实现步骤:
- 先创建数据库级别的凭据,关联Blob存储的读取权限SAS令牌:
注意SAS令牌不要带开头的-- 创建凭据,IDENTITY固定为SHARED ACCESS SIGNATURE CREATE DATABASE SCOPED CREDENTIAL BlobReadCred WITH IDENTITY = 'SHARED ACCESS SIGNATURE', SECRET = 'sv=2022-11-02&ss=b&srt=co&sp=r&st=2024-01-01T00:00:00Z&se=2025-01-01T00:00:00Z&sig=替换为你实际的SAS令牌';?符号,只需要保留sv到sig的完整参数串即可。 - 创建指向目标Blob容器的外部数据源:
CREATE EXTERNAL DATA SOURCE TargetBlobContainer WITH ( TYPE = BLOB_STORAGE, LOCATION = 'https://替换为你的存储账户名.blob.core.windows.net/替换为目标容器名', CREDENTIAL = BlobReadCred ); - 封装存储过程,用
OPENROWSET加SINGLE_BLOB参数读取原始二进制,不要加任何结构化解析相关参数(比如FORMATFILE、FIELDTERMINATOR、FIRSTROW等),即可拿到完整的原始文件内容:CREATE PROCEDURE sp_GetBlobBinary @BlobRelativePath NVARCHAR(1000), -- 传入容器内的文件相对路径,比如folder1/demo.pdf @FileBinary VARBINARY(MAX) OUTPUT AS BEGIN SELECT @FileBinary = BulkColumn FROM OPENROWSET( BULK @BlobRelativePath, DATA_SOURCE = 'TargetBlobContainer', SINGLE_BLOB ) AS RawBlob; END
如果是SQL Server 2016及更早版本,没有原生BLOB_STORAGE类型外部数据源支持,可以用OLE Automation对象调用HTTP接口读取,但不推荐,权限配置复杂且性能较差。
问题2:存储过程接收varbinary(max)入参,直接写入Blob Storage
结论:Azure SQL Database可原生实现,本地SQL Server需要借助CLR集成实现
两种落地方式:
- 方式一(Azure SQL Database专属,纯T-SQL实现,无外部依赖):
利用已正式发布的内置存储过程sp_invoke_external_rest_endpoint直接调用Blob Storage的Put Blob REST接口完成写入,全程逻辑都可以封装在存储过程内部:- 提前给SQL数据库的系统托管标识分配目标存储账户的「存储Blob数据参与者」权限,或者生成有写入权限的SAS令牌用于鉴权。
- 封装写入存储过程:
CREATE PROCEDURE sp_WriteBinaryToBlob @FileBinary VARBINARY(MAX), @BlobRelativePath NVARCHAR(1000) AS BEGIN DECLARE @PutUrl NVARCHAR(2000) = CONCAT( 'https://替换为你的存储账户名.blob.core.windows.net/替换为目标容器名/', @BlobRelativePath, '?替换为有写入权限的SAS令牌' ); EXEC sp_invoke_external_rest_endpoint @url = @PutUrl, @method = 'PUT', @headers = '{"x-ms-blob-type":"BlockBlob"}', @payload = @FileBinary; END
- 方式二(本地SQL Server适用):
启用数据库CLR集成,编写CLR存储过程封装Azure Blob Storage SDK的上传逻辑,部署后和普通T-SQL存储过程调用体验完全一致,不需要依赖外部服务调度。
注意:以上读写全程都是原始二进制流操作,不会对文件内容做任何结构化解析,完全不需要走表导入流程,只要不添加结构化文件解析相关参数,就不会出现CSV/Excel自动解析的行为。
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

