Logiranje izmjene strukture baze - DDL LOGGER

April 11, 2013 – mradovan

Modeliranje baze podataka često nije jednokratan posao, uvijek se nađe potreba da se naprave izmjene na dijelovima koda ili strukturi tablica, doda ili oduzme neka kolona u nekoj tablici, izmijeni tip podatka neke kolone, doda ili obriše neki ključ ili index…

Kada se takve izmjene rade nepredviđeno, a ne dokumentiraju se, ili u okolini gdje takve stvari radi više ljudi (namjerno ili slučajno), i kad se to radi ručno kroz komandnu liniju a bez modeliranja u nekom alatu za modeliranje (čiji bi se modeli spremali pod sistemom verzioniranja), mogu dovesti do vrlo nezgodnih situacija u kojima ne znamo tok događaja - tko je, kada i što napravio (i zašto ?).

Čak sam i sam bio u situacijama gdje neke promjene radim na razvoju, pa nakon nekog vremena ne znam šta sam napravio i kojim redoslijedom, ili zaključim da sam otišao pogrešnim putem i da se trebam vratiti nekoliko koraka unatrag, a ne znam točno kako…

Rješenje je vrlo jednostavno - database trigger koji logira sistemske događaje u tablicu DDLOG sa sljedećim kolonama:

  • OWNER (vlasnik objekta)
  • OPERATION (CREATE, ALTER ili DROP)
  • OBJECT_TYPE (procedure, table, trigger,package…)
  • OBJECT_NAME (ime objekta)
  • SQL_TEXT (prvih 1000 znakova sql izraza)
  • SQL_FULLTEXT (kompletni kod izraza)
  • CREATED (vrijeme upisa)
  • CREATED_BY (user koji je pokrenuo operaciju)
  • TERMINAL_NAME (ime računala s kojeg je operacija pokrenuta)
  • TERMINAL_IP (IP adresa računala s kojeg je operacija pokrenuta)
  • SESSIONID (ID sesije u kojoj je operacija izvršena).

Iz drugih korisničkih shema se može raditi select na ovu tablicu uz posjedovanje SELECT ANY TABLE privilegije.

Druga tablica ERRLOG služi za logiranje eventualnih grešaka u samom triggeru.

Priložena je skripta koju je potrebno pokrenuti pod SYS userom, čime se kreira user DDLOGGER, sa tablicom DDLOG:

/********************************************************************************************************************************************
Desc: User for logging changes on database objects: CREATE, ALTER and DROP operations.
Author: Mihael Radovan
Last change: 28.03.2013
********************************************************************************************************************************************/
/*  user with privileges */
CREATE user ddlogger IDENTIFIED BY DDL;
GRANT UNLIMITED TABLESPACE TO ddlogger;

/* error log table */
CREATE TABLE ddlogger.errlog
(tstamp TIMESTAMP DEFAULT systimestamp,
errcode number,
errtext varchar2(500))
NOLOGGING, COMPRESS FOR oltp, NOCACHE, NOMONITORING;

/* err log procedure */

CREATE OR REPLACE PROCEDURE ddlogger.plog(errcode number, errtext varchar2)
IS
  PRAGMA autonomous_transaction;
BEGIN
  INSERT /*+ append */ INTO ddlogger.errlog(errcode, errtext)
  VALUES (errcode, errtext);

  COMMIT;

END plog;
/
/* ddl log table */

CREATE TABLE ddlogger.ddlog (
owner   VARCHAR2(30),
operation   VARCHAR2(30),
object_type VARCHAR2(30),
object_name VARCHAR2(30),
sql_text    VARCHAR2(1000),
sql_fulltext clob,
created TIMESTAMP,
created_by  VARCHAR2(30),
terminal_name VARCHAR2(255),
terminal_ip VARCHAR2(30),
sessionid number)
NOLOGGING, COMPRESS FOR oltp, NOCACHE, NOMONITORING;

/* database trigger */

