Reputation: 623
I have a table City
; my Pic
column datatype is varbinary(max)
:
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
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