簡體   English   中英

SQL中來自OpenXML的動態列和記錄

[英]Dynamic columns and records from openxml in sql

我有一個相當簡單的xml文檔。 唯一的區別是元素可以更改。 有一次我可能有:

<data><PersonalInfo>
<Person><FirstName>Bob</FirstName><LastName>Smith</LastName></Person>
<Person><FirstName>John</FirstName><LastName>Doe</LastName></Person>
</PersonalInfo></data>

下次我可能會:

<data><AddressInfo>
<Address><City>Cleveland</City><State>OH</State></Address>
<Address><City>Chicago</City><State>IL</State></Address>
</AddressInfo></data>

我想寫一條選擇語句,該語句根據當前獲取的xml文檔生成一個動態表。

例如:對於第一個:

First Name     Last Name
------------------------
Bob             Smith
John            Doe
Etc...

對於第二個

City       State
-----------------------
Cleveland   OH
Chicago     IL
Etc...

這兩個例子沒有任何關系(鮑勃不是克里夫蘭人,等等。)

我只想使用相同的代碼來生成兩個表...取決於xml文檔。 當然,唯一的區別是節點引用:

Example 1:  data/PersonalInfo/Person*
Example 2:  data/AddressInfo/Address*

我不想合並或更改xml doc結構中的任何內容。 它們就是它們要傳入的東西。我如何引用每個表來創建上面的兩個不同的表-傳入的每個xml文檔將位於單獨的運行存儲過程中。 但這將是相同的存儲過程。 非常感謝您的協助,在此先感謝您!

像這樣嘗試:

CREATE PROCEDURE dbo.TransformPlainXML(@InputXml XML)
AS
BEGIN

DECLARE @PivotColumns NVARCHAR(MAX);

WITH DistinctElementNames AS
(
    SELECT DISTINCT '[' + Element.value('fn:local-name(.)','varchar(max)') + ']' AS ElementName
    FROM @InputXml.nodes('/data/*/*/*') As One(Element)
)
SELECT @PivotColumns = STUFF(
(
    SELECT ',' + ElementName
    FROM DistinctElementNames
    FOR XML PATH('')
),1,1,'');

DECLARE @cmd NVARCHAR(MAX)=
'WITH Lines AS
(
    SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowIndex
          ,Line.query(''.'') AS OneLine
    FROM @xml.nodes(''/data/*/*'') As One(Line)
)
SELECT p.*
FROM
(
    SELECT RowIndex
          ,Element.value(''.[1]'',''varchar(max)'') AS ElementValue
          ,Element.value(''fn:local-name(.)'',''varchar(max)'') AS ElementName
    FROM Lines
    CROSS APPLY OneLine.nodes(''./*/*'') AS The(Element)
) AS tbl
PIVOT
(
    MIN(ElementValue) FOR ElementName IN(' + @PivotColumns + ')
) AS p
';

EXECUTE sp_executesql @cmd,N'@xml XML',@xml=@InputXml;
END
GO

像這樣測試

declare @xml1 XML=
'<data>
  <PersonalInfo>
    <Person>
      <FirstName>Bob</FirstName>
      <LastName>Smith</LastName>
    </Person>
    <Person>
      <FirstName>John</FirstName>
      <LastName>Doe</LastName>
    </Person>
  </PersonalInfo>
</data>';


EXEC TransformPlainXML @xml1;

declare @xml2 XML=
'<data>
  <AddressInfo>
    <Address>
      <City>Cleveland</City>
      <State>OH</State>
    </Address>
    <Address>
      <City>Chicago</City>
      <State>IL</State>
    </Address>
  </AddressInfo>
</data>';
EXEC TransformPlainXML @xml2;

兩個結果:

RowIndex    FirstName   LastName
1           Bob         Smith
2           John        Doe

RowIndex    City        State
1           Cleveland   OH
2           Chicago     IL

您可以創建一個列映射表,該表存儲任何數量的“映射模板” ...(由於缺少更好的描述)

這樣您的新表將具有以下值:

TYPE        ORDER            COLUMNNAME
Person      1                FirstName
Person      2                LastName
Address     1                City
Address     2                State

然后,您可以使用該表加載實際的xml節點名稱,並使用循環從XML收集值。

這可行嗎? 您是否有權使用SQL制作和讀取此表?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM