Introduction
Transact-SQL does not include built in function to convert binary type into base64 string and vice versa, but it does includes several built-in options we can use. This article demonstrates several options to convert VARBINARY data into Base64 string, and vice versa convert Base64 string into VARBINARY.
Table of Contents
Preparation
1. Create folder
For the sake of this demo we will create the folder: C:\Ariely_BASE46_VARCHAR
2. insert image
we will need a simple image for our demo. For the sake of this demo we will use your personal avatar image from your MSDN profile.
Go to your profile -> right click on your avatar image -> and save the image in the new folder, which we created.
The avatar image named avatar.jpg
3. Create new table
USE tempdbGO DROP TABLE IF EXISTS AriTestTblGO CREATE TABLE AriTestTbl( Id int identity(1,1) primary key, AvatarBinary VARBINARY(MAX), AvatarBase64 VARCHAR(MAX))GO
4. Import the image into the database as binary data
* Let's insert the same image 3 times, simply to give us several rows for the demo.
Insert AriTestTbl(AvatarBinary)SELECT col FROM OPENROWSET( BULK N'C:\Ariely_BASE46_VARCHAR\avatar.jpg', SINGLE_BLOB) Tbl(col)GO 3 SELECT * FROM AriTestTblGO
OK, now we can start our discussion and demo...
Convert VARBINARY to Base64 String
we can use XML built-in options and JSON built-in (from SQL Server 2016) functions, in order to convert VARBINARY into Base64. Using variables is a bit different from working with tables. Therefore, we will show both options in separate sections.
Converting Variables from VARBINARY to Base64
In this section we will use simple select from OPENROWSET query (same way we imported the image to the table), in order to configure the value of our VARBINARY variable.
Option 1: Convert binary to Base64 using JSON
The basic logic of this action based on:
- We select the value as table
- We convert the data in the table into JSON using the built-in hint "FOR JSON AUTO". This operating will automatically convert any binary data type in the table into BASE64 String.
- Next, Using the function OPENJSON, we extract the BASE64 String from the JSON
----------------------- Get valueDECLARE @B VARBINARY(MAX)SELECT @B = colFROM OPENROWSET(BULK N'C:\Ariely_BASE46_VARCHAR\avatar.jpg', SINGLE_BLOB) Tbl(col)----------------------- Convert to BASE64select colfrom openjson( ( select col from (SELECT @B as col) T for json auto )) with(col varchar(max))GoOption 2: Convert binary to Base64 using XML XQuery
XQuery (XML Query) is a query language designed to query XML data. Transact-SQL supports a subset of the XQuery language, which can be used for querying xml data type. For more information you can check the links
----------------------- Get valueDECLARE @B VARBINARY(MAX)SELECT @B = colFROM OPENROWSET(BULK N'C:\Ariely_BASE46_VARCHAR\avatar.jpg', SINGLE_BLOB) Tbl(col)----------------------- Convert to BASE64select cast('' as xml).value('xs:base64Binary(sql:variable("@B"))', 'varchar(max)')GOOption 3: Convert binary to Base64 using XML and the hint "for xml path"
----------------------- Get valueDECLARE @B VARBINARY(MAX)SELECT @B = colFROM OPENROWSET(BULK N'C:\Ariely_BASE46_VARCHAR\avatar.jpg', SINGLE_BLOB) Tbl(col)----------------------- Convert to BASE64select * from (select @B as '*') Tblfor xml path('')GOConverting Column values from VARBINARY to Base64
In most cases we will need to work on multiple rows in table, and we want to convert only the VARBINARY data into BASE64 String. The basic solution is the same as above, except for the solution using XML XQuery, which we will simply need to use different method.
Option 1: Convert binary to Base64 using JSON
select Id,AvatarBinaryfrom openjson( ( select Id,AvatarBinary from AriTestTbl for json auto )) with(Id int, AvatarBinary varchar(max))GOOption 2: Convert binary to Base64 using XML XQuery
select Id, cast('' as xml).value( 'xs:base64Binary(sql:column("AriTestTbl.AvatarBinary"))', 'varchar(max)' )from AriTestTblGOOption 3: Convert binary to Base64 using XML and the hint "for xml path"
select Id,AvatarBinary,sfrom AriTestTblcross apply (select AvatarBinary as '*' for xml path('')) T (s)GOConvert Base64 String to VARBINARY
Basically for each option demonstrated above, there is an equivalent option to convert the data in the opposite direction. For the sake of this article, we will focus on one example at this time.
Converting Variables from Base64 to VARBINARY
DECLARE @B VARBINARY(MAX)DECLARE @S VARCHAR(MAX)----------------------- Get Binary valueSELECT @B = colFROM OPENROWSET(BULK N'C:\Ariely_BASE46_VARCHAR\avatar.jpg', SINGLE_BLOB) Tbl(col)----------------------- Get the result of Convert Binary to BASE64 Stringselect @S = colfrom openjson( ( select col from (SELECT @B as col) T for json auto )) with(col varchar(max))----------------------- Convert BASE64 String back to BinarySELECT @B Original, @S Base64_String, CAST(N'' AS xml).value( 'xs:base64Binary(sql:variable("@S"))', 'varbinary(max)' ) Result_VarbinaryGOConverting column values from Base64 to VARBINARY
First we will fill the table with the BASE64 values of the images.
UPDATE AriTestTbl SET AvatarBase64 = sfrom AriTestTblcross apply (select AvatarBinary as '*' for xml path('')) T (s)GO SELECT * FROM AriTestTblGO
and now, we can see example of converting the data
SELECT AriTestTbl.AvatarBase64, CAST(N'' AS xml).value( 'xs:base64Binary(sql:column("AriTestTbl.AvatarBase64"))' , 'varbinary(max)') AS column_varbinaryFROM AriTestTblGOIn conclusion
As you can see in the above demo it is very simple to convert both direction between Base64 String and VARBINARY, using built-in XML and JSON features.
You might ask yourself, why do we need these type of actions in practice, in the SQL Server side. Won't is be better to do it in your application (client) side... Well, in most cases the answer is yes, but for example, in lot of cases we want to senfd email using the built-in stored procedure sp_send_dbmail. Using Base64 string we can include embedded images, which stored in the database as VARBINARY, in our email.
No comments:
Post a Comment