Találkozott már valaki azzal a problémával, hogy az XML kezelés egy idő után rettenetesen belassul? XML típusú tábláról van szó, 1 rekord 1 xml fájlként látszik a WebDav folderben. Szóval egy idő után rettentően lelassul, de ismét felgyorsul, ha a következőt megcsináljuk:
1. kimásolok minden xml fájlt a WebDav folderből egy lokális könyvtárba 2. törlöm az xml fájlokat az adatbázisból (WebDav folderből) 3. visszamásolom a fájlokat a WebDav folderbe
Sajnos az adott konkrét esetben a fájlok visszamásolása 44 óra hosszat tart, úgyhogy jó lenne valami szerencsésebb módszert találni vagy a lelassulás elkerülésére, vagy az ismételt felgyorsításra.
select cast(extractvalue( value( p ), '/row/@Id','xmlns="cardtype"') as varchar2(5)) Id, cast(extractvalue( value( p ), '/row/@code','xmlns="cardtype"') as varchar(5)) Code, cast(extractvalue( value( q ), '/adat','xmlns="cardtype"') as varchar(5)) adat from zzz x , table (xmlsequence(xmltype.extract(value(x), '/cardtype/data/row','xmlns="cardtype"'))) p ,table(xmlsequence(extract( value( p ), '/row/belso/adat','xmlns="cardtype"') )) q ;
Újabb problémába ütköztem. Bár meg is tudom kerülni a dolgot, leírom, hátha valaki találkozott már ilyennel, és tud rendes megoldást rá.
Pillanatnyilag a programunk sys_xmlgen-nel hozza létre a kimenő xml-t, és DBMS_XDB.createResource-szal tárolja le a WebDav folderbe, ahonnan egy idegen web service kiszedi, és használja a saját céljaira. Ez így szépen működik is.
Most annyi változás van, hogy a sémában szereplő base64Binary típusú (opcionális) elemeket is töltenem kell. Meglepődve tapasztaltam, hogy az Oracle ehhez a típushoz RAW, vagy BLOB típusú mezőt rendel, ami teljesen más, mint a base64Binyary, hiszen ezek csak a hexadecimális számok karaktereit (számokat és A-től F-ig betűket) tartalmazzák, míg a base64Binary típus az angol ábécé összes betűjét tartalmazhatja. Abban reménykedtem, hogy majd a sys_xmlgen visszakonvertálja ezeket a tartalmakat normális base64Binary-vá, de nem teszi.
A problémát úgy tudom például megkerülni, hogy nem az eredeti sémát regisztrálom, hanem a base64Binary típusokat lecserélem stringre, és ezzel dolgozom. De azért érdekelne, hogy a már foglalkoztak az Oracle-nél ezzel az adattípussal, akkor hogy képzelték a használatát. Ha valaki tudja, kérem árulja el nekem!
Hi Thomatos, welcome to Oracle XML! Látom, te is gyorsabban oldottad meg a problémádat, minthogy valaki segíthetet volna:-)
Most nekem van ismét újabb kérdésem. Nem akadok meg akkor sem, ha nem oldódik meg, de egy csomó dolog sokkal egyszerubb lenne, ha nemcsak user-objektumokat lehetne XML-lé konvertálni (az alább emlegetett sys_xmlgen-nel, vagy XMLTYPE.createXML-lel), hanem fordítva is menne valahogy, vagyis egy xmlből (vagy egy ágából) lehetne olyan user-objektumot létrehozni, amilyenből ő létrehozható.
Tehát például egy <Dolgozo> <Nev>Kiss Pista</Nev> <IdegenNyelv>angol</IdegenNyelv> <IdegenNyelv>orosz</IdegenNyelv> </Dolgozo>
stringből "Dolgozo_t" típusú objektumot .
Lehetséges ez valahogy szerintetek? (Persze úgy én is tudom, hogy szétextraktolom, aztán a darabkákból felépítem az objektumot. Valami közvetlen módszerre gondolok)
select sys_xmlgen( "Dolgozo_t"(NULL,'Kiss Pista',"Nyelvek_t"('angol','orosz')), xmlformat.createformat('Dolgozo','USE_GIVEN_SCHEMA','sample.xsd') ) from dual;
Csak épp a sokezer oldalas Oracle dokumentációban, és az egész interneten egyetlen példa sincs arra, hogy is kell ezt a createformat-ot paraméterezni. Azért, ha nehezen is, csak sikerült megfejtenem.
Nem tudja valaki véletlenül, hogy a "Dolgozo_t"-nek igazából mi kéne az első NULL paraméter helyett (csak azért írtam NULL-t mert valamit muszáj volt ideírni)?
A describe "Dolgozo_t"; kérdés így írja le a típust:
SYS_XDBPD$ XDB.XDB$RAW_LIST_T
Nev VARCHAR2(4000 CHAR)
IdegenNyelv Nyelvek_t
Szóval, mi a szösz ez a XDB.XDB$RAW_LIST_T típusú SYS_XDBPD$?
Mégpedig úgy, hogy ennek az xml-nek a struktúráját leíró xml schémát (xsd) regisztrálom, és a regisztráció során létrejövő típusokat használom. De sajnos egészen ilyet nem tudok, csak ilyet:
Hogy meg tudjam mutatni, miről van szó, direktben definiálom a típusokat, és az adatokat is direktben írom be. Tehát ezt így értem el:
Előkészítés:
drop type "Dolgozo_t" / drop type "Nyelvek_t" / create or replace type "Nyelvek_t" as varray(2147483647) of varchar(40); / create or replace type "Dolgozo_t" as OBJECT("Név" varchar2(40),"IdegenNyelv" "Nyelvek_t"); /
A lekérdezés:
select sys_xmlgen("Dolgozo_t"('Kiss Pista',"Nyelvek_t"('angol','orosz')),xmlformat.createformat('Dolgozó')) from dual;
Ez a lekérdezés tehát a második (piros) eredményt adja.
Van valakinek ötlete, hogy lehetne az első (zöld) struktúrájú eredményhez jutni (persze a definiált típusokat használva, vagyis anélkül, hogy leírnám a "Név" és az "IdegenNyelv" szavakat)?
Úgy tűnik, olyan vagyok, mint az egyszeri júzer. Elég, ha elpanaszkodhatom valakinek a bajom, és máris megvan a megoldás.
Az oracle-felhasználót még proxy felhasznélónak is fel kellett venni. Az Enterprise managerben meg lehet ezt tenni. Az SQL parancs, amit generált:
ALTER user GRANT CONNECT THROUGH
Sajnos megint segítségre szorulok. Megy minden szépen ebben az XML DB-ben, csak az FTP hozzáféréssel van bajom. Félek tőle, hogy ez igazából nem is Oracle probléma, hanem Windows. Az operációs rendszerem Windows Server 2003 Enterprise Edition. Az Oracle-n belül szépen megy minden, de ftp-vel csak a bejelentkezés, a cd és az ls parancs megy. Szépen látom is az XML Database Resources folderének, ill. az alkönyvtárainak a tartalmát, de ha egy get parancsot adok ki, arra ez a válasz: ORA-00942: table or view does not exist.
Oracle jogosultságok rendben, XDBADMIN joggal sem, sőt a sys usernek sem megy a dolog.
Mi lehet itt a hiba?
Ha jól látom, már majdnem 2 éve volt ez a dolog. Meglepő módon az Oracle8i-ben ment végülis flottul minden. A megrendelő csak most szánta rá magát a 10g-re való átállásra, úgyhogy ezzel most kell foglalkoznom. Ismerkedem ezzel a 10g-vel, egész jónak tunik ez is, a minta XML és XSD fájlok szépen muködnek is. Igenám, de nekem nem mintafájlokkal kell dolgoznom, hanem azokkal, amelyek valahonnan jönnek, és olyanok, amilyenek. Ránézésre teljesen szépek, minden valid, az Oracle-be is be tudom olvasni, csak épp a lekérdezés nem megy (pl. az existsNode() és az extractvalue()).
A ténylegesen használandó XML és XSD fájlok elég bonyolultak, de egy általam alkotott egyszeru példán meg tudom mutatni, mi a problémám.
<?xml version="1.0"?> <tns:purchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://xyz.hu/test" xsi:schemaLocation="http://xyz.hu/test y2.xsd" orderDate="1967-08-13"> <tns:comment>Hurry, my lawn is going wild!</tns:comment> <shipTo> <name>Alice Smith</name> <street>123 Maple Street</street> <city>Mill Valley</city> <state>CA</state> <zip>90952</zip> </shipTo> </tns:purchaseOrder>
Tehát második az elsőtől abban tér el, hogy használ egy tns nevu name space-t. Az XmlSpy mindkettot validnak mondja, sot az oracle XMLIsValid() függvény is.
Az y1.xsd-ből az oracle az alábbi resource-ot hozza létre:
Az eltérés a kettő működése között az, hogy az y1.xml-re vonatkozó
select existsNode(OBJECT_VALUE,'/purchaseOrder/shipTo/name') from "purchaseOrder244_TAB";
kérdés 1-et, az y2.xml-re vonatkozó
select existsNode(OBJECT_VALUE,'/purchaseOrder/shipTo/name') from "purchaseOrder284_TAB";
pedig 0-t ad vissza.
Hasonlóan, az y1.xml-re vonatkozó select extractvalue(object_value,'/purchaseOrder/shipTo/name') from "purchaseOrder244_TAB"; kérdés visszaadja a tényleges "Alice Smith" értéket, míg az y2.xmlre vonatkozó select extractvalue(object_value,'/purchaseOrder/shipTo/name') from "purchaseOrder284_TAB"; kérdés pedig üres eredményt hoz.
A hasonló kérdések, amelyek a '/purchaseOrder/@orderDate' -re, ill. a '/purchaseOrder/comment'-re vonatkoznak, mindkét esetben jó eredményt adnak.
Sajnos én elég kezdő vagyok ebben a dologban, annak ellenére, hogy már 2 éve fut az Oracle8i-re írott xml-t oracle-be pakoló alkalmazásom.
Van valakinek elképzelése, mit kellene csinálnom, hogy az y2.xsd/y2.xml párost is rendesen le tudjam kérdezni? Tudom, kicsit bonyolult a dolog, de a mellékelt fájlok segítségével könnyen rekonstruálni lehet az esetet, és hátha ebbol rögtön látja valaki, mi itt a helyzet.
Kösz a választ! Egyelőre sajnos ezt a kérdést félre kell tennem, a megrendelő ugyanis az XML-be való exportot anyagi okok miatt csak jövőre fogja kérni, sőt idén még az Oracle9-re történő átállás is elmarad, úgyhogy most csak XML olvasással kell foglalkoznom, azzal is csak 8i-ben :(
select-el, sqlx függvényekkel nem tudod az encoding attribútumot beletenni.
Ha úgy készíted az xml-t, hogy nincs még prolog, akkor hozzá lehetne konkatenálni egyet.
Ha van prolog, akkor már nem megy a konkat, mert abból nem sül ki jó...
Szerintem a legjobb lenne, ha csinálsz egy pl/sql tárolt eljárást, ami az encoding-ot beállítja megfelelőre. Ez lehetne a sys.xmldom csomaggal, de az xmldom.setCharset() fgv. sajnos nem állítja be a megfelelő encoding értéket valami hiba folytán. Ez persze az újabb xdk-val változhat. Megcsinálhatod viszont java tárolt eljárással is, a file kezelésre már úgyis csináltál egyet.
Remélem, van olyan közöttetek, aki használ ORACLE XML funkciókat. Én most ismerkedek vele, és úgy tűnik, hogy működik. Tudok SQL queryből XML fájlt készíteni, és XML fájlt SQL-lel olvasni. Aprócska problémáim azért vannak, például most a következő.
Szeretnék egy ilyen XML fájlt csinálni SQL queryvel:
A prolog, vagyis a <?xml version="1.0" encoding="ISO-8859-1"?> sor nélkül símán megy:
select
xmlelement("DATATRANSFER",xmlattributes('egyik ceg' as "snd",'masik ceg' as "rcv"),
xmlelement("MSG",xmlattributes('uzenet azonosito' as "MessageID"),
xmlelement("tenyleges_adatok")
)
)
from dual ;
A prologot a SYS_XMLGEN() függvénnyel próbáltam rárakni, kis hibákkal sikerült is. A parancs:
select
sys_xmlgen(
xmlelement("MSG",xmlattributes('uzenet azonosito' as "MessageID"),
xmlelement("tenyleges_adatok")
),
xmlformat.createformat('DATATRANSFER')
).getclobval()
from dual;