4

FOR XML PATHSQL Server 2008R2 のテーブルから XML を構築するために使用しています。XML は次のように構築する必要があります。

<Root>
    <OuterElement>
        <NumberNode>1</NumberNode>
        <FormattedNumberNode>0001</KFormattedNumberNode>
        <InnerContainerElement>
            <InnerNodeOne>0240</InnerNodeOne>
            <InnerNodeStartDate>201201</InnerNodeStartDate>
        </InnerContainerElement>
    </OuterElement>
</Root>

スキーマ ファイルによると、InnerContainerElementはオプションですが、InnerNodeOneは必須です。スキーマ ファイルは私が設定したものではなく、非常に複雑で、相互に参照し、明示的な XSD 名前空間を持たないため、データベースに簡単にロードできません。

XML は、次のクエリを使用して入力されたテーブルから作成する必要があります。

SELECT
    1 AS NumberNode
    , '0001' AS [FormattedNumberNode]
    , '0240' AS [InnerNodeOne]
    , '201201' AS [InnerNodeStartDate]
INTO #temporaryXMLStore
UNION
SELECT
    2 AS NumberNode
    , '0001' AS [FormattedNumberNode]
    , NULL AS [InnerNodeOne]
    , NULL AS [InnerNodeStartDate]

を使用してこの XML を構築するには、2 つの方法が考えられますFOR XML PATH

1) XML サブクエリからの名前付き結果として「InnerContainerElement」を使用する:

SELECT
    NumberNode
    , [FormattedNumberNode]
    , (
        SELECT
            [InnerNodeOne]
            , [InnerNodeStartDate]
        FOR XML PATH(''), TYPE
    ) AS [InnerContainerElement]
FROM #temporaryXMLStore
FOR XML PATH('OuterElement'), ROOT('Root') TYPE

2) XML サブクエリからの出力要素として「InnerContainerElement」を使用しますが、名前を付けません。

SELECT
    NumberNode
    , [FormattedNumberNode]
    , (
        SELECT
            [InnerNodeOne]
            , [InnerNodeStartDate]
        FOR XML PATH('InnerContainerElement'), TYPE
    )
FROM #temporaryXMLStore
FOR XML PATH('OuterElement'), ROOT('Root'), TYPE

ただし、いずれも望ましい結果をもたらしません。どちらの場合も、結果は次のようになります。

<Root>
  <OuterElement>
    <NumberNode>1</NumberNode>
    <FormattedNumberNode>0001</FormattedNumberNode>
    <InnerContainerElement>
      <InnerNodeOne>0240</InnerNodeOne>
      <InnerNodeStartDate>201201</InnerNodeStartDate>
    </InnerContainerElement>
  </OuterElement>
  <OuterElement>
    <NumberNode>2</NumberNode>
    <FormattedNumberNode>0001</FormattedNumberNode>
    <InnerContainerElement></InnerContainerElement>
    <!-- Or, when using the second codeblock: <InnerContainerElement /> -->
  </OuterElement>
</Root>

が空の場合は常にInnerContainerElement、空の要素として表示されます。スキーマによると、これは無効です。要素InnerContainerElementが XML にInnerNodeOneある場合は常に、これも必要です。

空の場合は常に が除外されるFOR XML PATHようにクエリを作成するにはどうすればよいですか?InnerContainerElement

4

1 に答える 1

6

InnerContainerElementコンテンツがない場合に備えて、行がゼロであることを確認する必要があります。

select T.NumberNode,
       T.FormattedNumberNode,
       (
         select T.InnerNodeOne,
                T.InnerNodeStartDate
         where T.InnerNodeOne is not null or
               T.InnerNodeStartDate is not null
         for xml path('InnerContainerElement'), type
       )
from #temporaryXMLStore as T
for xml path('OuterElement'), root('Root')

InnerContainerElementまたは、要素を列エイリアスの一部として指定することもできます。

select T.NumberNode,
       T.FormattedNumberNode,
       T.InnerNodeOne as 'InnerContainerElement/InnerNodeOne',
       T.InnerNodeStartDate as 'InnerContainerElement/InnerNodeStartDate'
from #temporaryXMLStore as T
for xml path('OuterElement'), root('Root')
于 2012-11-20T10:20:32.410 に答える