Már régóta csináljuk így, automatikus újrafordigatással, csak egyre hosszabb ideig tart. Persze a delete egy nem partícionált táblán hosszabb lenne - meg sokat kéne move-olgatni.
Egy invaliddá vált procedúra simán továbbfut. Csak pl. visszahívni már nem tudja magát (meg más sem tudja hívni), mert először az Oracle implicite le akarja fordítani, ami nem megy neki, mert ugyebár fut. Na erre ítéletnapig képes várni az oracle (4 órát biztos :) hogy hátha befejezi a futását végre a procedúra. Explicit fordításkor ha jól emlékszem, 300 másodperc múlva a recompile hibára fut, ha nem tudja zárolni a procedúrát magának - márpedig ha fut, akkor nem tudja. Ráadásul újrafordítás után, azon sessionökben, ahol korábban már futtatták, a procedúra legközelebbi meghívásakor kapsz egy "object's state is modified" (vagy ilyesmi) hibát. Az ezután következő hívásnál ugyanebből a sessionből viszont szépen lefut!
Valóban "kicsit" problémás a dolog a motor oldaláról, de engem ettől még zavar :) Belegondolva, nem is tudom, hogy megy-e a drop partition, ha éppen select fut a táblára. Ha nem megy, akkor egyátalán nem értem, hogy minek invalidál. Ha megy, akkor triviális - elég nehéz kitalálni, hogy éppen kersztbe teszel-e a futó selectnek.
Nem találtam sehol olyan parnacsot, amivel le tudnám kérdezni, hogy egy táblában létezik-e az adott oszlop. Nagyon sok táblán kell lefuttatni vmit, de csak amiben egy adott mező megtalálható. Köszönöm.
Mar regen tul vagyunk rajta, az elso feladatok kozott volt annak idejen. Mondjuk erdekes, hogy a tobbi, altalunk hasznalt adatbaziskezelo automatikusan megoldja ezt a kerdest, csak az Oracle-es verziohoz kellett megirnunk.
>A legszebb az, amikor az invalidda valt objektumok kozott is van fuggoseg, es nem mindegy, hogy milyen sorrendben validalod... Ja-ja. Épp ezért erre a célra van a dba_dependencies (+order by). Vagy a brute force (isméltelten kellő számban végrehajtott fordítási ciklus kísérlet -> mindaddig legalábbis, amíg legalább egy objektum sikeresen fordul le) Egyébként ez érdekes téma, jó játék. :o)
"Package becomes INVALID when a partiiton is dropped" http://www.freelists.org/archives/oracle-l/06-2005/msg01247.html
A fenti link szerint, azért válik invaliddá egyes tárolt eljárások, mert nem varchar2(2), hanem t1.col%type-ként deklaráltál. Az előbbi esetben nincs invaliddá válás.
Kiegészítés1: külön történet az automatikus recompilálás. Ilyen kódot pár sorban nagyon könnyű írni. (És drop partition után futtatni). És aztán karosszékben kényelmesen hátradőlve azon merengeni, helyes-e az oracle Corp részéről ilyesmivel fárasztani a szegény usereket... ;) Másik lehetőség, ahogy mondják is: szétválasztani a drop partition témát az application témától.
Kiegészítés2: valaki nyitott TAR-t a témában a metalinken. Azt meglehet érdemes lenne megnézni (ha van élő supportod)
"Compile procedure automatically -- how to avoid cascading invalidations" http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:286816015990
"yes, that'll invalidate the package since the package is dependent on the TABLE (not the partitions therein) and the table has been structurally modified to a degree that necessitates recompilation."
"incremental refinements happens all of the time in Oracle - there are fewer invalidations in 10g than there were in 9i than there were in 8i than there were......."
>Van valakinek valami használható ötlete arra, hogy a függőség ne invalidáljon drop partition-ál? /9i2-őt használok/
Na azért szerintem óvatosabban az ilyen igényekkel... ;)
- First lookra megalapozottnak tűnik annak felvetése, hogy partició eldobáskor miért válik invalidussá az alattvaló objektumok. Valszeg azért, mert bonyolult művelet a drop partition (indexek azonnal mennek a levesbe, garmadányi data dictionary view stb.). És azért el lehet képzelni némi fantáziával, hogy van olyan pillanat, amikor _nem_ selectálható a folyamat során a tábla (és DDL-probléma miatt, nem DML-tranzakció probléma miatt!). De ez maradjon nyitott kérdésnek a továbbiakra.
- Nem mindegy, hogy view avagy store procedure válik invalidussá. De ezt most nem ragozom tovább, egyébként könnyen belátható.
- BTW.: Az első kézenfekvő ötlet: dinamikus sql használata a tárolt eljárásban. Ne nevessen senki: ez szerintem nem olyan hülyeség, ha egy eljárás több instance-ban érintett, és fel-le kapcsolgatják az instance-okat az üzemeltetés során. Az más kérdés, hogy ökölszabálynak ('mindent dinamikus sql-be!') én sem mondanám ki.
- Ha 8i-ben tennéd fel a kérdést, az némileg érdekesebb lenne. De ott is van megoldás (egy igen kevéssé dokumentált view): sys.order_object_by_dependency. Kombinálva /join formájában/ mondjuk a dba_objects-cel már lekérdezhető lenne a neked szükséges infó. Drop partition elött, of course.
- 9i-ben már van: dba_dependencies. Type-ok is korrektek már benne.
- Nem akarok hülyeséget mondani, de invaliddá vált procedure mintha nem nagyon futkorászhatna tovább szerintem az RDBMS-ben.
Sziasztok! Némi kényelmetlenséget okoz nekem az objektumok közti függőség: ha idő szerint partícionált táblákból régi partíciót eldobálok, minden ezt használó eljárás/view invalid lesz, aztán fordigathatom újra bőszen a fél adatbázist. Ami nem is olyan egyszerű, ha pl. fut egy frissen invalidált procedúra. Van valakinek valami használható ötlete arra, hogy a függőség ne invalidáljon drop partition-ál? Tudom, hogy az oracle által látott függőséget meg lehet szüntetni az "execute immediate" sűrű használatával (persze view-ra ez sem megoldás). De magával a függőség létezésével nincs bajom, mert segít az adatbázis egységét fenntartani (legalább tudom, hogy kinek mi kell, hogy működjön). 9i2-őt használok Köszi az ötleteket :)
>Ha nincs jobb ötleted, keresgélj a 'GRANT INSERT ON ... TO ...' körül Na jó! De ki adja ki? Ő saját magának ugye nem tudja, de nem feltétlen kell a DBA sem, ugye... ;)
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;