xml.exist - sql:要序列的列

问题描述 投票:0回答:1

我尝试使用sql:column-function创建一个使用xml.exist的查询,其中列的值应该转换为可用的XQuery序列。

这是具有静态序列的查询,这是有效的。

SELECT
    FieldA
    , FieldB
FROM
    MyTable
WHERE
    FieldC.exist('DSAuth/role[@id=("195", "267", "350")')

为了得到一个动态序列,我将使用一个表函数,返回一个带有“IDsequence”列的表,其中所有id都是一个字符串。例如'“195”,“267”,“350”'。

表函数应该只返回一行!有多行可行,但我必须将结果分组,这对性能有害。

SELECT
    FieldA
    , FieldB
FROM
    MyTable
CROSS APPLY
    dbo.MyFunc(0) AS f
WHERE
    FieldC.exist('DSAuth/role[@id=sql:column("f.IDsequence")]')

有没有办法从sql:column(“f.IDsequence”)获取XQuery的可用序列?

感谢帮助。

编辑:

性能问题是FieldB(以及更多字段)是一个xml列,所以我必须将其转换为group by。

SELECT
    FieldA
    , CAST(CAST(FieldB AS nvarchar(max)) AS xml) AS FieldB
FROM
    MyTable
CROSS APPLY
    dbo.MyFunc(0) AS f
WHERE
    FieldC.exist('DSAuth/role[@id=sql:column("f.IDsequence")]')
GROUP BY
    FieldA
    , CAST(FieldB AS nvarchar(max))
sql xml xquery sequence
1个回答
0
投票

我不知道这是否是最简单的方法,但您可能会尝试将列表包含在XML中并在谓词中使用它,如下所示:

- 一个显示原则的样机表

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;

- 但是你可以像在这个cte中那样将值添加到XML中

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
© www.soinside.com 2019 - 2024. All rights reserved.