I have an XML column in a SQL Server 2008 database with values like the following simplified examples:
Case 1
<root>
<child>sometimes text here</child>
<otherstuff ..... />
</root>
Case 2
<root>
<child/>
<otherstuff ..... />
</root>
Given a string value, I would like to be able to select rows that have a specific value in the "child" node, including selection of case 2.
So for example, if I have a local variable:
declare @queryText nvarchar(MAX)
select @queryText = 'sometimes text here'
I can select the row that matches case 1 by:
select * from [my_table]
where [my_xml_column].exist('/root/child[text()=sql:variable("@queryText")]') = 1
However, for case 2, where I would expect @queryText = '' or @queryText = NULL to work, neither matches.
As a workaround I can use:
select * from [my_table]
where [my_xml_column].value('(/root/child)[1], 'nvarchar(MAX)') = @queryText
This works, but it leaves me feeling like I'm missing something and using a dirty workaround to test for existence with .value() rather than .exist()... Is there a similar expression I can [and should?] use in .exist() to match either specific text or an empty node? Is there any reason to care beyond readability? I look forward to my impending facepalm when somebody points out whatever blatantly obvious thing I have missed. :)