2013-04-01 110 views
0

最近我遇到了通过T-SQL脚本(在SQL Server 2008 R2中)解析XML文件的问题。如何根据属性值解析SQL Server中的XML节点

任务是检索特定日期的数据(指标)。我设法检索所有日期的数据。

但我需要使用select声明表示它像

|Date | Indicator_name | Indicator_value| 

稍后,我将在游标中使用此选择来根据从XML检索的数据更新多个表。

你能帮助SQL和Xpath使用正确的输出吗?

我的代码:

declare @in as xml; --original document with indicators 
--test data for xml 
set @in=' 
<root> 
<org name="org1"/> 
    <dates> 
    <date id="7/1/2009"> 
    <indicator1 name="110_ii">0</indicator1> 
    <indicator1 name="1120_ii">0</indicator1> 
    <indicator1 name="1121_ii">0</indicator1> 
    <indicator1 name="1122_ii">0</indicator1> 
    <indicator1 name="120_ii">4388176</indicator1> 
    <indicator1 name="135_ii">0</indicator1> 
    <indicator1 name="140_ii">866212</indicator1> 
    <indicator1 name="145_ii">0</indicator1> 
    <indicator1 name="150_ii">860428</indicator1> 
    <indicator1 name="190_ii">6114816</indicator1> 
    <indicator1 name="210_ii">286254</indicator1> 
    <indicator1 name="220_ii">110173</indicator1> 
    <indicator1 name="240_ii">707265</indicator1> 
    <indicator1 name="250_ii">30115</indicator1> 
    <indicator1 name="260_ii">378524</indicator1> 
    <indicator1 name="270_ii">119324</indicator1> 
    <indicator1 name="290_ii">1631655</indicator1> 
    <indicator1 name="300_ii">7746471</indicator1> 
    <indicator1 name="410_ii">325194</indicator1> 
    <indicator1 name="411_ii">655</indicator1> 
    <indicator1 name="1340_ii">0</indicator1> 
    <indicator1 name="420_ii">251639</indicator1> 
    <indicator1 name="430_ii">0</indicator1> 
    <indicator1 name="470_ii">4601840</indicator1> 
    <indicator1 name="490_ii">5178018</indicator1> 
    <indicator1 name="510_ii">1204181</indicator1> 
    <indicator1 name="515_ii">285692</indicator1> 
    <indicator1 name="1430_ii">0</indicator1> 
    <indicator1 name="520_ii">113460</indicator1> 
    <indicator1 name="590_ii">1603333</indicator1> 
    <indicator1 name="610_ii">508631</indicator1> 
    <indicator1 name="620_ii">456489</indicator1> 
    <indicator1 name="640_ii">0</indicator1> 
    <indicator1 name="650_ii">0</indicator1> 
    <indicator1 name="660_ii">0</indicator1> 
    <indicator1 name="690_ii">965120</indicator1> 
    <indicator1 name="700_ii">7746471</indicator1> 
    <indicator1 name="910_ii">245294</indicator1> 
    <indicator1 name="911_ii">165164</indicator1> 
    <indicator1 name="920_ii">194742</indicator1> 
    <indicator1 name="930_ii">0</indicator1> 
    <indicator1 name="940_ii">524989</indicator1> 
    <indicator1 name="950_ii">0</indicator1> 
    <indicator1 name="960_ii">3647627</indicator1> 
    <indicator1 name="970_ii">5377</indicator1> 
    <indicator1 name="980_ii">0</indicator1> 
    <indicator1 name="990_ii">0</indicator1> 
    <indicator2 name="f2_010">1639698</indicator2> 
    <indicator2 name="f2_020">1207761</indicator2> 
    <indicator2 name="nacenka">0</indicator2> 
    <indicator2 name="f2_021">0</indicator2> 
    <indicator2 name="f2_022">106342</indicator2> 
    <indicator2 name="f2_023">0</indicator2> 
    <indicator2 name="f2_024">0</indicator2> 
    <indicator2 name="f2_025">0</indicator2> 
    <indicator2 name="f2_029">431937</indicator2> 
    <indicator2 name="f2_030">0</indicator2> 
    <indicator2 name="f2_040">0</indicator2> 
    <indicator2 name="f2_050">431937</indicator2> 
    <indicator2 name="f2_080">15790</indicator2> 
    <indicator2 name="f2_060">15798</indicator2> 
    <indicator2 name="f2_070">36105</indicator2> 
    <indicator2 name="f2_090">0</indicator2> 
    <indicator2 name="f2_100">39647</indicator2> 
    <indicator2 name="f2_140">387773</indicator2> 
    <indicator2 name="f2_150">88393</indicator2> 
    <indicator2 name="f2_2421">0</indicator2> 
    <indicator2 name="f2_142">0</indicator2> 
    <indicator2 name="f2_141">6380</indicator2> 
    <indicator2 name="f2_151">0</indicator2> 
    <indicator2 name="f2_190">305760</indicator2> 
    <indicator2 name="f2_2510">0</indicator2> 
    <indicator2 name="f2_2520">0</indicator2> 
    <indicator2 name="f2_2500">0</indicator2> 
    <indicator2 name="f2_202">0</indicator2> 
    <indicator2 name="f2_2910">0</indicator2> 
    </date> 
    <date id="8/1/2009"> 
    <indicator1 name="110_ii">0</indicator1> 
    <indicator1 name="1120_ii">0</indicator1>  
    </date> 
    </dates> 
</root>' 

--here I have the select that just returns all indicators name and values on all dates. 
--I guess that XPath is needed in where section smth like node(//date[@balans_date])='8/1/2009' 

select 
    coalesce(t.c.value('(@name)[1]', 'varchar(max)'),'0') as indicator_name 
    ,coalesce(t.c.value('(.)[1]', 'decimal(28,4)'),0) as indicator_value 
from @in.nodes('/root/dates/date/*') t(c) 

回答

1

您可以使用下面的表达式中的XPath按日期套用筛选:

select 
    coalesce(t.c.value('(../@id)[1]', 'datetime'), 0) as indicator_date, 
    coalesce(t.c.value('(@name)[1]', 'varchar(max)'),'0') as indicator_name, 
    coalesce(t.c.value('(.)[1]', 'decimal(28,4)'),0) as indicator_value 
from @in.nodes('/root/dates/date[@id="8/1/2009"]/*') t(c) 
+0

是的,这工作。 是否有可能不过滤但输出XML结构如 ** date | indicator_name | indicator_value ** 或者可能需要从XML创建一个日期数组(在这个例子中有2个日期,但可以是很多),然后按日期循环检索数据?如何创建一个数组并向其添加值从 'select(tcvalue('(。)','nvarchar(255)'))from @ in.nodes('/ root/dates/date/@ id ')t(c)' – user2232196

+0

我编辑了我的答案,包含父节点的日期 – Alexander

+1

非常感谢!我改变了一下,以便按照我想要的方式进行检索。 final version declare @in as xml; - 带指示器的原始文档 - xml的测试数据 'select coalesce(tcvalue('(../@id)[1]','datetime'),0)as indicator_date, coalesce(tc value('(@ name)[1]','varchar(max)'),'0')as indicator_name, coalesce(tcvalue('(。)[1]','decimal(28,4)') ),0)作为来自@ in.nodes('/ root/dates/date/*')的指标值 t(c)' – user2232196