我有一個包含base64編碼的jpegs以及其他一些數據的表。 base64字符串存儲在VARCHAR(MAX)
列中。如何將base64編碼的圖像數據保存到動態命名的子文件夾中的文件中
如何將這些圖像保存到使用存儲過程中的表中的其他數據動態命名的文件夾內的實際文件?
我有一個包含base64編碼的jpegs以及其他一些數據的表。 base64字符串存儲在VARCHAR(MAX)
列中。如何將base64編碼的圖像數據保存到動態命名的子文件夾中的文件中
如何將這些圖像保存到使用存儲過程中的表中的其他數據動態命名的文件夾內的實際文件?
我通過結合來自不同地方的許多小技巧找到了答案,並希望在這裏整理它們,因爲似乎沒有人看到完整的過程。
我有兩個表,分別叫Photos
和PhotoBinary
。 Photos
包含至少一個PhotoID BIGINT
,Base64
數據VARCHAR(MAX)
,以及根據需要增加FolderName
- NVARCHAR(15)
。我還有一個BIT
字段將它們標記爲isProcessed
。 PhotoBinary
有一個VARBINARY(MAX)
列,應該是空的。
第二個表有兩個目的,它以二進制格式保存轉換後的base64編碼圖像,並且允許我解決BCP在使用「格式文件時從表中導出數據時不會讓您跳過列的事實「來指定列格式。所以在我的情況下,數據必須獨自坐在一張桌子上,我確實試着從一個視圖中看到它,但是前面提到的問題是不允許跳過id列。
主存儲過程有一個bcp
命令,該命令取決於使用以下SQL創建的.fmt
文件。我非常肯定,我必須使用純文本編輯器編輯生成的文件,將8
更改爲0
,表示SQLBINARY
之後的前綴長度。我不能在主存儲過程的命令中使用-n
開關,因爲它導致在結果文件中放入一個8字節前綴,這使得它成爲無效的jpeg。所以,我用編輯過的格式文件來解決這個問題。
DECLARE @command VARCHAR(4000);
SET @command = 'bcp DB.dbo.PhotoBinary format nul -T -n -f "A:\pathto\photobinary.fmt"';
EXEC xp_cmdshell @command;
然後我在我運行到圖像導出到相應的文件夾的存儲過程如下:
DECLARE @command VARCHAR(4000),
@photoId BIGINT,
@imageFileName VARCHAR(128),
@folderName NVARCHAR(15),
@basePath NVARCHAR(500),
@fullPath NVARCHAR(500),
@dbServerName NVARCHAR(100);
DECLARE @directories TABLE (directory nvarchar(255), depth INT);
-- The location of the output folder
SET @basePath = '\\server\share';
-- The server that the photobinary db is on
SET @dbServerName = 'localhost';
-- @basePath values, get the folders already in the output folder
INSERT INTO @directories(directory, depth) EXEC master.sys.xp_dirtree @basePath;
-- Cursor for each image in table that hasn't already been exported
DECLARE photo_cursor CURSOR FOR
SELECT PhotoID,
'some_image_' + CAST(PhotoID AS NVARCHAR) + '.jpg',
FolderName
FROM dbo.Photos
WHERE isProcessed = 0;
OPEN photo_cursor
FETCH NEXT FROM photo_cursor
INTO @photoId,
@imageFileName,
@folderName;
WHILE (@@FETCH_STATUS = 0) -- Cursor loop
BEGIN
-- Create the @basePath directory
IF NOT EXISTS (SELECT * FROM @directories WHERE directory = @folderName)
BEGIN
SET @fullPath = @basePath + '\' + @folderName;
EXEC master.dbo.xp_create_subdir @fullPath;
END
-- move and convert the base64 encoded image to a separate table in binary format
-- it should be the only row in the table
INSERT INTO DB.dbo.PhotoBinary (PhotoBinary)
SELECT CAST(N'' AS xml).value('xs:base64Binary(sql:column("Base64"))', 'varbinary(max)')
FROM DB.dbo.Photos
WHERE PhotoID = @photoId;
-- This command uses the command-line BCP tool to "bulk export" the image data in binary to an "archive" file that just happens to be a jpg
SET @command = 'bcp "SELECT TOP 1 PhotoBinary FROM DB.dbo.PhotoBinary" queryout "' + @basePath + '\' + @folderName + '\' + @imageFileName + '" -T -S ' + @dbServerName + ' -f "A:\pathto\photobinary.fmt"';
EXEC xp_cmdshell @command;
-- clean up the photo data
DELETE FROM DB.dbo.PhotoBinary;
-- mark photo as processed
UPDATE DB.dbo.Photos SET isProcessed = 1 WHERE PhotoID = @photoId;
FETCH NEXT FROM photo_cursor
INTO @photoId,
@imageFileName,
@folderName;
END -- cursor loop
CLOSE photo_cursor
DEALLOCATE photo_cursor
你問的問題19分鐘前,那麼你19分鐘前回答了 – Mark
@Mark然後你評論1分鐘前... – Klors