0

这可能很简单,我只是没有正确使用大括号,但由于我几乎没有查询 SQL SERVER XML 数据的经验,这让我发疯了。

我有一个带有 XML 类型列NoSqlField的简单表。这包含 NULL 或

<root version="1.0">
  <entry key="mykey">1</entry>
</root>

我想要表中所有在其NoSqlField列中具有 <entry key="mykey">1</entry> 值的行。

一个(相当愚蠢,因为它使用 .ToString())LINQ 查询使用

where h.NoSqlField.ToString().IndexOf("<entry key=\"mykey\">1</entry>") > -1

返回一个结果,所以它肯定存在。

如何在 T-SQL 中运行相同的查询?我试过了

SELECT * FROM mytable WHERE 
NoSqlField.value('(//entry[@key=mykey])[1]','varchar(1)') = '1'

在各种变体中(有和没有斜杠,完整路径,...),但从未得到一个返回的行。

4

1 回答 1

1

解决方案 1: 如果要检查NoSqlField列是否有//root/entry元素并且该元素包含1(内部文本),则可以使用此解决方案:

SET ANSI_WARNINGS ON;
GO

DECLARE @TestData TABLE (
    ID INT IDENTITY PRIMARY KEY,
    NoSqlField XML NULL
);

INSERT  @TestData  (NoSqlField)
SELECT  NULL 
UNION ALL
SELECT  '
<root version="1.0">
  <entry key="mykey">1</entry>
</root>'
UNION ALL
SELECT  '
<root version="1.0">
  <entry key="mykey" anotherkey="myanotherkey">1</entry>
</root>'
UNION ALL
SELECT  '
<root version="1.0">
  <entry key="anotherkey" key2="a">1</entry>
</root>'
UNION ALL
SELECT  '
<root version="1.0">
  <entry key="mykey" key3="3">22</entry>
</root>';

SELECT  * 
FROM    @TestData t
WHERE   t.NoSqlField.exist('//root/entry[@key="mykey"][text() = "1"]') = 1

结果:

ID NoSqlField
-- ---------------------------------------------------------------------------------
2  <root version="1.0"><entry key="mykey">1</entry></root>
3  <root version="1.0"><entry key="mykey" anotherkey="myanotherkey">1</entry></root>

注1:您可以看到此解决方案允许(存在)其他属性(例如anotherkey)。

解决方案 2: 如果你想要一个严格的过滤器(entry只有一个属性的元素:),key那么你可以使用这个查询:

SELECT  *
FROM
(
        SELECT  * 
                ,t.NoSqlField.exist('//root/entry[@key="mykey"][text() = 1]') AS XmlExist
                ,t.NoSqlField.query('
                    let $list := //root/entry/@*
                    for $i in $list
                    where local-name($i) != "key"
                        return <ret value="1"/>
                ').exist('//ret') AS HasAnotherAttribute
        FROM    @TestData t
) src
WHERE   src.XmlExist = 1
AND     src.HasAnotherAttribute = 0

结果:

ID NoSqlField                                              XmlExist HasAnotherAttribute
-- ------------------------------------------------------- -------- -------------------
2  <root version="1.0"><entry key="mykey">1</entry></root> 1        0

注意 2:将构建一个包含元素let $list := //root/entry/@*的所有 (@*) 属性的列表。//root/entry

注 3:本地名称()

于 2012-06-14T15:05:43.903 回答