henrry
henrry

Reputation: 623

Update var binary to existing SQL columns (Add to existing image)?

I have a table City; my Pic column datatype is varbinary(max):

enter image description here

I update my pic column with this code and work (for 1 pic):

UPDATE City 
SET pic = 0xwed323422222222.... 
WHERE id = 4

but how can I update 3 images or more in Pic column? (add to existing image)

It my means I stored in table where id = 4 just 1 image binary. How can I save more than 1 image in a single column?

Upvotes: 1

Views: 1208

Answers (1)

lptr
lptr

Reputation: 6788

You could store multiple images in a "semi-structured" way, within a single column by leveraging xml (and its structural integrity). You could change the datatype of the "pic" column to xml or keep it varbinary (some type casting is required for the latter).

The following example assumes varbinary storage for "the image" column and a "c:\testnew" folder (on the sql instance) which contains 3 images (image[1..3].png).

First, the two images are loaded for "the image" column of cityid=1 and later on the third image is appended to the binary data(first 2 pics) with update .write(). Removing images or inserting images in specific place within the blob could be achieved by utilizing the xml.modify() method.

All this, if you really need/have to store multiple images in a single row&column.

create table dbo.TestImages
(
    id int identity(1,1) constraint pkidTestImages primary key clustered(id),
    CityId int,
    ImagesBlobXml varbinary(max) --or xml
)
go


--insert two images from folder c:\testnew
insert into dbo.TestImages
(
    CityId, ImagesBlobXml
)

values (
1, 
cast((
select TheImage
from 
(
select *
from openrowset(bulk N'C:\testnew\image1.png', single_blob) as i(TheImage)
union all
select *
from openrowset(bulk N'C:\testnew\image2.png', single_blob) as i(TheImage)
--union all
--select *
--from openrowset(bulk N'C:\testnew\stackoverflow.png', single_blob) as i(TheImage)
) as images
for xml path(''), type
) as varbinary(max))
);

select 'table content', *
from  dbo.TestImages;


--retrieve images (2)
select 'images in blob, initial insert', t.id, t.CityId, i.bin.value('.', 'varbinary(max)') as TheImage
from
(
select *, cast(ImagesBlobXml as xml) as ImagesBlobXmlXML
from dbo.TestImages 
) as t
cross apply t.ImagesBlobXmlXML.nodes('TheImage') as i(bin);


--append new image
update t
set ImagesBlobXml .WRITE( --note:write cannot be used on NULL values
cast((
select TheImage
from 
(
select *
from openrowset(bulk N'C:\testnew\image3.png', single_blob) as i(TheImage)
) as images
for xml path(''), type
) as varbinary(max)) , 
null, 0 --write() append
)
from dbo.TestImages as t
where CityId = 1;


--retrieve the images (3)
select 'images in blob, after update_append', t.id, t.CityId, i.bin.value('.', 'varbinary(max)') as TheImage
from
(
select *, cast(ImagesBlobXml as xml) as ImagesBlobXmlXML
from dbo.TestImages 
) as t
cross apply t.ImagesBlobXmlXML.nodes('TheImage') as i(bin);

--check for any diff
select i.bin.value('.', 'varbinary(max)') as TheImage
from
(
select *, cast(ImagesBlobXml as xml) as ImagesBlobXmlXML
from dbo.TestImages 
) as t
cross apply t.ImagesBlobXmlXML.nodes('TheImage') as i(bin)
except
select TheImage
from 
(
select *
from openrowset(bulk N'C:\testnew\image1.png', single_blob) as i(TheImage)
union all
select *
from openrowset(bulk N'C:\testnew\image2.png', single_blob) as i(TheImage)
union all
select *
from openrowset(bulk N'C:\testnew\image3.png', single_blob) as i(TheImage)
) as images;
go

--cleanup
drop table dbo.TestImages;
go

Upvotes: 1

Related Questions