CREATE OR REPLACE TRIGGER ddlogger.DDL_TRIGGER BEFORE DDL ON DATABASE
DECLARE
  oper varchar2(30);
  l_sql_text ora_name_list_t;
  l_count NUMBER;
  l_sql varchar2(1000);
  errcode number;
  errtext varchar2(500);
BEGIN
  SELECT ora_sysevent
    INTO oper
   FROM DUAL;

   l_count := ora_sql_txt(l_sql_text);

  FOR i IN 1..l_count

  LOOP
      l_sql := l_sql||l_sql_text(i);
  END LOOP;

  IF (oper IN ('CREATE', 'ALTER', 'DROP')) AND (ora_dict_obj_name != ' ddlog') THEN NULL;

   INSERT /*+ append */ INTO ddlogger.ddlog (owner, operation, object_type, object_name, sql_text, sql_fulltext, created, created_by, terminal_name, terminal_ip, sessionid)
   VALUES (ora_dict_obj_owner, oper, ora_dict_obj_type, ora_dict_obj_name, substr(l_sql, 1, 1000), l_sql, systimestamp, user, SYS_CONTEXT ('userenv', 'host'),  SYS_CONTEXT ('userenv', 'ip_address'), SYS_CONTEXT ('userenv', 'sessionid'));
  END IF;

EXCEPTION
  WHEN others THEN
     errcode:= SQLCODE;
     errtext:= SQLERRM;
     plog(errcode, errtext);
END;
/

REGEXP_SUBSTR/REGEXP_INSTR: ORA-01428: argument ‘-1′ is out of range

February 11, 2013 – Dejan

Programiram ja danas nesto i hocu pri tome koristiti regular expression (REGEXP_SUBSTR, REGEXP_INSTR i REGEXP_REPLACE), ali sam na jednom “problemu” izgubio 3-4 sata i ne mogu da nadjem uzrok te greske… Ni Google mi nije pomogao, MyOracleSupport takodje nista…

Htio sam koristiti opciju “backward search”, tj. da se pattern u stringu trazi unatrag, a ne od pocetka. Dakle, ovaj SQL:

select regexp_instr('Austria01#Vienna01#1130', '#', -1, 1)
from dual;

izbacuje gresku:

ORA-01428: argument '-1' is out of range

Sluzbena dokumentacija prvo kaze:
“position: A nonzero integer indicating the character of source_char where the function begins the search. When position is negative, then the function counts and searches backward from the end of string.

A na drugom mjestu samo:
“position is a positive integer indicating the character of source_char where Oracle should begin the search.”

Dakle, sta je od ovih tvrdnji u sluzbenoj dokumentaciji tacno!?

Kao sto rekoh, pretragom interneta nisam nasao nikakve korisne informacije, tako da sam kreirao Service Request kod Oracle Support, pa cemo vidjeti sta ce oni reci…

Stay tuned.

Edit 21.02.2013.:
nakon prepiske sa Oracle Supportom, ustanovljeno je da je dokumentacija pogresna. :)
Ovo su mi javili:

“Hello,

the new doc bug 16374293 has been created and it was already screened for DBE, then it will be processed in accord with its priority and the next Olap guides will be corrected.

Thanks for your hint.”

Znaci, trenutno nije moguce koristiti backward search sa REGEXP komandama…


Druženje u Beogradu?

January 26, 2013 – Dejan

Nakon nekoliko seminara u Zagrebu, ovaj put idem na jedan kurs u Beograd: “Oracle Database 11g: Data Guard Administration Rel 2″, jer mi je potreban kao uslov za polaganje OCM (Oracle Certified Master) ispita.
Dakle, od 31.03.2013. do 04.04.2013. sam u Beogradu, pa ako je neko za druženje uz pivo/nespresso/ćevape/Sushi i ostale delikatese, nek se javi!


Full Table Scan vs. BITMAP Index vs. VIRTUAL Column

November 2, 2012 – Dejan

Ovaj put donosim još jedan primjer iz prakse, na osnovu kojeg ću pokazati interesantne metode optimizacije problematičnog SQL upita.

