2

以下のようなxmlを生成するテーブルをクエリする方法を理解しようとしています:(これはAdventureWorksデータベースからのサンプルです。

要素として列名を取得するのは簡単ですが、属性として列名と値の両方を作成することは可能ですか?これを一般的な方法で行う方法を理解しようとしているので、FOREXPLICITを使用して列名をハードコーディングしたくありません

    <TABLE name="StateProvince">
        <ROW>
            <COL name="StateProvinceID" value="1" />
            <COL name="StateProvinceCode" value="AB" />
            <COL name="CountryRegionCode" value="CA" />
            <COL name="IsOnlyStateProvinceFlag" value="0" />
            <COL name="Name" value="Alberta" />
            <COL name="TerritoryID" value="6" />
            <COL name="rowguid" value="298C2880-AB1C-4982-A5AD-A36EB4BA0D34" />
            <COL name="ModifiedDate" value="2004-03-11T10:17:21.587" />
        </ROW>
    </TABLE>
4

2 に答える 2

4

列名を指定せずにこれを行うのは少し注意が必要ですが、実行可能です。
これを使用するには、テーブル名に置き換え@T、テーブル名定数'StateProvince'をテーブル名に変更する必要があります。

declare @T table
(
  StateProvinceID int,
  StateProvinceCode char(2),
  CountryRegionCode char(2),
  IsOnlyStateProvinceFlag int,
  Name varchar(50),
  TerritoryID int,
  rowguid uniqueidentifier,
  ModifiedDate datetime
)

insert into @T values
(1, 'AB', 'CA', 0, 'Alberta', 6, '298C2880-AB1C-4982-A5AD-A36EB4BA0D34', '2004-03-11T10:17:21.587'),
(2, 'AB', 'CA', 0, 'Alberta', 6, '298C2880-AB1C-4982-A5AD-A36EB4BA0D34', '2004-03-11T10:17:21.587')

select 'StateProvince' as [@name],
  (
    select 
      (
        select T3.N.value('local-name(.)', 'sysname') as [@name],
               T3.N.value('.', 'nvarchar(max)') as [@value]
        from (
               select T1.*
               for xml path(''), type
             ) T2(N)
          cross apply T2.N.nodes('*') as T3(N)       
        for xml path('COL'), root('ROW'), type
      )         
    from @T as T1
    for xml path(''), type
  )
for xml path('TABLE')  

結果:

<TABLE name="StateProvince">
  <ROW>
    <COL name="StateProvinceID" value="1" />
    <COL name="StateProvinceCode" value="AB" />
    <COL name="CountryRegionCode" value="CA" />
    <COL name="IsOnlyStateProvinceFlag" value="0" />
    <COL name="Name" value="Alberta" />
    <COL name="TerritoryID" value="6" />
    <COL name="rowguid" value="298C2880-AB1C-4982-A5AD-A36EB4BA0D34" />
    <COL name="ModifiedDate" value="2004-03-11T10:17:21.587" />
  </ROW>
  <ROW>
    <COL name="StateProvinceID" value="2" />
    <COL name="StateProvinceCode" value="AB" />
    <COL name="CountryRegionCode" value="CA" />
    <COL name="IsOnlyStateProvinceFlag" value="0" />
    <COL name="Name" value="Alberta" />
    <COL name="TerritoryID" value="6" />
    <COL name="rowguid" value="298C2880-AB1C-4982-A5AD-A36EB4BA0D34" />
    <COL name="ModifiedDate" value="2004-03-11T10:17:21.587" />
  </ROW>
</TABLE>

注:テーブルの列名は、有効なXML要素名である必要があります。たとえば、列名にスペースを含めることはできません。

于 2012-03-03T17:57:37.743 に答える
1

SQL Server の機能だけを使用して、探しているものを 100% 達成できるとは思いません。近づくことはできますが、100% にはなりません。

ここでのクエリでは、FOR XML PATHSQL Server 2005 以降で使用可能な構造を使用しています。

SELECT 
    [StateProvinceID] AS 'COL/@StateProvinceID',
    '',
    [StateProvinceCode] AS 'COL/@StateProvinceCode',
    '',
    [CountryRegionCode] AS 'COL/@CountryRegionCode',
    '',
    [IsOnlyStateProvinceFlag] AS 'COL/@IsOnlyStateProvinceFlag',
    '',
    [Name] AS 'COL/@Name',
    '',
    [TerritoryID] AS 'COL/@TerritoryID',
    '',
    [rowguid] AS 'COL/@rowguid',
    '',
    [ModifiedDate] AS 'COL/@ModifiedDate'
  FROM [Person].[StateProvince]
  FOR XML PATH('ROW'), ROOT('TABLE')

次のような XML になります。

<TABLE>
  <ROW>
    <COL StateProvinceID="1" />
    <COL StateProvinceCode="AB " />
    <COL CountryRegionCode="CA" />
    <COL IsOnlyStateProvinceFlag="0" />
    <COL Name="Alberta" />
    <COL TerritoryID="6" />
    <COL rowguid="298C2880-AB1C-4982-A5AD-A36EB4BA0D34" />
    <COL ModifiedDate="2008-03-11T10:17:21.587" />
  </ROW>
  <ROW>
    <COL StateProvinceID="2" />
    <COL StateProvinceCode="AK " />
    <COL CountryRegionCode="US" />
    <COL IsOnlyStateProvinceFlag="0" />
    <COL Name="Alaska" />
    <COL TerritoryID="1" />
    <COL rowguid="5B7B8462-A888-4E0B-A3E1-7278F8AF107E" />
    <COL ModifiedDate="2008-03-11T10:17:21.587" />
  </ROW>
  ..........
</TABLE>

<COL .... />次のように、すべての列の値が単一の要素に固執するのを避けるために、各属性の間で「空の」列を選択する必要があります。

    <COL StateProvinceID="2"  
         StateProvinceCode="AK "  
         CountryRegionCode="US"    
         IsOnlyStateProvinceFlag="0"  
         Name="Alaska"  
         TerritoryID="1" 
         rowguid="5B7B8462-A888-4E0B-A3E1-7278F8AF107E"  
         ModifiedDate="2008-03-11T10:17:21.587" />
于 2012-03-03T09:05:49.597 に答える