Я не знаю, является ли это самым простым подходом, но вы можете попытаться включить свой список в XML и использовать его в предикате, как здесь:
- A таблица макетов, чтобы показать принципы
DECLARE @tbl TABLE(TheXml XML)
INSERT INTO @tbl VALUES
(
N'<root>
<a>1</a>
<a>2</a>
</root>'
)
,(
N'<root>
<a>1</a>
</root>'
)
,(
N'<root>
<a>3</a>
<a>4</a>
</root>'
);
- Это легко: просто одно значение
SELECT * FROM @tbl WHERE TheXml.exist('/root/a[. cast as xs:int?=1]')=1;
- Это ваша последовательность .
- Но вы не можете ввести список значений с помощью sql:column()
или sql:variable()
.
SELECT * FROM @tbl WHERE TheXml.exist('/root/a[. cast as xs:int?=(2,3)]')=1;
- Но вы можете добавить значения в свой XML до , как в этом cte
DECLARE @values TABLE(val INT);
INSERT INTO @values VALUES(2),(3);
WITH cte(NewXml) AS
(
SELECT (SELECT (SELECT val AS [@val] FROM @values FOR XML PATH('values'),TYPE)
,TheXml AS [*]
FOR XML PATH(''),TYPE
)
FROM @tbl t
)
SELECT NewXml.query('/root') TheXml
FROM cte
WHERE NewXml.exist('/root/a[. cast as xs:int?=/values/@val]')=1;
Промежуточный XML выглядит следующим образом:
<values val="2" />
<values val="3" />
<root>
<a>1</a>
<a>2</a>
</root>
Финальный .query('/root')
вернет предыдущий XML без изменений.
UPDATE
То же самое будет работать с введением на основе строк, как здесь:
WITH cte(NewXml) AS
(
SELECT (SELECT CAST(N'<values val="2" /><values val="3" />' AS XML)
,TheXml AS [*]
FOR XML PATH(''),TYPE
)
FROM @tbl t
)
SELECT NewXml.query('/root') TheXml
FROM cte
WHERE NewXml.exist('/root/a[. cast as xs:int?=/values/@val]')=1