U stvarnoj bazi postoji jedna tabela, u koju se podaci unose i obrađuju po slijedećem principu:
- podaci se unose u nejednakim razmacima, pri čemu se jedna status kolona označi sa ‘N’, što znači da podaci nisu obrađeni; ukoliko dođe do neke greške prilikom unosa ili su podaci nepotpuni, onda status kolona dobija vrijednost NULL
- jedan SQL upit se izvršava svakih 5 sekundi i provjerava, da li postoje neobrađeni ili nepotpuni podaci
- ukoliko postoje neobrađeni podaci, onda bivaju obrađeni, nakon čega se vrijednost u status koloni mijenja iz ‘N’ u ‘Y’

E sad, ostavimo na stranu što je dizajn ove tabele, odnosno njena fizička struktura, u praksi veoma loša…

Zadatak je da optimiram onaj SQL, koji svakih 5 sekundi provjerava, da li postoje neobrađeni podaci. Možeš se žaliti da je struktura tabele loša i da ju treba izmijeniti - odgovor je uvijek isti:”Nemamo sad vremena za komplikovane izmjene, moramo do kraja mjeseca završiti druge bitnije stvari, a to ćemo naknadno…bla bla“…

Dakle, na posao… Trebalo mi je skoro 2 sata vremena, ali rezultat je bio itekako dojmljiv… Zanima vas kako?
Pročitaj kompletan tekst »


Interval partitioning: zašto i kako?

October 27, 2012 – Dejan

Zašto?

Slagaću ako kažem, da nisam početkom skoro svake godine nailazio na grešku “ORA-14400: inserted partition key does not map to any partition“. Uvijek, ali uvijek! neko od programera zaboravi kreirati particiju za MAXVALUE ili particije i za narednu godinu, pa poslije Nove godine bude frka i panika, kad aplikacija ne radi, a telefon zvoni, dok preko E-Maila šalju screenshotove sa greškom… Na svu sreću, Oracle je tom problemu izašao u susret i omogućio opciju “Interval partitioning“, pomoću koje se nove particije automatski kreiraju.

Naravno kao i uvijek ću na praktičnom primjeru pokazati i objasniti, kako se interval partitioning podešava, kao i osnovne naredbe za rad sa particijama i subparticijama u tom slučaju.
Pročitaj kompletan tekst »


Preglednost kôda: IF var1,…,varN IS NOT NULL … vs. COALESCE(var1, var2,…, varN)

October 24, 2012 – Dejan

Po ko zna koji put vidjam u PL/SQL procedurama aljkav kôd i ne mogu se nacuditi raznim improvizacijama i perverzijama, koje pojedini programeri pisu…

Jedna od zadnjih se protezala na 90 linija kôda i izgledala je ovako:

IF var1 IS NOT NULL THEN varResult := var1;
ELSIF var2 IS NOT NULL THEN varResult := var2;
...
ELSIF varN IS NOT NULL THEN varResult := varN;
END IF;

Mislim, cemu to!? Shvatio sam da je cilj provjeriti varijable jednu po jednu, i cim se dodje do prve varijable, koja ima neku vrijednost, dodijeliti ju rezultatskoj varijabli. Zar nije ovako preglednije?

varResult := COALESCE(var1, var2, ..., varN);

FLASHBACK DATABASE glavu čuva!

October 23, 2012 – Dejan

Zašto Flashback?

Sigurno ste se već našli u situaciji da imate veoma kratak “maintenance window” u sklopu kojeg se vrše neke izmjene nad bazom, npr. instaliranje novog patcha, novi release ogromne aplikacije ili neka slična operacija, koja bi mogla biti kritična, što znači, da bi u slučaju neke greške ili neželjenog rezultata morali vratiti bazu u prvobitno stanje, dakle prije te izmjene.

U mnogim slučajevima se previdi taj “fallback” scenario, pa Oracle DBA radi restore kompletne baze… A to traje, pogotovo ukoliko je baza velika… Taman ste pomislili:”Još ova sitnica, 5-10 minuta i gotovo!“, kad ono cvrc! Greška. Panika. Psovanje. Restore baze. Pa se onda češkate po glavi i nestrpljivo čekate kad će restore biti okončan…

