SQL ForXml; объединение полей, возвращающих либо список, разделенный запятыми, либо пустую строку

Я просмотрел несколько вопросов SO об использовании FOR XML, но либо пропустил, либо не нашел ничего конкретного для моего запроса.

К счастью, а может и нет, служба, в которую мне нужно отправить данные, хочет, чтобы поля из моей таблицы (таблиц) были представлены как атрибуты, а не элементы, что означает, что я могу использовать FOR XML AUTO. Однако для этого требуются некоторые вещи, которые я не уверен, как написать правильный sql для достижения, и для которых я приветствовал бы некоторые советы.

Некоторые поля (скажем, у меня есть три с именами Log1, Log2 и Log3) должны быть возвращены как один атрибут, вызываемый для аргументов Logs. Если все три поля журнала имеют значение Null, это должна быть пустая строка, или, если они содержат данные, они должны быть объединены запятой в качестве разделителя. Я подозреваю, что простой Coalesce здесь не подходит, но я не совсем уверен, что еще можно сделать.

Как я уже сказал, я приветствовал бы некоторые предложения. Спасибо.

РЕДАКТИРОВАТЬ

Извиняюсь, нужно было добавить sql для помощи.

SELECT  LandingId,
    VesselId,
    TicketNumber,
    CONVERT(VARCHAR(10),LandingDate1,112) AS landingdate1,
    Log1,
    Log2,
    Log3,
    COALESCE(VesselName,'') AS vesselName,
    VesselOwner
FROM Landings.LandingHeaders AS sale  FOR XML AUTO

Log1, Log2 и Log3 должны стать журналами и представлять собой либо пустую строку, если все они равны нулю, либо список, разделенный запятыми, если они содержат данные.

EDIT2 (текущий вывод с удаленными VesselName и Owner для сохранения конфиденциальности)

<sale LandingId="3388" VesselId="1" TicketNumber="1         " landingdate1="20130705" />

Ass the Log values are null nothing is being returned, Not sure if I can use a form of coalesce to either produce the empty string or a comma separated list. I do know that I need to trim the ticketNumber.


person Dom Sinclair    schedule 15.05.2015    source источник
comment
если вы добавите некоторые примеры данных, запрос, который вы используете сейчас, и ожидаемый результат, мы сможем помочь вам намного лучше   -  person Jeremy C.    schedule 15.05.2015
comment
Если вы предоставите желаемую структуру xml, а также вашу схему sql и некоторые ваши попытки запроса - будет намного проще что-то предложить. Прямо сейчас ваш вопрос не очень читабелен и ясен.   -  person Andy Korneyev    schedule 15.05.2015
comment
Добавил sql, прошу прощения, что не сделал этого раньше.   -  person Dom Sinclair    schedule 15.05.2015
comment
Ок, отлично. А как насчет желаемой структуры xml? Как это должно выглядеть?   -  person Andy Korneyev    schedule 15.05.2015
comment
Добавил вывод, спасибо   -  person Dom Sinclair    schedule 15.05.2015


Ответы (1)


Лучше использовать не for xml auto, а for xml path, так как это дает гораздо больше гибкости.

Ваша желаемая цель (если я правильно понял) может быть достигнута так (я пропустил некоторые поля)

select
    VesselId as '@VesselId',
    TicketNumber as '@TicketNumber',
    isnull(Log1 + ',', '') + isnull(Log2 + ',', '') + isnull(Log3 + ',', '') as '@Log123'
from Landings.LandingHeaders for xml path('sale')

обновить

Честно говоря, в вашем конкретном случае вы также можете достичь своей цели, используя for xml auto, ключевую идею объединения полей, таких как

isnull(Log1 + ',', '') + isnull(Log2 + ',', '') + isnull(Log3 + ',', '')

чтобы получить пустую строку, если все три поля пусты, а непустая строка с некоторыми данными в противном случае остается прежней.

person Andy Korneyev    schedule 15.05.2015
comment
Большое спасибо, Энди, это здорово. я придумал ; COALESCE(CONCAT('',RTRIM(Log1), ',',RTRIM(Log2),',',RTRIM(Log3)),'') журналы AS, которые работают, но ваше решение более аккуратное. Я новичок в FOR XML, так в чем же преимущество Path перед AUTO? - person Dom Sinclair; 15.05.2015
comment
@DomSinclair, как я уже сказал, path дает вам гораздо больше гибкости, чем auto. Вы можете взглянуть на мой другой ответ, где я предоставил некоторые подробности об этом. - person Andy Korneyev; 15.05.2015
comment
Спасибо, Энди, +1 за ваш другой ответ, поскольку он хорошо объясняет. - person Dom Sinclair; 15.05.2015
comment
Энди, только что заметил, что выходные данные для нулевых значений включают запятые, например, ‹sale vesseID=2 logs=,, /› ‹sale vesseID=1 logs=L7014,L7015,L7016 /› ‹sale vesseID=22 logs=,, /› Как можно просто вернуть простую пустую строку, если журналы равны NULL? - person Dom Sinclair; 15.05.2015
comment
Не обращайте внимания, что я ошибаюсь, опечатка с моей стороны. - person Dom Sinclair; 15.05.2015
comment
@DomSinclair такое поведение возможно, если вы используете свой подход с concat, поскольку он преобразует нули в пустые строки, поэтому concat(null, ',', null) даст в результате ,, а isnull(null + ',', '') + isnull(null + ',', '') вернет пустую строку. - person Andy Korneyev; 15.05.2015