2013-04-01 1 views
0

Недавно я столкнулся с проблемой разбора XML-файла с помощью сценария T-SQL (в SQL Server 2008 R2).Как анализировать XML-узлы в SQL Server по значению атрибута

Задача состоит в том, чтобы получить данные (индикаторы) на определенную дату. Мне удалось получить данные во все даты.

Но мне нужно, чтобы представить его как

|Date | Indicator_name | Indicator_value| 

используя select заявление.

Позже я буду использовать этот выбор в курсоре для обновления нескольких таблиц на основе данных, полученных из 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 (в этом примере есть две даты, но может быть многие), а затем извлекать данные в цикле по датам? Как создать массив и добавить к нему значения из 'select (tcvalue ('(.)', 'Nvarchar (255)')) from @ in.nodes ('/ root/date/date/@ id ') t (c) ' – user2232196

+0

Я отредактировал свой ответ, чтобы включить дату с родительского узла – Alexander

+1

Большое спасибо! Я меняю его немного, чтобы он получал то, что я хотел. окончательная версия Объявление @in как xml; --original документ с индикаторами --test данные для XML 'выберите COALESCE (tcvalue ('(../@ ID) [1]', 'DateTime'), 0), как indicator_date, сливаются (дц значение ('(@ name) [1]', 'varchar (max)'), '0') в качестве имени_имя, coalesce (tcvalue ('(.) [1]', 'decimal (28,4)'), 0) в качестве индикатора_значения из @ in.nodes ('/ root/date/date/*') t (c) ' – user2232196