1

次のようにテーブルを作成しています。

CREATE TABLE dbo.Test
(
  A int,
  B int
)

GO

INSERT INTO Test VALUES (1, 11)
GO

INSERT INTO Test VALUES (5, 55)
GO

INSERT INTO Test VALUES (4, 44)
GO

これを次のように XML に変換するクエリがあります。

  SELECT A,B
  FROM Test
  ORDER BY A
  FOR XML AUTO, ROOT ('myroot'), ELEMENTS

次の結果を得るには、上記のクエリをサブクエリとして使用する必要があります。

A           B
1           11
4           44
5           55

私はこのようなクエリを試みていますが、エラーが発生します:

SELECT Z.Value('@A', 'INT'),
   Z.Value('@B', 'INT')
FROM (SELECT A, B
  FROM Test
  ORDER BY A
  FOR XML AUTO,Elements, ROOT ('myroot')) Doc(Z)

メッセージ 4121、レベル 16、状態 1、行 1 列 "Z"、ユーザー定義関数または集計 "Z.Value" が見つからないか、> の名前があいまいです。

以下のような単純なクエリを記述して結果を取得できますが、要件は、それを XMl に変換してから、サブクエリを使用して同じ結果を取得することです。 Select * from test order by A

For XML によって返されたレコードをテーブル変数に挿入し、クロス適用を使用して結果を取得できることはわかっていますが、上記のように、一時テーブルや一時変数を使用せずに単一のクエリでこれを実行しようとしています。

4

2 に答える 2

1

ここにはいくつかの問題があります。まず、xml は次のようになります。

<myroot>
    <Test>
         <A>1</A><B>11</B>
    </Test>
    <Test>
         <A>4</A><B>44</B>
    </Test>
    <Test>
         <A>5</A><B>55</B>
    </Test>
</myroot>

@Aそして、データを属性 ( 、 )として取得しようとしています@BA[1]要素 (または)としてフェッチする必要があります(A/text())[1]

次に、xml タイプにしtypeたい場合は、キーワードを使用する必要があります。xml第 3 に、行ごとにデータを分割するには、関数が必要nodes()です。したがって、クエリは次のようになります。

select
   D.Z.value('(A/text())[1]', 'int'),
   D.Z.value('(B/text())[1]', 'int')
from (
   select A, B
   from Test
   order by A
   for xml auto, elements, root('myroot'), type
) as Doc(Z)
    outer apply Doc.Z.nodes('myroot/Test') as D(Z)

ところで、次のように属性を使用することをお勧めします。

select
   D.Z.value('@A', 'int'),
   D.Z.value('@B', 'int')
from (
   select A, B
   from Test
   order by A
   for xml raw('Test'), root('myroot'), type
) as Doc(Z)
    outer apply Doc.Z.nodes('myroot/Test') as D(Z)

sql fiddle demo

于 2013-10-05T08:40:54.070 に答える
0

モードを忘れたTYPE(それがないと xml ではなく nvarchar を取得する) ため、valueキーワードは小文字にする必要があります。

これを試して:

SELECT Z.Z.value('@A', 'INT'),
    Z.Z.value('@B', 'INT')
FROM (
    SELECT A, B
    FROM Test
    ORDER BY A
    FOR XML AUTO, ROOT ('myroot'), TYPE
) Doc(Doc)
CROSS APPLY Doc.nodes('/myroot/Test')Z(Z)

しかし、キーワードを使用してより宣言的な方法で、モードなしで XML を生成することをお勧めします ( の代わりにAUTO記述すると、クエリが壊れます)。dbo.TestTestPATH

SELECT Z.Z.value('@A', 'INT'),
    Z.Z.value('@B', 'INT')
FROM (
    SELECT A AS '@A', B AS '@B'
    FROM dbo.Test
    ORDER BY A
    FOR XML PATH('Test'), ROOT ('myroot'), TYPE
) Doc(Doc)
CROSS APPLY Doc.nodes('/myroot/Test')Z(Z)
于 2013-10-05T08:03:27.650 に答える