У меня есть столбец XML в базе данных SQL Server 2008 со значениями, подобными следующим упрощенным примерам:
Случай 1
<root>
<child>sometimes text here</child>
<otherstuff ..... />
</root>
Случай 2
<root>
<child/>
<otherstuff ..... />
</root>
Учитывая строковое значение, я хотел бы иметь возможность выбирать строки, которые имеют определенное значение в «дочернем» узле, включая выбор случая 2.
Так, например, если у меня есть локальная переменная:
declare @queryText nvarchar(MAX)
select @queryText = 'sometimes text here'
Я могу выбрать строку, соответствующую случаю 1, следующим образом:
select * from [my_table]
where [my_xml_column].exist('/root/child[text()=sql:variable("@queryText")]') = 1
Однако для случая 2, когда я ожидаю, что @queryText = '' или @queryText = NULL будут работать, ни одно из них не соответствует.
В качестве обходного пути я могу использовать:
select * from [my_table]
where [my_xml_column].value('(/root/child)[1], 'nvarchar(MAX)') = @queryText
Это работает, но у меня возникает ощущение, что я что-то упускаю и использую грязный обходной путь для проверки существования с помощью .value(), а не .exist()... Есть ли подобное выражение, которое я могу [и должен?] использовать в .exist() для соответствия либо конкретному тексту, либо пустому узлу? Есть ли какая-то причина для беспокойства помимо читабельности? Я с нетерпением жду моего предстоящего фейспалма, когда кто-нибудь укажет на какую-то очевидную вещь, которую я пропустил. :)