Преобразование типа данных изображения в VARCHAR в SQL Server 2008 - PullRequest
17 голосов
/ 24 октября 2011

У нас есть база данных TestPartner в SQL Server. Описания ошибок хранятся в столбце типа изображения. Нам нужно написать запрос для отображения данных в виде таблицы HTML. У нас есть этот запрос, который считывает данные из соответствующих таблиц для отображения информации в формате xml с использованием For XML. Но преобразование типа данных изображения в varchar вызывает исключение: «FOR XML не удалось сериализовать данные для узла« TD », поскольку он содержит символ (0x0002), который не разрешен в XML. Чтобы извлечь эти данные с использованием FOR XML, преобразуйте его в двоичный файл , varbinary или image data и используйте директиву 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

Это возвращает странный символ для каждой строки. Может кто-нибудь знает, как заставить эту вещь работать.

Ответы [ 5 ]

13 голосов
/ 22 мая 2017

Простой ответ:

select cast(cast(my_column as varbinary(max)) as varchar(max)) as column_name
from   my_table

Преобразует столбец в формат varchar. nvarchar (max) может быть лучше, если у вас есть данные Unicode.

7 голосов
/ 18 февраля 2015

Вы можете конвертировать так же, как это

convert (varchar(max) , convert (varbinary (max) , blob_data)), cast(cast(blob_data as binary) as varchar(max)) 
3 голосов
/ 11 октября 2017

Попробуйте этот код:

Select  MASTER.dbo.Fn_varbintohexstr(tpcommanddetail) From TestPartnerDB.TP_RESULTS_RECORDS
3 голосов
/ 26 декабря 2012

Если данные были сохранены в поле изображения как данные 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) кажется мне бесполезным.

Использование бинарного (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');
2 голосов
/ 17 ноября 2011

Я полагаю, что данные, хранящиеся в столбце вашего изображения, не являются "обычным" текстом - я предполагаю, что это какая-то произвольная структура данных (отсюда и решение использовать изображение вместо 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...