我们在SQL Server中有TestPartner数据库。错误的描述存储在“image”数据类型列中。我们需要编写一个查询来将数据显示为html表。我们有这个查询从相应的表中读取数据,以使用For XML
将信息显示为xml。但是将image数据类型转换为varchar会引发异常:“FOR XML无法序列化节点'TD'的数据,因为它包含XML中不允许的字符(0x0002)。要使用FOR XML检索此数据,请将其转换为二进制,varbinary或image数据类型,并使用BINARY BASE64指令。“。
查询:
DECLARE @ResultsTable nvarchar(MAX)
--Create the XML table with the query results
SET @ResultsTable =
N'<H3>QA Automation Tests Results Summary </H3>' +
N'<table border="1">' +
N'<tr><th>Test Name</th><th>Execution Date</th>' +
N'<th>Check Name</th><th>Description</th></tr>' +
CAST ( (
select distinct Name as TD, '',
(Select CAST(CONVERT(nchar(100),CAST( TPCommandDetail AS BINARY(100) )) as VARCHAR(100)) ) as TD, ''
FROM TestPartnerDB.TP_RESULTS_RECORDS
FOR XML PATH('tr'), TYPE
) AS nvarchar(max) ) + N'</table>'
SELECT @ResultsTable
令人惊讶的是,它适用于某些记录,只要你将大小设置为200即可。它会再次抛出错误。我也尝试过:
Select CONVERT(varchar(1000), convert(varbinary(1000), tpcommanddetail)) From TestPartnerDB.TP_RESULTS_RECORDS
每行返回奇怪的字符。任何人都可以知道如何使这件事工作。
答案 0 :(得分:11)
简单的答案是
select cast(cast(my_column as varbinary(max)) as varchar(max)) as column_name
from my_table
这会将列转换为varchar格式。如果你有unicode数据,nvarchar(max)可能会更好。
答案 1 :(得分:7)
您也可以像这样转换
convert (varchar(max) , convert (varbinary (max) , blob_data)), cast(cast(blob_data as binary) as varchar(max))
答案 2 :(得分:3)
如果数据已作为Unicode数据存储在图像字段中,那么如果将行Select CONVERT(nvarchar(1000), convert(varbinary(1000), tpcommanddetail)) From TestPartnerDB.TP_RESULTS_RECORDS
替换为Select CONVERT(varchar(1000), convert(varbinary(1000), tpcommanddetail)) From TestPartnerDB.TP_RESULTS_RECORDS
,它将无法正常工作。
使用正确的排序规则和字符大小进行从二进制数据到文本的第一次转换非常重要:如果文本位于Ascii中,则必须使用varchar()并且文本是否为Unicode ,你必须使用nvarchar()。
从nvarchar(100)到varchar(100)的第二次转换对我来说没什么用。
使用binary(100)代替varbinary(100)对我来说也很可疑。
最后,如果你得到像0x0002这样的奇怪字符,那么可能这就是为什么它存储在图像字段而不是文本字段中:这是一个特殊格式的字段,其中并非所有字符都是文本字符。但是,由于您没有向我们展示以二进制(或更准确地说,十六进制)或任何结果打印原始字段的结果,因此无法再说些什么。
我刚做了几个测试;有了这些,你应该能够理解发生了什么:
select ascii ('A'), unicode(N'A');
select convert (binary(2), ascii('A')), convert (binary(2), unicode(N'A'));
--
declare @ab binary(10), @vab varbinary(10);
declare @nab binary(10), @vnab varbinary(10);
--
set @ab = convert (binary (10), 'AB');
set @vab = convert (varbinary (10), 'AB');
set @nab = convert (binary (10), N'AB');
set @vnab = convert (varbinary (10), N'AB');
--
select @ab, @vab, @nab, @vnab;
--
select convert(varchar(10), @ab) + '*',
convert(varchar(10), @vab) + '*',
convert(varchar(10), @nab) + '*',
convert(varchar(10), @vnab) + '*';
--
select len(convert(varchar(10), @ab)),
len(convert(varchar(10), @vab)),
len(convert(varchar(10), @nab)),
len(convert(varchar(10), @vnab));
--
select len(convert(varchar(10), @ab) + '*'),
len(convert(varchar(10), @vab) + '*'),
len(convert(varchar(10), @nab) + '*'),
len(convert(varchar(10), @vnab) + '*');
--
select convert(nvarchar(10), @ab) + '*',
convert(nvarchar(10), @vab) + '*',
convert(nvarchar(10), @nab) + '*',
convert(nvarchar(10), @vnab) + '*';
--
select len(convert(nvarchar(10), @ab)),
len(convert(nvarchar(10), @vab)),
len(convert(nvarchar(10), @nab)),
len(convert(nvarchar(10), @vnab));
--
select convert(varchar(10), convert(nvarchar(10), @ab)) + '*',
convert(varchar(10), convert(nvarchar(10), @vab)) + '*',
convert(varchar(10), convert(nvarchar(10), @nab)) + '*',
convert(varchar(10), convert(nvarchar(10), @vnab)) + '*';
--
select len(convert(varchar(10), convert(nvarchar(10), @ab))),
len(convert(varchar(10), convert(nvarchar(10), @vab))),
len(convert(varchar(10), convert(nvarchar(10), @nab))),
len(convert(varchar(10), convert(nvarchar(10), @vnab)));
--
select convert(nvarchar(10), @nab) for xml path('tr');
select convert(varchar(10), convert(nvarchar(10), @nab)) for xml path('tr');
select 'The Name' as td, '', convert(nvarchar(10), @nab) as td for xml path('tr');
答案 3 :(得分:2)
我的猜测是存储在图像列中的数据不是“正常”文本 - 我猜它是一些任意数据结构(因此决定使用图像而不是varchar)?
我试了一下没有问题:
declare @data varchar(max)
declare @fred table (d1 varchar(max), d2 xml, d3 image)
set @data = 'here is some data'
while (len(@data) < 200) set @data = @data + ' ' + cast(rand() as varchar)
insert into @fred (d1,d2,d3) values (@data,@data,@data)
set @data = 'here is some more data'
while (len(@data) < 200) set @data = @data + ' ' + cast(rand() as varchar)
insert into @fred (d1,d2,d3) values (@data,@data,@data)
declare @xml xml
set @xml = (select cast(cast(d3 as varbinary(max)) as varchar(max)) as 'td' from @fred FOR XML PATH('tr'), TYPE)
select @xml
答案 4 :(得分:2)
试试这段代码:
Select MASTER.dbo.Fn_varbintohexstr(tpcommanddetail) From TestPartnerDB.TP_RESULTS_RECORDS