I recently encountered an interesting issue where XML elements had similar names but differed in character capitalization.
Lets show it via an example:
At first, will declare an XML variable and assign the simplest XML code to it:
DECLARE @xml XML = ' <ROOT> <ELEMENT NAME="ElementName" VALUE="PascalCase" /> <ELEMENT NAME="ELEMENTNAME" VALUE="UPPERCASE" /> <ELEMENT NAME="elementname" VALUE="LOWERCASE" /> </ROOT>'; SELECT @xml;
DECLARE @RequestElement SYSNAME = 'ElementName'; SELECT [Case] = 'Not case sensitive' , ElementName = C.value('@NAME', 'VARCHAR(100)') , ElementValue = C.value('@VALUE', 'VARCHAR(100)') FROM @xml.nodes('//ELEMENT') AS X(C) WHERE C.value('@NAME', 'VARCHAR(100)') = @RequestElement;
That happened because SQL Server is not case sensitive by default.
In order to return the record I need I may switch the whole database I'm working in to Case Sensitive Collation or just simply add a Case Sensitive collation to my WHERE clause like this:
DECLARE @RequestElement SYSNAME = 'ElementName'; SELECT [Case] = 'Case sensitive using Collation' , ElementName = C.value('@NAME', 'VARCHAR(100)') , ElementValue = C.value('@VALUE', 'VARCHAR(100)') FROM @xml.nodes('//ELEMENT') AS X(C) WHERE C.value('@NAME', 'VARCHAR(100)') = @RequestElement COLLATE Latin1_General_CS_AS;
DECLARE @RequestElement SYSNAME = 'ElementName'; SELECT [Case] = 'Case sensitive via parameter' , ElementName = C.value('@NAME', 'VARCHAR(100)') , ElementValue = C.value('@VALUE', 'VARCHAR(100)') FROM @xml.nodes('//ELEMENT[@NAME=sql:variable("@RequestElement")]') AS X(C)
- Filtering in the "WHERE" clause depends on SQL Server database collation, but an XML query is always case sensitive.