Taaa-daaam!

Od sad, pa nadalje i ubuduće za većinu tih “maintenance taskova” (plaćam pivo i ćevape za iole smislen prevod ovih riječi!) možete koristiti Flashback tehnologiju! Ukratko, Flashback omogućava “povratak u prošlost” do nekog zadanog trenutka.

Dakle, prije nego što započnete sa izmjenama na bazi, aktivirate Flashback i postavite tačku (”RESTORE POINT“) do koje želite vratiti bazu ukoliko dođe do nekih problema.

Kako Flashback?

Pokazaću kako se Flashback aktivira, kako se postavlja RESTORE POINT i kako se koristi za vraćanje kompletne baze do te tačke.

1. Da bi Flashback mogao biti aktiviran, baza mora biti u ARCHIVELOG režimu rada. Provjeriti parametre i ukoliko je potrebno, prebaciti bazu u ARCHIVELOG režim. U suprotnom, preskočite taj korak.

SQL> select log_mode, flashback_on from v$database;

LOG_MODE     FLASHBACK_ON
------------ ------------------
NOARCHIVELOG NO

SQL> sho parameter db_recovery_file_dest

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest                string      D:\_Oracle_\app\flash_recovery_area
db_recovery_file_dest_size           big integer 3912M

SQL> shut immediate
Database closed.
Database dismounted.
ORACLE instance shut down.

SQL> startup mount
ORACLE instance started.

Total System Global Area 2572144640 bytes
Fixed Size                  2178496 bytes
Variable Size            1811939904 bytes
Database Buffers          738197504 bytes
Redo Buffers               19828736 bytes
Database mounted.
SQL> alter database archivelog;

Database altered.

SQL> alter database open;

Database altered.

2. Potrebno je obavezno podesiti dva parametra u bazi: veličinu i lokaciju za Flashback arhivu:

SQL> alter system set DB_RECOVERY_FILE_DEST_SIZE=10G scope=BOTH;

System altered.

SQL>  alter system set db_recovery_file_dest='D:\_Oracle_\app\flash_recovery_area' scope=BOTH;

System altered.

Parametri moraju ostati permanentno u SPFILE ili u init.ora datoteci, da se ne bi nakon restarta baze izgubili. Ako ne stavite “scope=BOTH” ili ukoliko u init.ora datoteci ne sačuvate te parametre, onda ćete nakon restarta baze dobiti slijedeću gresku:

SQL> flashback database to restore point BEFORE_CHANGE;
flashback database to restore point BEFORE_CHANGE
*
ERROR at line 1:
ORA-00283: recovery session canceled due to errors
ORA-38770: FLASHBACK DATABASE failed during recovery.
ORA-38760: This database instance failed to turn on flashback database

a u alert logu ćete pronaći ove greske:

Thu Oct 25 09:45:09 2012
ALTER DATABASE   MOUNT
Successful mount of redo thread 1, with mount id 684437221
Allocated 14761792 bytes in shared pool for flashback generation buffer
Starting background process RVWR
Thu Oct 25 09:45:14 2012
RVWR started with pid=18, OS id=58916978
RVWR could not begin generation of flashback log data because
DB_RECOVERY_FILE_DEST is not set.
Errors in file ..._rvwr_58916978.trc:
ORA-38776: cannot begin flashback generation - recovery area is disabled
Database mounted in Exclusive Mode
Lost write protection disabled
Completed: ALTER DATABASE   MOUNT
Thu Oct 25 09:45:24 2012
flashback database to restore point BEFORE_CHANGE
Flashback Restore Start
Thu Oct 25 09:46:18 2012
Flashback Restore Complete
Flashback Media Recovery Start
 started logmerger process
Thu Oct 25 09:46:18 2012
Slave exiting with ORA-38770 exception
Errors in file ..._pr00_24903742.trc:
ORA-38770: FLASHBACK DATABASE failed during recovery.
ORA-38760: This database instance failed to turn on flashback database
Recovery Slave PR00 previously exited with exception 38770
Flashback Media Recovery failed with error 10879
ORA-283 signalled during: flashback database to restore point BEFORE_CHANGE...

