Reputation: 95
I am trying to query an XML column to return all rows where an attribute is in a list of possible values.
XQuery allows something like
SELECT COUNT(*)
FROM table
WHERE xml_col.exist('//Field.[@name=("value1","value2","value3")]') = 1
which would return the number of records that have a Field with attribute @name set to either "value1", "value2" or "value3".
What I'd like to do is write a concise query that could handle the set "value1", "value2", "value3" as an input parameter, e.g.
DECLARE @list NVARCHAR(100)
SET @list = '("value1","value2","value3")'
SELECT COUNT(*)
FROM table
WHERE xml_col.exist('//Field.[@name=sql:variable("@list")]') = 1
which, of course, is invalid. Any suggestions would be appreciated!
Upvotes: 2
Views: 2364
Reputation: 117337
simplest way to do it is (if your name could not contain ,
):
declare @list nvarchar(max) = ',value1,value2,value3,'
select count(*)
from test
where xml_col.exist('//Field[contains(sql:variable("@list"), concat(",", @name, ","))]') = 1;
or SQL way:
select count(*)
from test
where
exists
(
select 1 from xml_col.nodes('//Field') as T(C)
where T.C.value('@name', 'nvarchar(max)') in ('value1', 'value2', 'value3')
)
Upvotes: 3
Reputation: 5120
You may try following construct:
select count(1)
from [table] t
where exists (
select 1 from (values ('value1'),('value2'),('value3')) l(v)
where t.xml_col.exist('//Field[@name=sql:column("l.v")]') = 1);
Also it can be used with table variable or table valued parameter in the following way:
declare @list table (value varchar(100))
insert into @list values ('value1'),('value2'),('value3')
or
create type ListOfValues as table (value varchar(100))
GO
declare @list ListOfValues
insert into @list values ('value1'),('value2'),('value3')
and then
select count(1)
from [table] t
where exists(select 1 from @list l
where t.xml_col.exist('//Field[@name=sql:column("l.value")]') = 1);
Upvotes: 1
Reputation: 13315
Maybe in this case it would be easier to check on the SQL side:
SELECT COUNT(*)
FROM table
WHERE xml_col.value('(//Field/@name)[1]', 'nvarchar(255)') in ('value1', 'value2', 'value3')
At least this would work if there is only one Field
element in your XML, otherwise it would get a bit more complex.
Upvotes: 1