如何将不同的XML字段值作为表中的行插入

时间:2014-10-31 14:03:53

标签: sql xml sql-server-2008

我有一个如下所述的xml,

 declare  @Message as xml

 set @Message='<message>

        <body>
        <ID>1</ID>
        <setup_time>10</setup_time>
        <prod_cycle_time>10</prod_cycle_time>
        <unit>cas</unit>
        <Flag>NULL</Flag>
        <FillingPO>NULL</FillingPO>
        <PackAtCAN1>NULL</PackAtCAN1>
        </body>
        </message>'

从上面的xml结构需要插入几个字段数据,如下所述格式

    ID     Desc              Value
     1      setup_time        10
     1      prod_cycle_time   10
     1      unit              Case
     1      Flag              NULL

2 个答案:

答案 0 :(得分:1)

您还可以使用XQuery首先转换XML:

declare @transform xml

set @transform = @message.query('
    let $capture := ("setup_time","prod_cycle_time","unit","Flag")

    for $item in /message/body/*
    let $id := $item/../ID
    where $capture = local-name($item)
    return <Row>
            <ID>{$id/text()}</ID>
            <Desc>{local-name($item)}</Desc>
            <Value>{$item/text()}</Value>
        </Row>
')

SELECT  x.value('ID[1]','int') AS ID,
        x.value('Desc[1]','varchar(max)') AS [Desc],
        x.value('Value[1]','varchar(max)') AS Value
FROM    @transform.nodes('/Row') tmp(x)

答案 1 :(得分:0)

看起来您希望从XML中获取值,然后执行取消操作。

使用value()函数从XML中提取值,您可以使用union all来进行unpivot。

declare  @Message as xml

set @Message='
<message>
  <body>
    <ID>1</ID>
    <setup_time>10</setup_time>
    <prod_cycle_time>10</prod_cycle_time>
    <unit>cas</unit>
    <Flag>NULL</Flag>
    <FillingPO>NULL</FillingPO>
    <PackAtCAN1>NULL</PackAtCAN1>
  </body>
</message>'

declare @ID int 
set @ID = @Message.value('(/message/body/ID/text())[1]', 'int') 

select @ID as ID, 
       'setup_time' as [Desc], 
       @Message.value('(/message/body/setup_time/text())[1]', 'nvarchar(50)') as Value 
union all
select @ID, 
       'prod_cycle_time', 
       @Message.value('(/message/body/prod_cycle_time/text())[1]', 'nvarchar(50)') 
union all
select @ID, 
       'unit', 
       @Message.value('(/message/body/unit/text())[1]', 'nvarchar(50)')  
union all
select @ID, 
       'Flag', 
       @Message.value('(/message/body/Flag/text())[1]', 'nvarchar(50)')