3. Aktiviranje Flashback-a i postavljanje tačke povratka:

3.1. U verziji 10g baza mora biti u MOUNT režimu, da bi se Flashback mogao aktivirati:

SQL> shut immediate
Database closed.
Database dismounted.
ORACLE instance shut down.

SQL> startup mount
ORACLE instance started.

Total System Global Area 2572144640 bytes
Fixed Size                  2178496 bytes
Variable Size            1811939904 bytes
Database Buffers          738197504 bytes
Redo Buffers               19828736 bytes
Database mounted.

SQL> alter database flashback on;

Database altered.

SQL> create restore point BEFORE_CHANGE guarantee flashback database;

Restore point created.

SQL> alter database open;

Database altered.

3.2. U verziji 11gRel2 baza ne mora biti u MOUNT režimu, tako da odmah možemo aktivirati Flashback i postaviti RESTORE POINT:

SQL> alter database flashback on;

Database altered.

SQL> create restore point BEFORE_CHANGE guarantee flashback database;

Restore point created.

SQL> col name for a25
SQL> col time for a34
SQL> set lines 180
SQL> select SCN, NAME, GUARANTEE_FLASHBACK_DATABASE as GUA, STORAGE_SIZE, TIME
 from v$restore_point;

       SCN NAME               GUA STORAGE_SIZE TIME
---------- ------------------ --- ------------ ----------------------------------
   1673006 BEFORE_CHANGE      YES     15941632 23-OCT-12 10.00.42.000000000 PM

4. Napravimo neku izmjenu u bazi - za ovaj primjer ću samo kreirati jedan tablespace i jednog korisnika:

SQL> create tablespace dejan
datafile 'D:\_ORACLE_\APP\ORADATA\DWHTEST\dejan.dbf' size 16M autoextend off
extent management local segment space management auto;

Tablespace created.

SQL> create user dejan identified by dejan default tablespace users temporary tablespace temp;

User created.

Opcionalno možete povećati “retention time”, ukoliko taj “maintenance task” traje duže od jednog dana. Standardno je parametar “db_flashback_retention_target” postavljen na 1440 minuta, odnosno jedan dan, pa ga po potrebi povećajte:

SQL> sho parameter flashback

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_flashback_retention_target        integer     1440 

SQL> alter system set db_flashback_retention_target=2880;

System altered.

5. Ok, gotovi smo sa izmjenama, pa možemo ili vratiti bazu u prvobitno stanje ukoliko se pojavila neka kritična greška, ili deaktivirati Flashback i obrisati RESTORE POINT:

5.1. Vraćanje baze u prvobitno stanje:

SQL> shut immediate
Database closed.
Database dismounted.
ORACLE instance shut down.

SQL> startup mount
ORACLE instance started.

Total System Global Area 2572144640 bytes
Fixed Size                  2178496 bytes
Variable Size            1811939904 bytes
Database Buffers          738197504 bytes
Redo Buffers               19828736 bytes
Database mounted.

SQL> flashback database to restore point BEFORE_CHANGE;

Flashback complete.

SQL> alter database open resetlogs;

Database altered.

SQL> alter database flashback off;

Database altered.

SQL> drop restore point BEFORE_CHANGE;

Restore point dropped.

5.2. Sve je u redu, nastavljamo u revijalnom tonu:

SQL> alter database flashback off;

Database altered.

SQL> drop restore point BEFORE_CHANGE;

Restore point dropped.

6. OBAVEZNO!!!! uraditi full backup baze, zato što smo napravili novu inkarnaciju baze sa ALTER DATABASE OPEN RESETLOGS.

Eto, pa vi sad usporedite vrijeme potrebno za restore kompletne baze i vrijeme potrebno da se baza pomoću Flashback tehnologije vrati u prvobitno stanje.


OLAP 11g: Instalacija AWM (Analytic Workspace Manager)

October 23, 2012 – Dejan

