Moving PDF files from a SQL Server Table to Blob Storage

ffdz8vbo  于 2023-10-15  发布在  SQL Server
关注(0)|答案(1)|浏览(122)

I am trying to move PDF files from the Azure SQL Server database table to Blob Storage and running into some trouble.

I am trying to use the SQL Server stored procedure sp_invoke_external_rest_endpoint to accomplish this task. The issue is it is converting my file to Unicode before transmitting:

Here is my code

DECLARE @bytes VARBINARY(MAX) = NULL;
DECLARE @fileName VARCHAR(MAX) = NULL;

SELECT TOP 1 @bytes = Bytes, @fileName = FileName
FROM #TempPdf
OPTION(RECOMPILE);

DECLARE @response VARCHAR(MAX) = NULL;
DECLARE @storageContainerUrl VARCHAR(MAX) = 'https://mystorage.blob.core.windows.net/testing-pdfs/';

DECLARE @url VARCHAR(MAX) = CONCAT(@storageContainerUrl, @fileName);
DECLARE @payload VARCHAR(MAX) = @bytes;
DECLARE @payloadLength INT = DATALENGTH(@payload);

DECLARE @headers VARCHAR(1000) = JSON_OBJECT
(
        'content-length': @payloadLength,
        'x-ms-content-length': CAST(@payloadLength AS VARCHAR(20)),
        'content-type': 'application/x-www-form-urlencoded',
        'Accept': 'application/xml',
        'x-ms-blob-type': 'BlockBlob'
);

SELECT
@bytes AS Bytes,
DATALENGTH(@bytes) AS BytesLength,
@payload AS Payload,
DATALENGTH(@payload) AS PayloadLength;

EXEC sp_invoke_external_rest_endpoint
    @url = @url,
    @method = 'PUT',
    @headers = @headers,
    @payload = @payload,
    @credential = 'MyCredentials',
    @response = @response OUTPUT;

SELECT CAST(@response AS XML) AS Response;

The data length of both the bytes( VARBINARY(MAX) ) and payload( VARCHAR(MAX) ) is 88,698 , which is correct for this PDF. However, when I look at the size in Blob Storage it is 127KiB, which is larger than 87Ki it should be.

I believe it doing this because sp_invoke_external_rest_endpoint parameter @payload is a NVARCHAR(MAX) , so it's converting my 8-bit variable to Unicode, which is causing file corruption.

Is there a way to use sp_invoke_external_rest_endpoint without file corruption or an alternative way of doing this in a stored procedure?

If all else fails, I will just have to accomplish this using C# and create some type of temporary job.

Thanks!

0dxa2lsx

0dxa2lsx1#

A PDF is a binary file. You can't just convert it to a varchar(max) and send it as a string. You must send it as binary data. But sp_invoke_external_rest_endpoint doesn't accept binary payloads because it's for calling REST endpoints.

So you'll need an Azure function or similar to do this. You can either have the function read the PDF from Azure SQL and write the blob, or have it accept the PDF data encoded in Base64 or hex string encoded as a string from sp_invoke_external_rest_endpoint and decode it to a binary file and write it to storage.

相关问题