2014-10-06 118 views
3

我很相當新,在SQL Server中FOR XML,我搜索了相當多,我找不到答案。對於XML SQL Server - 輸出XML中的變量元素名稱

我可以使用'for xml',其中元素名稱不是硬編碼的,而是取自每行中的單元格?看看下面的例子...

ORDERS

ID  STATUS  TIME  AMOUNT 
------------------------------------ 
1  COMPLETE  02:31  2355 
2  ACCEPTED  02:39  6653 
3  ACCEPTED  04:21  4102 
4  RECEIVED  05:03  4225 

FOR XML查詢:

select ID, 
     TIME as STATUS_TIME, 
     AMOUNT as CURRENT_AMOUNT 
from ORDERS 
for xml raw(' **STATUS NAME HERE** '),root('ORDERS'), elements 

需要的輸出:

<ORDERS> 
    <COMPLETE>    <<<<--- Variable element name from STATUS in ORDERS 
     <ID>1</ID> 
     <STATUS_TIME>02:31</STATUS_TIME> 
     <CURRENT_AMOUNT>2355</CURRENT_AMOUNT> 
    </COMPLETE> 
    <ACCEPTED>    <<<<--- Variable element name from STATUS in ORDERS 
     <ID>2</ID> 
     <STATUS_TIME>02:39</STATUS_TIME> 
     <CURRENT_AMOUNT>6653</CURRENT_AMOUNT> 
    </ACCEPTED> 
    <ACCEPTED>    <<<<--- Variable element name from STATUS in ORDERS 
     <ID>3</ID> 
     <STATUS_TIME>04:21</STATUS_TIME> 
     <CURRENT_AMOUNT>4102</CURRENT_AMOUNT> 
    </ACCEPTED> 
    <RECEIVED>    <<<<--- Variable element name from STATUS in ORDERS 
     <ID>4</ID> 
     <STATUS_TIME>05:03</STATUS_TIME> 
     <CURRENT_AMOUNT>4225</CURRENT_AMOUNT> 
    </RECEIVED> 
</ORDERS> 

我知道我能給予的屬性到元素名稱,我可以給個人ORDERORDERSSTATUS像下面屬性,但不幸的是,這不是什麼將接收XML文檔的人都在找:(

select ID, 
     STATUS as '@STATUS' 
     TIME as STATUS_TIME, 
     AMOUNT as CURRENT_AMOUNT 
from ORDERS 
for xml raw('ORDER'),root('ORDERS'), elements 

輸出:

<ORDERS> 
    <ORDER STATUS='COMPLETE'>    <<<<--- Attribute for STATUS but not what I want 
     <ID>1</ID> 
     <STATUS_TIME>02:31</STATUS_TIME> 
     <CURRENT_AMOUNT>2355</CURRENT_AMOUNT> 
    </ORDER> 
    <ORDER STATUS='ACCEPTED'>    <<<<--- Attribute for STATUS but not what I want 
     <ID>2</ID> 
     <STATUS_TIME>02:39</STATUS_TIME> 
     <CURRENT_AMOUNT>6653</CURRENT_AMOUNT> 
    </ORDER> 
.... 

我希望能夠儘可能在SQL Server中完成所有這些。 許多非常感謝,如果你能在這方面幫助我。

+0

檢查答案... – 2014-10-06 12:43:00

回答

1

您不能在XML Raw()中指定列值。所以,你必須做的是從選擇查詢和鑄造結果所需的列到XML,這樣的 -

模式

DECLARE @temp table (ID int, [STATUS] [varchar](100) NOT NULL, [TIME] [varchar](100), AMOUNT int); 

INSERT @temp (ID, [STATUS], [TIME], AMOUNT) VALUES (1, 'COMPLETE', '02:31', 2355),(2, 'ACCEPTED', '02:41', 6653),(3, 'ACCEPTED', '02:31', 4102),(4, 'ACCEPTED', '02:31', 4225) 

查詢

SELECT 
CAST('<' + STATUS + '>' + 
    '<ID>' + CAST(ID AS varchar) + '</ID>' + 
    '<TIME>' + TIME + '</TIME>' + 
    '<AMOUNT>' + CAST(AMOUNT AS varchar) + '</AMOUNT>' + 
'</' + STATUS + '>' AS XML) from @temp 
FOR XML PATH(''),root('ORDERS') 

輸出

<ORDERS> 
    <COMPLETE> 
    <ID>1</ID> 
    <TIME>02:31</TIME> 
    <AMOUNT>2355</AMOUNT> 
    </COMPLETE> 
    <ACCEPTED> 
    <ID>2</ID> 
    <TIME>02:41</TIME> 
    <AMOUNT>6653</AMOUNT> 
    </ACCEPTED> 
    <ACCEPTED> 
    <ID>3</ID> 
    <TIME>02:31</TIME> 
    <AMOUNT>4102</AMOUNT> 
    </ACCEPTED> 
    <ACCEPTED> 
    <ID>4</ID> 
    <TIME>02:31</TIME> 
    <AMOUNT>4225</AMOUNT> 
    </ACCEPTED> 
</ORDERS> 
1

在SQL Server中,XML模式必須是靜態的,所以不可能指定可變元素名稱(無論是文檔還是屬性)。

如果爲STATUS領域可能的選擇是有限的,穩定的,那麼你可以說他們都明確,就像下面的例子:

select (
    select t.ID, t.TIME as [STATUS_TIME], t.AMOUNT as [CURRENT_AMOUNT] 
    from @temp t 
    where t.STATUS = 'ACCEPTED' 
    for xml path('ACCEPTED'), type, elements 
    ), (
    select t.ID, t.TIME as [STATUS_TIME], t.AMOUNT as [CURRENT_AMOUNT] 
    from @temp t 
    where t.STATUS = 'COMPLETE' 
    for xml path('COMPLETE'), type, elements 
    ) 
for xml path('ORDERS'), type; 

我想你已經注意到了這個代碼是如何背叛無數的可能性你,但坦率地說,這種方法是唯一不包含字符串操作的可用方法(如果XML輸出的大小至少爲幾Mb,它們將對性能造成不利影響)。

作爲一種可能的解決方法,您可以動態生成此查詢,包括儘可能多的節,因爲您的表中存在明顯的STATUS值。非常醜,但它會起作用。