Как показывают решения Alan, одним из способов является чтение всего набора и использование внешнего WHERE
для фильтрации этого. Это работает и может быть лучшим подходом. Но с большими XML-файлами .exist()
намного быстрее, потому что уничтожение прекращается после первого попадания.
В качестве альтернативы вы можете попробовать это:
Кредиты Алану Бурштейну для MCVE
-- Sample data
DECLARE @users TABLE (userId INT IDENTITY, meta XML)
INSERT @users(meta) VALUES
('<users><user key="location" value="000" /></users>'),
('<users><user key="location" value="123" /></users>'),
('<users><user key="location" value="456" /></users>'),
('<users><user key="location" value="789" /></users>'),
('<users><user key="location" value="999" /></users>');
- Я обрамляю список номеров запятыми
DECLARE @SearchFor VARCHAR(100)=',123,456,789,';
- Простой contains()
ищет ,123,
найдет строку
SELECT *
FROM @users
WHERE meta.exist('/users/user[@key="location" and contains(sql:variable("@SearchFor"),concat(",",@value,","))]')=1;
Мы можемиспользуйте sql:variable()
, чтобы ввести внешнюю переменную в XQuery. (Вы можете сделать то же самое с "location" , конечно ...)
Если ваш список чисел взят из таблицы, вы можете попробовать что-то вроде этого:
DECLARE @SearchFor TABLE(LookUpNumber INT);
INSERT INTO @SearchFor VALUES(123),(456),(789);
SELECT *
FROM @users
CROSS APPLY(SELECT CONCAT((SELECT CONCAT(',',LookUpNumber) FROM @SearchFor FOR XML PATH('')),',')) A(SearchFor)
WHERE meta.exist('/users/user[@key="location" and contains(sql:column("SearchFor"),concat(",",@value,","))]')=1;
APPLY
создаст объединенный список значений на лету и передаст его в XML с помощью sql:column()
.