Az instance ugyanaz, nem kell módosítani az eljárást. Találtam még egy egyszerűbb megoldást (az elv hasonló, itt nem html az output, de ez is XML-en keresztül megy):
DECLARE cur sys_refcursor; BEGIN OPEN cur FOR SELECT * FROM emp; FOR c IN (SELECT t2.COLUMN_VALUE.getrootelement () NAME, EXTRACTVALUE (t2.COLUMN_VALUE, 'node()') VALUE FROM TABLE (XMLSEQUENCE (cur)) t, TABLE (XMLSEQUENCE (EXTRACT (COLUMN_VALUE, '/ROW/node()'))) t2) LOOP DBMS_OUTPUT.put_line (c.NAME || ': ' || c.VALUE); END LOOP; END; /
>Szeretnék csatlakozni Mi a gond? Tudod a virt géped ip-címét. Ha installtál rá Oracle-t (és el is indítottad) tudod a portot és a sidet (lásd product10.2.0db_1NETWORKADMINlistener.ora). Csak ennyi infó kell egy sikeres tnsnames.ora kigenerálásához.
Marha izgalmas és jó a kérdés, kár hogy nem tudok a témával kísérletezni, meg hosszabban foglalkozni...
- Szerintem az én linkemben is ott a megoldás az első "and we said..." szekcióban. - Ugyanaz a Thomas Kyte prezentálja a megoldásokat... (szerintem a lényeg is ugyanaz, az én linkem cikke mondjuk kicsit régi, és nem XML-es technikájú) http://tkyte.blogspot.com/2006/01/i-like-online-communities.html http://tkyte.blogspot.com/2006/01/9i-10g-version.html - Bevallom férfiasan; akárhogy nézem a kódokat - a rászánt pár percben - nem nagyon értem a dolog mélyét. De intuició alapján, símán el tudom képzelni a működését... (Már persze feltéve, hogy a function ugyanabban az instance-ban van, ahonnan a ref cursor cucca jön: különben nem) - Úgy értettem nem nagyon tudsz módosítani a ref cursor képzésének helyén. Pedig mint ha ez kellene. - Implicit offtopic: a ref cursor igen nagy hátránya, hogy instance-ok között nem megy.
Mindenkitől bocs, ha téves dolgot írtam nagy hevenyészés közepette...
Új vagyok Oracle témában,ill már telepítettem leírás alapján oracle9i-t redhat9 -re
kb 2 évvel ezelőtt.
Most oracle express debian4. virtuális gépen.
Szeretnék csatlakozni a virtuális géphez programon keresztül. Az oracle kliens programja fent van. Gondolom egy tns...ora fájl kellene ami tartalmazza a virtuális gép eléresét (ip,port,prortokol).
Köszönöm, de nem látom a megoldást a linkedben. Közben találtam egy lehetséges megoldást: http://forums.oracle.com/forums/thread.jspa?messageID=1185524
Parse out columns of a weakly typed ref cursor http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1895778276754
Az trivi, hogy a ref cursor egy szimpla pointer és esélyed nincs normál körülmények között kinyerni a describing infókat. Thomas Kyte a fenti cikkben láthatóan vázol egy workaroundot, de bevallom férfiasan kétszeri elolvasás után sem értem az elgondolása magvát, meglehet azért mert egésznapi agymunka után, hullafáradt vagyok már.
Holnap ha nagyon nem boldogulsz, megpróbálhatunk ismét nekifutni...
van valami ötletetek arra, hogyan lehetne a ref cursor által visszaadott öszlopokról leírást kinyerni (dinamikusan szeretném megnyitni a cursort, nem a ismerem előre a szerkezetét). DBMS_SQL.DESCRIBE_COLUMNS eljárással találtam megoldást (http://www.oracle.com/technology/oramag/code/tips2003/042003.html) , de ahhoz a ref cursor-t is ezzel a csomaggal kell kezelni, nálam a ref cursor-t visszaadó eljárások adottak, abba nem tudok belenyúlni).
Az Sql*Plus tudja valahogy, ezt a kiírást szeretném megcsinálni egy pl/sql eljárásból:
create or replace procedure emp_refcursor (p_dept in emp.deptno%type, p_cur out Sys_Refcursor ) is begin Open p_Cur For 'select empno,ename,job from emp where deptno='||p_dept; end; /
SET LINESIZE 1000; SET PAGESIZE 1000; VAR X REFCURSOR;
A scenario annyi volt, hogy egy reporting adatbazis frissult ejjelente. A webes reportok az MV-bol kerdeztek le. A refresh idotartamara a web nem volt leallitva.
Amig a fast refresh megy, addig jo, mert a report vagy a tegnapi adatokat mutatja, vagy mar a maiakat, koztes allapot nincs.
Viszont ha complete refresh van, akkor amig az fut, addig az MV ures, a report meg hulyeseget mutat. Ha valaki felkel hajnalban dolgozni, baromsagot lat.
Lehet, hogy el kéne olvasnod a referenciát... ;) ->NEXT SYSDATE + 1 a naponkénti;
Itt is lehet gáz a sysdate elcsúszásával... (például shutdown+startup után). Én jobb szeretem vagy kézzel vezéreltetni a frissítést (operátori indítás), vagy külső plsql progival - a dbms_job segítségével - korrekten beállítani az aktuálisan következő effektíve helyes adattartalmú konkrét időpontot.
Nem vagyok DBA, viszont szívtam már meg ilyen jellegű üzemeltetési gondokat ("egyik kéz nem tudja mit csinál a másik"). Lehet, hogy van korrektebb kezelés is, nekem a fenti módszer vált be.
Majd' elfelejtettem érdekes adalékként megemlítve (nem konkréten az alapkérdéshez kapcsolódva):
Nálunk egyszer volt olyan gond, hogy a végletekig optimalizált belött rendszerről készített MV-k 'on demand' Fast Refresh-e sem fért bele, a mentés előtt. Ezért felmerült a gondolat bennem (és implementáltam is, mivel nem nagy varázslás), hogy a logokat és a változást szenvedett rekordtartalmakat unloadoltam filerendszerbe, ahonnan ftp után az MV-k oldalán le lehetett 'játszani' (play) a scripteket a forrás rendszertől immáron függetlenül. A dolog működik, egyetlen szépséghibája volt: az Oracle egy nemdokumentált feature-ét használta ki megkerülhetetlenül, amit a megrendelő nem akart tolerálni semmiképp (ezért nem állt élesbe).
>Azt hiszem a válaszok megértéséhez is sokkal jobban kellene ismernem ezt a környezetet
Azt gondolom ('függetlenként' és nem 'hazabeszélve'), hogy az MV-k Oracle implementációja - Nagyon jól megtervezett - Nagyon jól sikerült fejlesztés (és fejlődik folyamatosan, pl.: limitek eltörlésével, vagy legalább kijjebb tolásával) - Nagyon hasznos, nagyon jól használhatók a való életben - és bizony nem kevés információ van a témában. 'query_rewrite' korrekt megértése például önmagában megér egy misét... Az Oracle maga is tán 2-3 napos tanfolyamot ajánl a témában (tán elsősorban inkább csak külföldön)
>Ez alatt azt értem, hogy a felh -k nem rögzítenek, töltenek be semmit csak és kizárólag lekérdeznek. Ez szimpatikus, jól hangzik... Ráadásul, ha jól értem instance-on belül, ami külön öröm a párhuzamosítás lehetősége miatt.
>A feltöltés havonta több alkalommal, akár naponta többször is történik egy automatizmus alapján, de nem állandóan. Mikor a MV-k frissülnének az adatbetöltés, átemelés szünetel.
Ez a típikus 'on demand' frissítés igénye. Én is ezt szeretem jobban (ugyanis a MV-célplatform a frissítés megkezdéséig akár offline-ban is lehet, ami nagyon kellemes feature). Frissítés alatt elvben mehet adatbetöltés is, hisz a Fast Refresht támogató MV-logok mindig csak SQL-Insertekkel bővülnek bármely típusú DML esetén... Sőt mint mondtam a betöltés + frissítés vége utáni commit eredményezhet két adatkonzisztens Oracle objektumot (betöltött táblát + MV-t)
>Adatkonzisztencia Ha jól értem elvben nem kell neked a refresh group. Hisz, ha nem töltesz, akkor a refresh groupon kívüli MV Fast Refresh-ek nem tudnak inkonzisztenciát okozni hiszen az alapadatok nem változnak.
Azaz szerintem jók a peremfeltételeid és elvben mindent tudsz a sikeres MV-zés megkezdéséhez... :o)
>a fast refresh az tranzakcios, tehat mindig ott az adat az MV-ben, csak delete/update/insert tortenik.
Szerintem 'lokális' értelemben nem 'tranzakciós' azaz nem 'DML'-enként, hanem csak a frissítés végén van commit (azaz 'globális' értelemben tranzakciós csak). Ennek legfőbb oka, hogy a hatékonyság miatti internal C-s Fast Refresh DML -> _nem_ SQL-szintű DML. Ezen közben persze selectálható az MV, de nem látható a menetközbeni fast-refresh-es változás.
Hogyha kétirányú szinkronizációt támogató updateable MV-kről beszélünk, akkor hogy milyen DML-ek megengedettek az mv-n a frissítés alatt, az külön történet. Nem is nagyon mélyedtem bele, nem is nagyon szimpatikus a lehetőség (noha elismerem, hogy az ügynökök laptopjain lévő változásokról akarhat tudni a 'központ')
>De a complete az a truncate miatt ugye committol az urites vegen. A truncate DDL-művelet, tehát implicit - Oracle SQL-engine által kezdeményezett - commit van, így a frissítés során MV-be átjött rekordok a globális frissítési tranzakciós commit után láthatók csak, az én emlékeim szerint is. Mondjuk a magam részéről én _annyira_ nem voltam elégedett a performanciájával, annyira nem találtam tuningolhatónak és annyival jobban bejött az 'offline' módszer, hogy nem nagyon firtattam az egész complett refresh témát, sose... (És csak 9iR2-ig van csak tapasztalatom)
materializedview tmp_mv_teszt_mv REFRESHSTARTWITH ROUND(SYSDATE-1) + 13/24 + 15/24/60 as select INTID as mv_id, INTKOD as mv_kod, INTOEPKOD as mv_oep, INTNEV as mv_nev, INTTELJNEV as mv_telj_nev, MEGJ as mv_megj, INTKOD || ' - ' || INTNEV as mv_nev_kod from tmp_mv_teszt;
"
és ez lessz belőle:
"
create
materializedview TMP_MV_TESZT3_MV refreshforceondemand startwith to_date('04-05-2007 13:15:00', 'dd-mm-yyyy hh24:mi:ss') nextnull as select INTID as mv_id, INTKOD as mv_kod, INTOEPKOD as mv_oep, INTNEV as mv_nev, INTTELJNEV as mv_telj_nev, MEGJ as mv_megj, INTKOD || ' - ' || INTNEV as mv_nev_kod from tmp_mv_teszt "
Javits ki, ha rosszul emlekszem, de mintha az lenne, hogy a fast refresh az tranzakcios, tehat mindig ott az adat az MV-ben, csak delete/update/insert tortenik. De a complete az a truncate miatt ugye committol az urites vegen. Regen hasznaltam mar...
Rettenetes nagy futási idő különbségek vannak a full és fast refresh között. A fast refresh-t ugyanis agyon optimalizálták (internal C) Oracle Corp-nál, ezért is meglepően gyors... Míg a complett hiába truncate-tel kezdődik: a nagy teljesítmény veszteség a hálón keresztüli átnyomáson van, típikusan (adatmennyiség, dblink, -nemparallelizálhatóság, unoptimális Oracle hálózati architektúra rengeteg réteggel etc.)
A vázolt szituban meglehet nem elég a complett refresh preformanciája (nekem volt erre precedensem), ilyenkor ajánlott a klasszikus BCP/DR megoldás: eredeti tábla például tablespace transportos (fileszintű!) átmozgatása (de ezer más akár gyorsabb és/vagy drágább technika is létezik) és egyetlen paranccsal mv-vé alakítása.
Oda kell figyelni nagyon tehát az adminisztrációra, és a BCP/DR-re. És az ugye mindenkinek trivi, hogy a fast refresh log generálása jelentős overheadet tud generálni az eredeti OLTP folyamatokra nézvést?
a force azt jelenti, hogy ha lehet akkor fast refresht csinal, de ha nem lehet akkor fullt.
megy szepen a dolog, mindenki boldog, aztan egyszer valami miatt kimarad a refresh vagy hasonlo, es nem lesz eleg a refresh log (asszem igy hivjak) es inkabb fullt csinal.
a full viszont truncate majd insert, ergo lesz egy adatmennyisegtol es egyebektol fuggo nagysagu idoablak, amikor a tabla URES! ha kozben futnak dolgok amik hasznaljak az mv-t, jol pofara tudnak esni, es neha nem trivialis rajonni mi volt, mert napkozben nem reprodukalhato, es atlagember nappal dolgozik.
Automatic Refresh Times for Materialized Views: Example The following statement creates the complex materialized view all_customers that queries the employee tables on the remote and local databases:
CREATE MATERIALIZED VIEW all_customers PCTFREE 5 PCTUSED 60 TABLESPACE example STORAGE (INITIAL 50K NEXT 50K) USING INDEX STORAGE (INITIAL 25K NEXT 25K) REFRESH START WITH ROUND(SYSDATE + 1) + 11/24 NEXT NEXT_DAY(TRUNC(SYSDATE), 'MONDAY') + 15/24 AS SELECT * FROM sh.customers@remote UNION SELECT * FROM sh.customers@local;
Oracle Database automatically refreshes this materialized view tomorrow at 11:00 a.m. and subsequently every Monday at 3:00 p.m. The default refresh method is FORCE. The defining query contains a UNION operator, which is not supported for fast refresh, so the database will automatically perform a complete refresh.