Pošto se u zadnje vrijeme intenzivno bavim DWH (Data WareHouse) tehnologijama, odlučio sam isprobati nove OLAP opcije u verziji 11g.

U sklopu toga, krenuh instalirati AWM (Analytic Workspace Manager) prateći uputstvo korak po korak kao što piše u tutorijalu “Building OLAP 11g Cubes“. Downloadao sam i instalirao sve šta je bilo potrebno, ali nisam morao čekati dugo na prvu grešku….

U poglavlju “Creating an Analytic Workspace” fino piše:
Enter Oracle11g in the Description field and <hostname>:1521:<SID> in the Connection Information field and click Create.“, a ja se pravim pametan i umjesto toga, upisujem tnsnames connection string (u mom slučaju DWHTEST). Naravno da nije radilo - dobio sam grešku:
oracle.jdbc.driver.T2CConnection.getLibraryVersionoNumber()

Dakle, ispravih to na localhost:1521:DWHTEST i mogao sam nastaviti dalje…

Čitav proces tekao je glatko dok nisam došao do dijela “Loading and Viewing Cube Data” i koraka “Maintain Cube SALES_CUBE” … E tu su nastale muke…

Konstantno sam dobijao grešku (kod mene na njemačkom jeziku, jer su mi lokalna podešavanja tako postavljena):

INI: Fehler beim Erstellen eines Definition Managers, Allgemein in TxsOqConnection::generic<BuildProcess>INI: XOQ-01600: OLAP-DML-Fehler “ORA-01858: Ein nicht-numerisches Zeichen wurde gefunden, während ein numerisches Zeichen erwartet wurde
” bei der Ausführung von DML “SYS.AWXML!R11_LOAD_MEASURES(’SALES_CUBE.CUBE’  SYS.AWXML!___R11_LONG_ARG_VALUE(SYS.AWXML!___R11_LONG_ARG_DIM 1)  SYS.AWXML!___R11_LONG_ARG_VALUE(SYS.AWXML!___R11_LONG_ARG_DIM 2)  SYS.AWXML!___R11_LONG_ARG_VALUE(SYS.AWXML!___R11_LONG_ARG_DIM 3) ‘NO’)”, Allgemein in TxsOqStdFormCommand::execute

error_maintain_sales_cube

Dole u popisu svih operacija, pored naziva “failed” koraka stoji i nepotpun SQL kôd, tako da ga ne mogu kopirati i izvršiti u SQL Developeru, TOAD-u ili SQL Plusu. I ajd sad ti znaj u čemu je problem !?

E sad na scenu stupa iskustvo - u TOAD-u nađem ovaj session od AWM programa, pokrenem tracing za taj session i opet u AWM kliknem na “Maintain SALES_CUBE”. Očekivano, u trace datoteci sam pronašao kompletan SQL kôd:

