Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 FOR XML Пустые теги  [new]
doom.ka
Member

Откуда:
Сообщений: 4
Как перестроить запрос "SELECT ... FOR XML", чтобы в итоговом xml-документе не было пустых тегов?
Часть запроса:
Select
(SELECT
p1.PerID UID,
p1.IdDocSeries DocumentSeries,
p1.IdDocNumber DocumentNumber,
CONVERT(date, p1.BirthDate) BirthDate,
p1.BirthPlace
FROM Person p1
WHERE p1.PerID=Application.PerID
FOR XML PATH('IdentityDocument'), ELEMENTS, TYPE)
from PerApp Application
where Application.PerID = 2834
FOR XML PATH('Application'),
Root('Applications')


Результат:
<Applications>
<Application>
<IdentityDocument>
<UID>2834</UID>
<DocumentSeries />
<DocumentNumber>5906677</DocumentNumber>
<BirthDate>1990-12-31</BirthDate>
<BirthPlace>Казахстан</BirthPlace>
</IdentityDocument>
</Application>
</Applications>

- например, чтобы <DocumentSeries /> не было в документе, если он пустой?
Пробовались разные варианты: FOR XML RAW, FOR XML AUTO

В документациях сказано:
Директива elements создает документ XML, где каждое значение столбца отображается в элемент.
Если значением столбца является null, то по умолчанию не добавляется никакой элемент.
SQL Server позволяет отображать отсутствующие значения в документе XML при использовании директивы elements
с опцией xsinil.

Но я не указываю ELEMENTS xsinil, что нужно поменять в запросе?
28 ноя 12, 14:41    [13543155]     Ответить | Цитировать Сообщить модератору
 Re: FOR XML Пустые теги  [new]
denis2710
Member

Откуда: Москва
Сообщений: 3384
doom.ka,
+ как вариант

declare @t table ( id int, s varchar(10) )
insert  into @t
        ( id, s )
values  ( 1, 'sassda' )
        ,
        ( 2, null )
select  t.id
      , isnull(t.s, '') as s
from    @t as t
for     xml auto
 
 
declare @t1 table ( id int, s varchar(10) )
insert  into @t1
        ( id, s )
values  ( 1, 'sassda' )
        ,
        ( 2, null )
select  t1.id
      , t1.s
from    @t1 as t1
for     xml auto

28 ноя 12, 14:47    [13543214]     Ответить | Цитировать Сообщить модератору
 Re: FOR XML Пустые теги  [new]
doom.ka
Member

Откуда:
Сообщений: 4
denis2710, Спасибо большое, хороший способ.
Но это только часть запроса, в полном запросе используются порядка 30 таблиц, с несколькими уровнями вложения одного for xml в другой, итоговый xml не настолько линейной структуры. Не представляю, как это применить в моем случае. Была надежда, что надо как-то изменить запрос for xml...
28 ноя 12, 15:07    [13543396]     Ответить | Цитировать Сообщить модератору
 Re: FOR XML Пустые теги  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381
> Если значением столбца является null

а оно null ? если что, в ms sql пустая строка и null - разные вещи.
28 ноя 12, 15:33    [13543636]     Ответить | Цитировать Сообщить модератору
 Re: FOR XML Пустые теги  [new]
dalex1973
Member

Откуда: Польша
Сообщений: 287
daw
> Если значением столбца является null

а оно null ? если что, в ms sql пустая строка и null - разные вещи.

Согласен с daw, попробуйте дать:
NULLIF(p1.IdDocSeries,'') DocumentSeries
28 ноя 12, 15:38    [13543700]     Ответить | Цитировать Сообщить модератору
 Re: FOR XML Пустые теги  [new]
doom.ka
Member

Откуда:
Сообщений: 4
Спасибо!
Частично разобрались, проблема с полями типа varchar() not null,
т.е. нужно
(case p1.IdDocSeries when '' then null else p1.IdDocSeries end) DocumentSeries

остался вопрос с вложенными тегами, например:
SELECT er.ErID UID,
er.TotalMark ResultValue,
(SELECT EgeID
FROM EntResult
WHERE ErID = er.ErID
FOR XML AUTO, ELEMENTS, TYPE )
FROM EntResult er
WHERE er.PerAppID = App.PerAppID
FOR XML PATH('EntranceTestResult'), ELEMENTS, TYPE

<EntranceTestResult>
<UID>11944</UID>
<ResultValue>73.0</ResultValue>
<EntResult>
<EgeID>966</EgeID>
</EntResult>
</EntranceTestResult>

, если же в EntResult вложенного тега нет, результат запроса пустой, то будет пустой тег <EntResult />:

<EntranceTestResult>
<UID>11938</UID>
<ResultValue>37.0</ResultValue>
<EntResult />
</EntranceTestResult>

как можно обойти такую ситуацию?
28 ноя 12, 15:52    [13543870]     Ответить | Цитировать Сообщить модератору
 Re: FOR XML Пустые теги  [new]
super-code
Member

Откуда:
Сообщений: 244
doom.ka,

case when not exits (SELECT EgeID
FROM EntResult
WHERE ErID = er.ErID
FOR XML AUTO, ELEMENTS, TYPE ) then null
else
(SELECT EgeID
FROM EntResult
WHERE ErID = er.ErID
FOR XML AUTO, ELEMENTS, TYPE )
end

МОжно использовать WITH CTE, чтобы не указывать запрос дважды.
28 ноя 12, 16:17    [13544146]     Ответить | Цитировать Сообщить модератору
 Re: FOR XML Пустые теги  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381
так можно попробовать
SELECT er.ErID UID, 
er.TotalMark ResultValue,
(SELECT EgeID 
FROM EntResult
 WHERE ErID = er.ErID
 FOR XML AUTO, ELEMENTS, TYPE ).query('for $s in . where not(empty(./*/*)) return($s)')
FROM EntResult er
 WHERE er.PerAppID = App.PerAppID
 FOR XML PATH('EntranceTestResult'), ELEMENTS, TYPE
28 ноя 12, 16:40    [13544402]     Ответить | Цитировать Сообщить модератору
 Re: FOR XML Пустые теги  [new]
doom.ka
Member

Откуда:
Сообщений: 4
Спасибо большое! Оба способа работают.
29 ноя 12, 15:53    [13550471]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить