powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / XML в Oracle9i. Примеры разборки
25 сообщений из 239, страница 6 из 10
XML в Oracle9i. Примеры разборки
    #35325531
Zloxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
SQL> select ExtractValue(value(t),'z:row@DateFrom','xmlns:z="#RowsetSchema"')
   2   from
   3      Table(XmlSequence(Extract(XMLtype(
   4   '<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
  5      xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
  6      xmlns:rs="urn:schemas-microsoft-com:rowset"
  7      xmlns:z="#RowsetSchema">
  8  <s:Schema id="RowsetSchema">
  9      <s:ElementType name="row" content="eltOnly">
 10          <s:AttributeType name="DateFrom" rs:number="1" rs:nullable="true" rs:writeunknown="true">
 11              <s:datatype dt:type="dateTime" rs:dbtype="timestamp" dt:maxLength="16" rs:scale="0" rs:precision="19" rs:fixedlength="true"/>
 12          </s:AttributeType>
 13          <s:AttributeType name="DateTo" rs:number="2" rs:nullable="true" rs:writeunknown="true">
 14              <s:datatype dt:type="dateTime" rs:dbtype="timestamp" dt:maxLength="16" rs:scale="0" rs:precision="19" rs:fixedlength="true"/>
 15          </s:AttributeType>
 16          <s:extends type="rs:rowbase"/>
 17      </s:ElementType>
 18  </s:Schema>
 19  <rs:data>
 20      <z:row DateFrom="2007-08-01T00:00:00" DateTo="2007-08-31T00:00:00"/>
 21      <z:row DateFrom="2007-09-01T00:00:00" DateTo="2007-09-10T00:00:00"/>
 22  </rs:data>
 23  </xml>'),'xml/rs:data/z:row','xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema"')))t
  24   ;
 
EXTRACTVALUE(VALUE(T),'Z:ROW@D
--------------------------------------------------------------------------------
 2007 - 08 -01T00: 00 : 00 
 2007 - 09 -01T00: 00 : 00 
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35325626
Фотография Ales Protiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
например так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
with t as (
select xmltype(
'<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
    xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
    xmlns:rs="urn:schemas-microsoft-com:rowset"
    xmlns:z="#RowsetSchema">
<s:Schema id="RowsetSchema">
    <s:ElementType name="row" content="eltOnly">
        <s:AttributeType name="DateFrom" rs:number="1" rs:nullable="true" rs:writeunknown="true">
            <s:datatype dt:type="dateTime" rs:dbtype="timestamp" dt:maxLength="16" rs:scale="0" rs:precision="19" rs:fixedlength="true"/>
        </s:AttributeType>
        <s:AttributeType name="DateTo" rs:number="2" rs:nullable="true" rs:writeunknown="true">
            <s:datatype dt:type="dateTime" rs:dbtype="timestamp" dt:maxLength="16" rs:scale="0" rs:precision="19" rs:fixedlength="true"/>
        </s:AttributeType>
        <s:extends type="rs:rowbase"/>
    </s:ElementType>
</s:Schema>
<rs:data>
    <z:row DateFrom="2007-08-01T00:00:00" DateTo="2007-08-31T00:00:00"/>
    <z:row DateFrom="2007-09-01T00:00:00" DateTo="2007-09-10T00:00:00"/>
</rs:data>
</xml>') x from dual)

select extract(column_value, '//@DateFrom').getstringval() d from t,
  table(xmlsequence(extract(x,'//row', 'xmlns="#RowsetSchema"')))
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35325654
avp78
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо всем!!! отлично работают оба варианта!! :)
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35443131
help_xml
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подскажите, плиз, что не так делаю.
Надо вывести в одну строчку все значения показателей.
Выводит пустые значения:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
select 
  v.xv.Extract('//KPI_by_day//KPI[name="KPI1"]/@value').getStringVal() kpi1,
  v.xv.Extract('//KPI_by_day//KPI[name="KPI2"]/@value').getStringVal() kpi2,
  v.xv.Extract('//KPI_by_day//KPI[name="KPI3"]/@value').getStringVal() kpi3
from 
(
    select 
    xmltype(
            '<?xml version="1.0" encoding="windows-1251" ?>
            <KPI_by_day>
            <KPI name="KPI1" value="100.56" />
            <KPI name="KPI2" value="10.4" />
            <KPI name="KPI3" value="3" />
            </KPI_by_day>'
            )  xv
from dual
) v;
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35443138
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
help_xml wrote:

> Подскажите, плиз, что не так делаю.


Условие "KPI[name" везде заменить на "KPI[@name".
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35443142
help_xml
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Denis Popov
help_xml wrote:

> Подскажите, плиз, что не так делаю.


Условие "KPI[name" везде заменить на "KPI[@name".
Posted via ActualForum NNTP Server 1.4

Спасибо!, работает :)
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35649770
Фотография barrabas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
получают от soap ответ от сбербанка
пока стоит задача научится его екстрактить на части, но этот подлец тут же ругается, на первом же элементе - extract('soap:Envelope').

оракулORA-31011: XML parsing failed ORA-19202: Error occurred in XML processing LPX-00601: Invalid token in: 'soap:Envelope' ORA-06512: at "SYS.XMLTYPE", line 111

без extract преобразование к xmltype проходит. Что ему еще от меня нужно ???

сокращенный xml

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
select *
from table(XMLSequence(xmltype(
'<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      
      <soap:Body>
          <GetCursOnDateResponse xmlns="http://web.cbr.ru/">
              <GetCursOnDateResult>
                 <xs:schema id="ValuteData" xmlns="" 
                     xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                     xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" 
                     xmlns:msprop="urn:schemas-microsoft-com:xml-msprop">
                       
                        <xs:element name="ValuteData" msdata:IsDataSet="true" 
                            msdata:UseCurrentLocale="true" msprop:OnDate="20071230">
                            
                             <xs:complexType><xs:choice minOccurs="0" maxOccurs="unbounded">
                                <xs:element name="ValuteCursOnDate">
                                   <xs:complexType>
                                      <xs:sequence>
                                         <xs:element name="Vname" type="xs:string" minOccurs="0" />
                                         <xs:element name="Vnom" type="xs:decimal" minOccurs="0" />
                                         <xs:element name="Vcurs" type="xs:decimal" minOccurs="0" />
                                         <xs:element name="Vcode" type="xs:int" minOccurs="0" />
                                         <xs:element name="VchCode" type="xs:string" minOccurs="0" />
                                      </xs:sequence>
                                    </xs:complexType>
                                </xs:element>
                                </xs:choice>
                             </xs:complexType>
                         </xs:element>
                  </xs:schema>
                  
                  
                   <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" 
                           xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
                  
                           <ValuteData xmlns="">
                              <ValuteCursOnDate diffgr:id="ValuteCursOnDate1" msdata:rowOrder="0">
                                 <Vname>Австралийский доллар</Vname>
                                 <Vnom>1</Vnom>
                                 <Vcurs>21.5246</Vcurs>
                                 <Vcode>36</Vcode>
                                 <VchCode>AUD</VchCode>
                              </ValuteCursOnDate>
                              
                              <ValuteCursOnDate diffgr:id="ValuteCursOnDate2" msdata:rowOrder="1">
                                 <Vname>Фунт стерлингов Соединенного королевства</Vname>
                                 <Vnom>1</Vnom>
                                 <Vcurs>49.0114</Vcurs>
                                 <Vcode>826</Vcode>
                                 <VchCode>GBP</VchCode>
                               </ValuteCursOnDate>
                           </ValuteData>
                              
                   </diffgr:diffgram>
              </GetCursOnDateResult>
          </GetCursOnDateResponse>
     </soap:Body>
 </soap:Envelope>'
 ).extract('soap:Envelope')))
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35649820
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
barrabasЧто ему еще от меня нужно ???namespace
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
select *
from table(XMLSequence(xmltype(
'<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <soap:Body>...
     </soap:Body>
 </soap:Envelope>'
 ).extract('//Body', 'xmlns="http://www.w3.org/2003/05/soap-envelope"')))
;

COLUMN_VALUE
--------------------------------------------------------------------
<soap:Body xmlns:soap="http://www.w3.org/2003/05/soap-envelope">...
     </soap:Body>
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35650010
Фотография barrabas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic,

супер, спасибо
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35650505
Sergei.Agalakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут Timm давал ссылку на SQL/XML how-to для 10g.
Погонял те же тесты на 11g - SQL/XML стал в несколько раз быстрее и обгоняет DBMS_GEN.
В 11g теперь стоит Java 1.5 с JIT компилятором. Неужели настолько лучше стало, или просто SQL/XML на С переписали?
Завтра, если не забуду, надо трейсы снять. Если это Java так ускорилась, то есть повод и другие пакеты потестировать.
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35651048
Фотография barrabas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как достать значение атрибута OnDate из
примера

я у него другой нейспейс
пробую так


Код: plaintext
1.
2.
3.
4.
5.
select extractValue(COLUMN_VALUE,'/@OnDate', 'xmlns="urn:schemas-microsoft-com:xml-msprop"') CUR_DATE
from table(XMLSequence(xmltype( 
testSoapclob(sysdate)
 ).extract('//element[@name="ValuteData"]','xmlns="http://www.w3.org/2001/XMLSchema"')
 ))
результат null
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35651289
Фотография barrabas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
для простоты восприятия
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
select extractValue(COLUMN_VALUE,'/@OnDate', 'xmlns="urn:schemas-microsoft-com:xml-msprop"') CUR_DATE
 from 
table(XMLSequence(xmltype( 
  '<xs:element xmlns:xs="http://www.w3.org/2001/XMLSchema" 
               name="ValuteData" 
               xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" 
               msdata:IsDataSet="true" 
               msdata:UseCurrentLocale="true" 
               xmlns:msprop="urn:schemas-microsoft-com:xml-msprop" 
               msprop:OnDate="20081031">
     <xs:complexType>
       <xs:choice minOccurs="0" maxOccurs="unbounded">
         <xs:element name="ValuteCursOnDate">
           <xs:complexType>
             <xs:sequence>
               <xs:element name="Vname" type="xs:string" minOccurs="0"/>
               <xs:element name="Vnom" type="xs:decimal" minOccurs="0"/>
               <xs:element name="Vcurs" type="xs:decimal" minOccurs="0"/>
               <xs:element name="Vcode" type="xs:int" minOccurs="0"/>
               <xs:element name="VchCode" type="xs:string" minOccurs="0"/>
             </xs:sequence>
           </xs:complexType>
         </xs:element>
       </xs:choice>
     </xs:complexType>
   </xs:element>'
).extract('//element[@name="ValuteData"]','xmlns="http://www.w3.org/2001/XMLSchema"')
 ))   
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35651568
Zloxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
 extractValue(COLUMN_VALUE,'element/@x:OnDate', 'xmlns="http://www.w3.org/2001/XMLSchema" xmlns:x="urn:schemas-microsoft-com:xml-msprop"') CUR_DAT
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35651617
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zloxa
Код: plaintext
1.
 extractValue(COLUMN_VALUE,'element/@x:OnDate', 'xmlns="http://www.w3.org/2001/XMLSchema" xmlns:x="urn:schemas-microsoft-com:xml-msprop"') CUR_DAT
Спасибо!
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35760474
BinaryBoy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пытаюсь распарсить XML документ:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
--select value(t) as XMLBody
select extract(value(t), 'ListNar/nz/text()', 'xmlns="http://tempuri.org"').getStringVal()   OrderNumber
from table(XMLSequence(xmltype(
 '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xmlns:s="http://www.w3.org/2001/XMLSchema">
      <SOAP-ENV:Body>
          <ListNarResponse xmlns="http://tempuri.org">
               <ListNarResult xsi:type="s01:ListNarResult" xmlns:s01="http://tempuri.org">
                   <list>                      
                        <ListNar xsi:type="s02:ListNar" xmlns:s02="http://tempuri.org">
                          <nz xsi:type="s:long">101</nz>
                          <abon xsi:type="s:string">РЫЖИХ ИВАН ЕРЕМЕЕВИЧ</abon>
                          <ndog xsi:type="s:string">2009101</ndog>
                          <tl xsi:type="s:string">8124444101</tl>
                          <prim xsi:type="s:string">ЧЕРЕЗ ТУЭС 13.01</prim>
                        </ListNar>
                  </list>
              </ListNarResult>  
          </ListNarResponse>
      </SOAP-ENV:Body>
  </SOAP-ENV:Envelope>').extract('//ListNarResponse/ListNarResult/list/ListNar', 'xmlns="http://tempuri.org"'))) t;

Oracle ругается:

ORA-31011: сбой разбора XML
ORA-19202: Возникла ошибка при обработке XML
LPX-00234: namespace prefix "xsi" is not declared
Error at line 1


Как правильно передать в это выражение нужный namespace?
extract(value(t), 'ListNar/nz/text()', 'xmlns="http://tempuri.org"').getStringVal()
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35760841
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BinaryBoyLPX-00234: namespace prefix "xsi" is not declared
Как правильно передать в это выражение нужный namespace? Всё правильно. Но На 9-ке не работает, потому что где-то теряются namespace-ы
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35760897
Zloxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Elicгде-то
ТУТ

Код: plaintext
Connected to Oracle9i Enterprise Edition Release  9 . 2 . 0 . 8 . 0  \n \nSQL> \nSQL> select extract(value(t), \'ListNar/nz/text()\', \'xmlns="http://tempuri.org"\').getStringVal()   OrderNumber\n   2   from table(XMLSequence(extract(xmltype(\n   3    \'<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"\n  4                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n  5                       xmlns:s="http://www.w3.org/2001/XMLSchema">\n  6        <SOAP-ENV:Body>\n  7            <ListNarResponse xmlns="http://tempuri.org">\n  8                 <ListNarResult xsi:type="s01:ListNarResult" xmlns:s01="http://tempuri.org">\n  9                     <list>\n 10                          <ListNar xsi:type="s02:ListNar" xmlns:s02="http://tempuri.org">\n 11                            <nz xsi:type="s:long">101</nz>\n 12                            <abon xsi:type="s:string">РЫЖИХ ИВАН ЕРЕМЕЕВИЧ</abon>\n 13                            <ndog xsi:type="s:string">2009101</ndog>\n 14                            <tl xsi:type="s:string">8124444101</tl>\n 15                            <prim xsi:type="s:string">ЧЕРЕЗ ТУЭС 13.01</prim>\n 16                          </ListNar>\n 17                    </list>\n 18                </ListNarResult>\n 19            </ListNarResponse>\n 20        </SOAP-ENV:Body>\n 21    </SOAP-ENV:Envelope>\'),\'//ListNarResponse/ListNarResult/list/ListNar\', \'xmlns="http://tempuri.org"\'))) t;\n \nORDERNUMBER\n--------------------------------------------------------------------------------\n 101 \n 
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35760911
BinaryBoy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ElicBinaryBoyLPX-00234: namespace prefix "xsi" is not declared
Как правильно передать в это выражение нужный namespace? Всё правильно. Но На 9-ке не работает, потому что где-то теряются namespace-ы

У меня 9.2.0.7
Вообще никак эту ситуацию не обойти?
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35761361
BinaryBoy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Elic - спасибо!

Zloxa - мегареспект! Действительно, не очевидня фича!
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35843186
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет!
Заранее извиняюсь что вклиниваюсь со своими проблемами... Но думаю что не стоит отдельную тему заводить.

Имеется следующая задача: Принять с клиента XML следующей структуры (схема может быть изменена, если это поможет делу, т.к. генерация XML под нашим контролем). Грубо говоря, это некоторые "измерения" и соответствующие каждому измерению "значения параметров".
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
<Root>
 <M w="12345" t="2008.12.27 23:59:00">
  <V v="8513" p="1"/>
  <V v="5548" p="2"/>
  <V v="9087" p="3"/>
 </M>
 <M w="12345" t="2008.12.27 23:59:01">
  <V v="7686" p="1"/>
  <V v="5577" p="2"/>
 </M>
</Root>

И соответсвенно раскидать по 2 табличкам master-detail
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
CREATE TABLE m
(
 ID NUMBER( 20 ) NOT NULL,
 w  NUMBER( 20 ) NOT NULL,
 t  DATE       NOT NULL
);

ALTER TABLE m
 ADD CONSTRAINT xpkm
  PRIMARY KEY (ID);

ALTER TABLE m
 ADD CONSTRAINT xak1m
  UNIQUE (w, t);

CREATE SEQUENCE seq_m;

CREATE OR REPLACE TRIGGER tbi_m
   BEFORE INSERT
   ON m
   FOR EACH ROW
BEGIN
   IF :NEW.ID IS NULL
   THEN
      SELECT seq_m.NEXTVAL
        INTO :NEW.ID
        FROM DUAL;
   END IF;
END;
/

CREATE TABLE v
(
  m_id NUMBER( 20 ) NOT NULL,
  p    NUMBER( 20 ) NOT NULL,
  v    NUMBER( 10 ) NOT NULL
);

ALTER TABLE v
 ADD CONSTRAINT xpkv
  PRIMARY KEY (m_id, p);

ALTER TABLE v
 ADD CONSTRAINT r1v
  FOREIGN KEY (m_id) REFERENCES m (ID)
    ON DELETE CASCADE;

Имеются достаточно жёсткие требования по скорости работы, и объёму передаваемой информации. Передаваться будет ориентировочно 15 подобных XML пакетов в минуту (хотелось бы чтобы система работала в режиме 24/7), каждый пакет - это 60 измерений (т.е. на каждую секунду) и вплоть до 200 параметров на каждое измерение (итого 1 пакет это до 12000 новых записей, но "типично" надеюсь будет раза в 2-3 меньше). Допускаются повторные передачи (для простоты считаем что без удаления ранее принятых данных - т.е. используя MERGE).
Сейчас нарисована следующая ХП (по сути черновик, хотя и выполняет свои задачи) для приёма пакетов:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
CREATE OR REPLACE PROCEDURE load_temporal_parameters (p_xml IN CLOB)
IS
   v_new_id   NUMBER ( 20 );
BEGIN
   FOR rec_m IN
      (SELECT m.EXTRACT ('/M/@w').getnumberval () w,
              TO_DATE (m.EXTRACT ('/M/@t').getstringval (),
                       'YYYY.MM.DD HH24:MI:SS'
                      ) t,
              m.EXTRACT ('/M') params
         FROM DUAL,
              TABLE (XMLSEQUENCE (XMLTYPE (p_xml).EXTRACT ('/Root/M'))) m)
   LOOP
      BEGIN
         SELECT ID
           INTO v_new_id
           FROM m
          WHERE w = rec_m.w AND t = rec_m.t;
      EXCEPTION
         WHEN NO_DATA_FOUND
         THEN
            SELECT seq_m.NEXTVAL
              INTO v_new_id
              FROM DUAL;

            INSERT INTO m
                        (ID, w, t
                        )
                 VALUES (v_new_id, rec_m.w, rec_m.t
                        );
      END;

      FOR rec_v IN (SELECT v.EXTRACT ('/V/@p').getnumberval () p,
                           v.EXTRACT ('/V/@v').getnumberval () v
                      FROM DUAL,
                           TABLE (XMLSEQUENCE (rec_m.params.EXTRACT ('/M/V'))) v)
      LOOP
         MERGE INTO v
            USING (SELECT v_new_id m_id, rec_v.p p, rec_v.v v
                     FROM DUAL) nv
            ON (v.m_id = nv.m_id AND v.p = nv.p)
            WHEN MATCHED THEN
               UPDATE
                  SET v.v = nv.v
            WHEN NOT MATCHED THEN
               INSERT (m_id, p, v)
               VALUES (nv.m_id, nv.p, nv.v);
      END LOOP;
   END LOOP;
END;
/

К сожалению, по скорости работы это явно не лучшее решение. Пока пакеты небольшие, это ещё приемлемо, но вот обработка 100-200Кб-ного пакета занимает уже до 20 секунд :(

Хочется совета, как быть... Может быть переписать парсинг средствами dbms_xmldom? Даст ли это реальный выигрыш по скорости обработки? Или может быть можно как-то оптимизировать приведенный код? Избежать внутреннего цикла (я так понимаю, он для каждого "куска" повторно выполняет парсинг и строит новый DOM) - всё-же 60 "лишних" обращений на пакет... Но увы я не представляю как можно от этого уйти :(

Написать процедуру на Java (используя SAX) заманчиво, но скорее всего неосуществимо :(

Целевой сервер будет не ниже 10-го, но лучше всего, если решение будет совместимо с 9-м, т.к. девелоперский сервер будет 9i (9.2.0.8). Клиентом - пока будет VB6 прога (через старый добрый ADO - спасибо форуму, нашёл как побороть лимит передачи параметра в 32К ;) ), в перспективе может быть и C# (ADO.NET) и даже какое-то сугубо оракловское решение (HTTP).

WBR, Igor
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35843319
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Igor Korolyov wrote at 27.02.2009 18:26:

> Имеется следующая задача: Принять с клиента XML следующей структуры
> (схема может быть изменена, если это поможет делу, т.к. генерация XML
> под нашим контролем).

....

> Имеются достаточно жёсткие требования по скорости работы, и объёму

....

> Целевой сервер будет не ниже 10-го, но лучше всего, если решение будет
> совместимо с 9-м, т.к. девелоперский сервер будет 9i (9.2.0.8).


Может сделать одну промежуточную таблицу и модифицировать XML так, чтобы он мог обработаться
пакетами DBMS_XMLSAVE и DBMS_XMLSTORE? Второй появился в Oracle 10g и по-моему через них будет
быстрее, чем через XmlType.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35844008
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут есть пара моментов
1) Оно до сих пор и работало через 2 промежуточные "рабочие" таблицы и пару процедур - там помимо погрузки ещё и вопросы обработки решались - минимаксы считались (по всему массиву конечно же считать минимакс это убийственно, вот оно и считалось по погружаемой порции, и сливалось с ранее запомненными данными), потом ещё и "интервалы непрерывности" считались (типа чтоб "дырки" по времени видеть - когда нет "измерений").
И всё это хозяйство, даже при не пиковой нагрузке генерировало до 45Мб редо-лога в минуту (чёрт его знает, там и сложность этой обработки, и кривость написанных процедур - всё понемногу влияло). Т.к. инстансы работали в режиме архивирования логов, то очень быстро пришлось такую систему вырубить :)
2) Я думал насчёт представления с инстед-оф триггером, чтоб он распихивал поступающие данные по 2-м таблицам. Это по идее сходно со схемой "плоской" рабочей таблицы...
Но, как я сейчас себе представляю логику работы такого триггера, то получается что для каждой записи (идущей в итоге в детэйл-таблицу) придётся делать поиск в мастер-таблице по альтернативному ключу (w+t) - а это боюсь будет очень неэффективно. Сейчас такой поиск проводится только 1 раз для всех "значений параметров" - которых, как я говорил, будет до 200 на "измерение"...
DBMS_XMLSAVE и тем паче DBMS_XMLSTORE конечно было бы заманчиво прикрутить (даже схему XML-я бы под них поменяли, чтобы не парится с трансформациями или "тонкой" настройкой пакета), но, как я понимаю, они оба не в состоянии работать с иерархиями :(

А в приведенной процедуре ничего нельзя подправить? Чтобы избежать для второго цикла запроса - т.е. как-то по иному rec_m.params прокручивать... Или тут не происходит повторного разбора XML-я?
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35844792
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Igor KorolyovА в приведенной процедуре ничего нельзя подправить? Чтобы избежать для второго цикла запроса - т.е. как-то по иному rec_m.params прокручивать... Или тут не происходит повторного разбора XML-я?

Может тогда разбирать XML единожды до "плоского" вида и вставлять данные в обе таблицы, вроде такого:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
declare v_id M.id%type;
begin
  for i in (
    with x as (
      select '
    <Root>
     <M w="12345" t="2008.12.27 23:59:00">
      <V v="8513" p="1"/>
      <V v="5548" p="2"/>
      <V v="9087" p="3"/>
     </M>
     <M w="12345" t="2008.12.27 23:59:01">
      <V v="7686" p="1"/>
      <V v="5577" p="2"/>
     </M>
    </Root>' xml
      from DUAL
    )
    select xml.w xml_w
         , xml.t xml_t
         , xml.p xml_p
         , xml.v xml_v
         , v.v   v_v
    from (select extract(value(m), '/M/@w').getNumberVal() w
               , to_date(extract(value(m), '/M/@t').getStringVal(), 'yyyy.mm.dd hh24:mi:ss') t
               , extract(value(v), '/V/@p').getNumberVal() p
               , extract(value(v), '/V/@v').getNumberVal() v
          from x x
             , table (XmlSequence (XmlType (x.xml).extract('/Root/M'))) m
             , table (XmlSequence (extract(value(m), '/M/V'))) v
         ) xml
       , (select M.w
               , M.t
               , V.p
               , V.v
          from M
             , V
          where V.m_id = M.id
         ) v
    where  1 = 1 
      and v.w (+) = xml.w
      and v.t (+) = xml.t
      and v.p (+) = xml.p
  ) loop
    begin
      select M.id into v_id from M where M.w = i.xml_w and M.t = i.xml_t;
    exception when NO_DATA_FOUND then
      insert into M (id, w, t) values (SEQ_M.nextval, i.xml_w, i.xml_t)
      return id into v_id;
    end;

    if i.v_v is null then
      insert into V (m_id, p, v) values (v_id, i.xml_p, i.xml_v);
    elsif i.xml_v != i.v_v then
      update V set V.v = i.xml_v where V.m_id = v_id and V.p = i.xml_p;
    end if;
  end loop;
end;
/
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35844795
VBR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
VBR
Гость
Попробуйте разбор через xmldom, может добавит скорости:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
DECLARE
  l_doc      xmltype;
  l_nlist    DBMS_XMLDOM.DOMNodeList;  
  l_nlist_v  DBMS_XMLDOM.DOMNodeList; 
  l_node     DBMS_XMLDOM.DOMNode;          
  l_temp_n    DBMS_XMLDOM.DOMNode;    
  l_node_v     DBMS_XMLDOM.DOMNode;   
  l_nattrs DBMS_XMLDOM.DOMNamedNodeMap; 
  l_attr VARCHAR2( 2000 );              
  
 BEGIN
   
   l_doc := XMLType('<Root>
  <M w="12345" t="2008.12.27 23:59:00">
  <V v="8513" p="1">7</V>
  <V v="5548" p="2"/>
  <V v="9087" p="3"/>
 </M>
 <M w="12345" t="2008.12.27 23:59:01">
  <V v="7686" p="1"/>
  <V v="5577" p="2"/>
 </M>
 </Root>');  
              
--  for i in 0..1000 loop 
  l_nlist := DBMS_XMLDOM.getchildnodes(dbms_xmldom.getNodeFromFragment(l_doc.extract('//M')));

   FOR i IN  0 ..DBMS_XMLDOM.getLength(l_nlist)- 1  LOOP           
          l_node := DBMS_XMLDOM.item(l_nlist,i);            
			    l_nattrs := DBMS_XMLDOM.GetAttributes(l_node);         
          FOR i IN  0 ..DBMS_XMLDOM.GetLength(l_nattrs)- 1  LOOP
             l_temp_n    := DBMS_XMLDOM.item(l_nattrs,i);
             l_attr  := DBMS_XMLDOM.GetNodeValue(l_temp_n);
--             dbms_output.put_line(l_attr);									 
          END LOOP;         
        	 l_nlist_v := DBMS_XMLDOM.getchildnodes(l_node);
       
	FOR j IN  0 ..DBMS_XMLDOM.getLength(l_nlist_v)- 1  LOOP			    
             l_node_v := DBMS_XMLDOM.item(l_nlist_v,j);					
	l_nattrs := DBMS_XMLDOM.GetAttributes(l_node_v);         
             FOR i IN  0 ..DBMS_XMLDOM.GetLength(l_nattrs)- 1  LOOP
               l_temp_n   := DBMS_XMLDOM.item(l_nattrs,i);
               l_attr  := DBMS_XMLDOM.GetNodeValue(l_temp_n);
--               dbms_output.put_line(l_attr);									 
            END LOOP;  
      END LOOP;         
                   
   END LOOP;           
--end loop;	 
 
END; 
...
Рейтинг: 0 / 0
XML в Oracle9i. Примеры разборки
    #35847043
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем, на текущий момент получилось следующее (на домашнем Oracle 10g XE при подаче тестового XML-я из CLOB поля таблички):
-Моя изначальная процедура исполняется около 20 секунд.
-Вариант с плоской таблицей, по наброску Дениса - 1 минуту 5 секунд.
-Вариант с DBMS_XMLDOM (приведенный ниже) - около 3 секунд. При этом если закомментировать собственно INSERT и MERGE (т.е. по сути оставить только парсинг) - то исполняется примерно за 600 мсек, что на данный момент меня более чем устраивает.
-Если будет время, попробую вариант с DBMS_XMLSTORE + view "распихивающий" данные по 2-м таблицам. Но боюсь что на реальной базе это будет неприемлемо медленно из-за огромного количества вспомогательных запросов на "наличие записи", даже учитывая что каждый такой запрос идёт по уникальному индексу... Всё-же 60 запросов куда как приятнее нежели 12000 :)

В общем промежуточный лидер забега - DBMS_XMLDOM :) Хотя я думаю что SAX парсер на Java был бы не медленнее (увы, нет возможности проверить это).

И конечно небольшое разочарование - на нашем кривом девелоперском сервере (давно уже надо всё переставлять, а то "недопатченный" 9.2.0.7 с некогда хранящимися в SYSTEM пользовательскими данными, переживший к тому-же пару серьёзных сбоев ОС - это та ещё "радость") вариант с DBMS_XMLDOM не работает вовсе - пресловутая ORA-06502: PL/SQL: numeric or value error: raw variable length too long

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
CREATE OR REPLACE PROCEDURE load_temporal_parameters3 (p_xml IN CLOB)
IS
   v_doc            DBMS_XMLDOM.domdocument;
   v_list_m         DBMS_XMLDOM.domnodelist;
   v_element_m      DBMS_XMLDOM.domelement;
   v_wellbore_id    m.w%TYPE;
   v_time           m.t%TYPE;
   v_new_id         m.ID%TYPE;
   v_list_v         DBMS_XMLDOM.domnodelist;
   v_element_v      DBMS_XMLDOM.domelement;
   v_parameter_id   v.p%TYPE;
   v_value          v.v%TYPE;
BEGIN
   v_doc := DBMS_XMLDOM.newdomdocument (p_xml);
   v_list_m := DBMS_XMLDOM.getelementsbytagname (v_doc, 'M');

   FOR i IN  0  .. DBMS_XMLDOM.getlength (v_list_m) -  1 
   LOOP
      v_element_m := DBMS_XMLDOM.makeelement (DBMS_XMLDOM.item (v_list_m, i));
      v_wellbore_id :=
                      TO_NUMBER (DBMS_XMLDOM.getattribute (v_element_m, 'w'));
      v_time :=
         TO_DATE (DBMS_XMLDOM.getattribute (v_element_m, 't'),
                  'YYYY.MM.DD HH24:MI:SS'
                 );

      BEGIN
         SELECT ID
           INTO v_new_id
           FROM m
          WHERE w = v_wellbore_id AND t = v_time;
      EXCEPTION
         WHEN NO_DATA_FOUND
         THEN
            SELECT seq_m.NEXTVAL
              INTO v_new_id
              FROM DUAL;

            INSERT INTO m
                        (ID, w, t
                        )
                 VALUES (v_new_id, v_wellbore_id, v_time
                        );
      END;

      v_list_v := DBMS_XMLDOM.getchildrenbytagname (v_element_m, 'V');

      FOR j IN  0  .. DBMS_XMLDOM.getlength (v_list_v) -  1 
      LOOP
         v_element_v :=
                     DBMS_XMLDOM.makeelement (DBMS_XMLDOM.item (v_list_v, j));
         v_parameter_id :=
                      TO_NUMBER (DBMS_XMLDOM.getattribute (v_element_v, 'p'));
         v_value := TO_NUMBER (DBMS_XMLDOM.getattribute (v_element_v, 'v'));
         MERGE INTO v
            USING (SELECT v_new_id m_id, v_parameter_id p, v_value v
                     FROM DUAL) nv
            ON (v.m_id = nv.m_id AND v.p = nv.p)
            WHEN MATCHED THEN
               UPDATE
                  SET v.v = nv.v
            WHEN NOT MATCHED THEN
               INSERT (m_id, p, v)
               VALUES (nv.m_id, nv.p, nv.v);
      END LOOP;
   END LOOP;

   DBMS_XMLDOM.freedocument (v_doc);
END;
/

Попутно возник ещё один вопрос - процедура за запуск (на чистой базе) генерирует 6.5Мб редо лога, если сразу после этого выполнить (в блоке BEGIN ... END) Два INSERT ... SELECT эффективно "удваивающих" данные (ну, конечно, со смещениями дабы не нарушать уникальных констрейнов) - то эта операция генерирует всего лишь 1.5 Мб лога - что может быть причиной подобного отличия? Порядок следования операций вставки? "чередующийся" в одном случае и "сплошной" в другом? Тот факт что первая операция исполняется на пустых таблицах а вторая на уже заполненных? Или какие-то особенности вычисления статистики TOAD-ом, о которых я не знаю?

WBR, Igor
...
Рейтинг: 0 / 0
25 сообщений из 239, страница 6 из 10
Форумы / Oracle [игнор отключен] [закрыт для гостей] / XML в Oracle9i. Примеры разборки
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]