mi az a valtnev meg vusazon? ha az ket valtozo, akkor vagy azok is kettospontos bind valtozok kellene legyenek, vagy azokat is be kellene konkatenalni. (utobbi erosen ellenjavallt, lasd sql injection attack)
az execute-kor meg kellene adni a bind valtozok ertekeit, kulonben hogyan hajtsa vegre?
execute immediate sqlp1 using 'pisti','vasszog',3;
aprosagok: ez plsql? a kapcsoszarojel oda tuti nem kell. a sysdate az nem fuggveny, nem kell utanna ()
Egy egyszerű insertálást szeretnék egy adott táblába végrehajtani úgy hogy a tábla nevét előtte egy változóban ( boltnev VARCHAR2(255);) rakom össze, de mindig azzal a hibával száll el, hogy nem megengedett tábla név.
Hogyan tudom apexben egy pl sql anonymus block-ban (after submitban) ezt összerakni?
Ez a kódom:
sqlp1:=q'{INSERT INTO '||boltnev||' (meboazon,meusazon,mefelvdate,meveazon,meteazon,memenny)
nade melyik exceptiont! mindig ird meg a hibat konkretan, mert neked lehet hogy nem jelent semmit ezert irrelevans, de nekunk meg eselyes hogy elmond mindent.
pl most az all_tables-t kerdezed. abban meg ugye olyan tablak is vannak, amik nem a sajatjaid, de van rajuk select jogod.
amikor direktben kerdezed, akkor ezert ki kell ird az ownert, mert nem a sajat semadban van. lasd tulajdonos1.konkret_tabla.
amikor a plsql kod epiti a query-t, akkor meg nem teszi bele az ownert, ezert ad hibauzenetet. es a hibauzenetbol egyertelmu is hogy azert "no luck" mert nem talalta a tablat, ugyanis a sajat semaban kereste. az en querym az user_tables-bol vette a tablanevet, az tuti hogy a sajat semaban van, nincs ilyen gond.
igy a loop query-ben elo kell venni a tulajt is:
for s in (select table_name, owner from all_tables ...
es a ciklusmagban amit epitunk queryt, abban is meg kell adni az ownert:
execute immediate 'select scn_to_timestamp(max(ora_rowscn)) from '||s.owner||'.'||s.table_name into d;
nono. a rownum-os where-t bennehagytad? szures nelkul az elso random 5 tablat veszi elo, es azok eleg frissek hogy tudja a datumot. a szuressel a teged erdeklo tablakat veszi elo, es ugy tunik azok tul regen modosultak ahhoz hogy meg tudjuk mondani az scn-bol a datumot. azokra a tablakra ha szoloban vegrehajtod a select-edet, akkor is hibat fogsz kapni datum helyett.
egyszeruen kiadsz a konnekson krealas utan egy alter session set nls_language='AMERICAN'-t, es kesz. a charset meg hasonlok eldonteset meghagynam a kliensnek. ha mazlink van ettol meg az nls_date_language sem valtozik meg, es nem lesz a Márciusból March. Azert van esely hogy valahol masutt lesz meglepetes, valami elkezd amerikaiul mukodni.
az említett szűréseket beleírva ugyan kilistázza a feltételek szerint megszűrt táblaneveket, ám a legutolsó frissítési dátumot már nem tudja melléjük tenni, hanem az exception kerül kiírásra.
Azt kell meglatni, hogy ez a kod nem egy select. hanem egy select ami eloszedi a tablak neveit, es utanna tablankent egy-egy kulon select. tehat 20 tablara 21 select.
for s in (select table_name from user_tables where rownum<6) loop
ez a sor generalja a tablak neveit. ha szurni akarsz, akkor
for s in (select table_name from user_tables where owner = 'XY' and table_name like 'táblanév első betűi%' and rownum<6) loop
ha kell az osszes, akkor az and rownum<6-ot hagyd ki, ez csak annyit csinal hogy korlatoz az elso ot sorra.
A ciklus belsejeben ugynevezett dinamikus sql-t hasznal. Nem parameterkent ad at tablanevet select-nek, met azt nem lehet (lasd kettes pont), hanem string muveletekkel (konkatenacio) epit egy select statementet, es azt vegrehajtja. Ennek a select-nek egy kimeno parametere van, a datum, ezt veszi at a D-be. Lehetne bemeno parametere is, de azt csak a select utani oszloplistaban es a where-ben hasznalhatnad, a from-ban nem (lasd kettes pont).
Ez a string epitgetes: 'select scn_to_timestamp(max(ora_rowscn)) from '||s.table_name . ez egy string, stringmuveletekkel osszerakva.
Tegyük fel, hogy hiba történt az INSERT-ben, és sqlca.sqlcode==-1. Gyanítom, hogy valamilyen constraint sérült.
Vajon mit ténykedek, ha (magában a programban) szeretném megállapítani annak a contraint-nek a nevét, ami sérült, hogy isten ments valahogy megpróbáljam menteni a helyzetet, vagy legalább informatív hibaüzenetet adjak?
Nem találtam jobbat, mint hogy az SQLErrorGetText kimenetében megkerestem az első (vagy egyetlen) zárójelpárt, abban volt a constraint neve. Na, eddig ment, de ma a következőt kaptam: 'z'.... Némi nyomozás után bele is raktam a programba a következő üzenetet:
if (q==p+1 && p[0]=='z') { /* Ezt találtuk meg: "A(z)" */ fprintf (stderr, "*** Valami jószándékú idióta az Oracle üzenetek" " nyelvét magyarra állította.n" "*** Kérlek javítasd ki:n" "export NLS_LANG=American_America.EE8ISO8859P2n"); p= q+1; goto KERESS; }
SQL window-ban futattam és ez magyarázatot ad arra, hogy miért futott le a serveroutput on nélkül, viszont hogy miért nem írta ki az exception-öket az homály..
Az egész kód lefut szépen, ha nincs meghatározva a táblák köre, maximum arra korlátozódik, hogy all_tables, vagy user_tables. Azonban ez a halmaz így nincs eléggé leszűkítve.
Nagyon jó lenne ha beleműthető lenne az alábbi feltételpáros:
...
where owner = 'XY' and table_name like 'táblanév első betűi%'
A már korábban említett
1. a select tablabol olvas
2. hogy melyik tablabol, az nem tud parameter lenni
pontokon kellene felülemelkedni..
- egyébként ez a mostani script is selectből olvas,
...
for s in (select table_name from user_tables where rownum<6) loop
...
- mégis lefut, ám ahogy a táblák körét, illetve azok nevét próbálom kiszűrni/átadni egyből nem működik, nem megy át a táblák neve, pedig trükköztem vele..
Összeségében egy szép ciklus motor lenne olyan esetekre, mikor meghatározott táblákon végigmenve kellene azokkal valami egyen műveleteket végezni..
biztos lehet abban is, csak maskeppen kell bekapcsolni az outputot. nem hasznaltam kb soha, sajnos ebben nem tudok segiteni. a helpjeben ha rakeresel a dbms_output-ra, tuti megtalalod.
Pl sql developert használok és az első sorra a hibaüzenet:
ORA-00922: Nem megengedett vagy hiányzó opció
Az az érdekes hogy ezután rögtön dob egy másik hibaablakat is, miszerint 4. sor 93. oszlop: identifier 'D' must be declared és 4. sor 7. oszlop: statement ignored - azonban ha kihagyom az első sort, akkor ez nem jelenik meg, hanem a már említett módon lefut úgy hogy 'se kép, se hang'..