PARSING IN CURSOR #46 len=11771 dep=1 uid=91 oct=3 lid=91 tim=215623360605 hv=3267082949 ad=’7ff86cb22c0′ sqlid=’a4nh9jm1brfq5′
SELECT /*+  bypass_recursive_check  cursor_sharing_exact  no_expand  no_rewrite */   T44_CHANNEL_KEY ALIAS_237,   T41_MONTH_ID ALIAS_238,   T38_STATE_PROVINCE_KEY ALIAS_239,   T35_ITEM_KEY ALIAS_240,   SUM(T47_SALES)  ALIAS_241,   SUM(T47_QUANTITY)  ALIAS_242 FROM   (  SELECT /*+  no_rewrite */     T1.”QUANTITY” T47_QUANTITY,     T1.”SALES” T47_SALES,     T1.”DAY_KEY” T47_DAY_KEY,     T1.”PRODUCT” T47_PRODUCT,     T1.”CHANNEL” T47_CHANNEL,     T1.”CUSTOMER” T47_CUSTOMER   FROM     OLAPTRAIN.”SALES_FACT” T1   )   T47,   (  SELECT /*+  no_rewrite */     T1.”CHANNEL_KEY” T44_CHANNEL_KEY   FROM     OLAPTRAIN.”CHANNELS” T1   )   T44,   (  SELECT /*+  no_rewrite */     T1.”DAY_KEY” T41_DAY_KEY,     T1.”MONTH_ID” T41_MONTH_ID   FROM     OLAPTRAIN.”TIMES” T1   )   T41,   (  SELECT /*+  no_rewrite */     T1.”CUSTOMER_KEY” T38_CUSTOMER_KEY,     T1.”STATE_PROVINCE_KEY” T38_STATE_PROVINCE_KEY   FROM     OLAPTRAIN.”CUSTOMERS” T1   )   T38,   (  SELECT /*+  no_rewrite */     T1.”ITEM_KEY” T35_ITEM_KEY   FROM     OLAPTRAIN.”PRODUCTS” T1   )   T35 WHERE   ((T47_CHANNEL = T44_CHANNEL_KEY)     AND (T47_DAY_KEY = T41_DAY_KEY)     AND (T47_CUSTOMER = T38_CUSTOMER_KEY)     AND (T47_PRODUCT = T35_ITEM_KEY)     AND ((T47_DAY_KEY)  IN ((TO_DATE(’06-FEB-2010′) ) , (TO_DATE(’20-JAN-2010′) ) , (TO_DATE(’14-NOV-2010′) ) , (TO_DATE(’21-APR-2010′) ) , (TO_DATE(’02-APR-2010′) ) , (TO_DATE(’11-JAN-2010′) ) , (TO_DATE(’29-JAN-2010′) ) , (TO_DATE(’27-JUN-2010′) ) , (TO_DATE(’30-NOV-2010′) ) , (TO_DATE(’11-AUG-2010′) ) , (TO_DATE(’30-JAN-2010′) ) , (TO_DATE(’25-JAN-2010′) ) , (TO_DATE(’26-NOV-2010′) ) , (TO_DATE(’26-OCT-2010′) ) ,
– … ostatak obrisan radi preglednosti …
(TO_DATE(’21-JAN-2010′) ) , (TO_DATE(’02-JUN-2010′) ) , (TO_DATE(’14-JUN-2010′) ) , (TO_DATE(’16-MAR-2010′) ) , (TO_DATE(’27-JUL-2010′) ) , (TO_DATE(’27-MAR-2010′) ) , (TO_DATE(’22-NOV-2010′) ) , (TO_DATE(’19-SEP-2010′) ) ) ) )  GROUP BY   (T35_ITEM_KEY, T38_STATE_PROVINCE_KEY, T41_MONTH_ID, T44_CHANNEL_KEY)  ORDER BY   T35_ITEM_KEY ASC NULLS LAST ,   T38_STATE_PROVINCE_KEY ASC NULLS LAST ,   T41_MONTH_ID ASC NULLS LAST ,   T44_CHANNEL_KEY ASC NULLS LAST
END OF STMT

Obratite pažnju na crveno označeni tekst! Dakle, kopiram čitav SQL upit i pokrenem ga u SQL Plusu. Naravno - greška:

sqlplus_ora-01858
Prva asocijacija je odmah bila na drugačije NLS postavke, jer su ovdje vrijednosti hardkodirane u formatu DD-MON-YYYY (hardkodiranje bez format maske je idiotski!! čisti amaterizam!!).

Prvo sam pokušao sa “AFTER LOGON ON DATABASE” triggerom postaviti NLS_DATE_FORMAT na DD-MON-YYYY, ali nije dalo očekivani rezultat…
Potom sam u registry promijenio NLS_LANG na AMERICAN_AMERICA.AL32UTF8, no ni to nije dalo rezultat…

