0

これはおそらく単純で、中かっこが正しくありませんが、SQL SERVER XMLデータのクエリの経験がほとんどないため、非常識になっています。

XMLタイプの列NoSqlFieldを持つ単純なテーブルがあります。これには、NULLまたは

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

NoSqlField列に<entrykey= "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'

さまざまなバリエーション(スラッシュありとなし、フルパスなど)がありますが、返される行は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属性が 1 つだけの要素: 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 に答える