我们在 SQL Server 中有 TestPartner 数据库。错误的描述存储在“image”数据类型列中。我们需要编写一个查询来将数据显示为 html 表。我们有一个查询,它从相应的表中读取数据,并使用
For XML
将信息显示为 xml。但是将图像数据类型转换为 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
这会为每行返回奇怪的字符。有谁知道如何让这个东西发挥作用?
简单的答案是
select cast(cast(my_column as varbinary(max)) as varchar(max)) as column_name
from my_table
这会将列转换为 varchar 格式。 如果您有 unicode 数据,nvarchar(max) 可能会更好。
你也可以这样转换
convert (varchar(max) , convert (varbinary (max) , blob_data)), cast(cast(blob_data as binary) as varchar(max))
如果数据已作为 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');
试试这个代码:
Select MASTER.dbo.Fn_varbintohexstr(tpcommanddetail) From TestPartnerDB.TP_RESULTS_RECORDS
我的猜测是图像列中存储的数据不是“正常”文本 - 我猜测它是某种任意数据结构(因此决定使用图像而不是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
对我转换 IMAGE 列有用的是:
SELECT convert(varchar(max), cast(mypicture as varbinary(max)), 1)
FROM MyTable
这对我有用。
select cast(cast(imageVal as varbinary(max)) as varchar(max)) from table