Čak mi ni moj prijatelj Google nije pomogao :-(

Međutim!!!! (sad malo dramaturgije uz zvuke fanfara…)

Daaaaavno sam se nešto bio patio sa JDeveloperom i u podsvijesti mi je sinula ideja sa dodatnim Java parametrima za AWM! Naime, u direktorijumu gdje je instaliran AWM, nalazi se i datoteka awm.bat. E u toj datoteci se nalazi slijedeća linija:

start javaw -mx1024m -jar awm11.2.0.3.0.jar

Dodao sam opcije -Duser.language=en -Duser.country=US, tako da je ta linija izgledala onda ovako:

start javaw -mx1024m -Duser.language=en -Duser.country=US -jar awm11.2.0.3.0.jar

Pokrenuo sam AWM, kliknuo na “Maintain SALES_CUBE” i sve je prošlo bez ijedne greške!!! Mojoj sreći nije bilo kraja…

Dakle, ovu grešku vjerovatno većina “english speaking” korisnika neće nikad dobiti, a nas non-english ko **** …


SQL Developer: instalacija na Windows 7 64-bit : problemi i rješenja

October 20, 2012 – Dejan

Na jednom od kompjutera sa instaliranim Windows 7 64-bit, morao sam instalirati Oracle 11gRel2 i SQL Developer. Pošto uz instalaciju baze standardno dolazi i SQL Developer, pomislio sam da neće biti potrebno ništa dodatno podešavati - ali, avaj, grdno sam se prevario…

Prvo je bilo potrebno podesiti lokaciju za java.exe, a onda se pojavila greška “Could not find jvm.cfg!”, odnosno “Unable to find a Java Virtual Machine“… Na svu sreću, otprije mi je poznat problem sa 32-bit i 64-bit nekompatibilnosti, pa sam skinuo ispravnu verziju Jave (trenutno JDK 7u9) i SQL Developera (trenutno verzija SQL Developer 3.2.1).

Naravno, tu nije bio kraj mukama. Nakon što se instaliraju Java i SQL Developer, prilikom pokretanja SQL Developera se pojavila greška “The program can’t be startet, the MSVCR100.dll is missing on the computer“. E, ovu grešku sam prvi put vidio.

Pošto je Google moj najbolji prijatelj, tako mi je pomogao i ovaj put. Rješenje je kopirati taj msvcr100.dll iz direktorija <Java install>\jdk1.7.0_09\bin\ u direktorij <SQL Developer install>\sqldeveloper\sqldeveloper\bin\ i to je to.


Oracle SQL Developer: problem sa memorijom “Java heap space”

October 4, 2012 – Dejan

Lično ne koristim Oracle SQL Developer, ali dosta PL/SQL programera kod mene u firmi koriste ovaj alat i žale se, da imaju problema pri radu sa većom količinom podataka ili sa većim datotekama. Ugnjavili su me da im pomognem, tako da sam testirao razna podešavanja parametara za SQL Developer i došao do rješenja.

U dva odvojena bin direktorija (kod mene se nalaze ovdje: C:\Program Files (x86)\Oracle\SQLDeveloper\sqldeveloper\bin\ i C:\Program Files (x86)\Oracle\SQLDeveloper\ide\bin\) se nalaze dvije datoteke za konfiguraciju GUI/IDE interfejsa za SQL Developer: ide.conf i sqldeveloper.conf.

Potrebno je postaviti/promijeniti slijedeće parametre:

C:\Program Files (x86)\Oracle\SQLDeveloper\ide\bin\ide.conf:

AddVMOption  -Xms512M
AddVMOption  -Xmx512M

C:\Program Files (x86)\Oracle\SQLDeveloper\sqldeveloper\bin\sqldeveloper.conf:

AddVMOption -XX:MaxPermSize=512M
AddVMOption -Dsun.awt.keepWorkingSetOnMinimize=true
AddVMOption -Dsun.java2d.noddraw=true
AddVMOption -XX:+UseCompressedOops
AddVMOption -XX:+AggressiveOpts
AddVMOption -XX:+UseConcMarkSweepGC
AddVMOption -XX:+UnlockExperimentalVMOptions
AddVMOption -XX:+UseG1GC
AddVMOption -XX:+G1YoungGenSize=25m
AddVMOption -XX:+G1ParallelRSetUpdatingEnabled
AddVMOption -XX:+G1ParallelRSetScanningEnabled

Ako imate dovoljno RAM memorije, onda umjesto 512M postavite 1024M.