Dozvola za ubijanje (sesija)

March 11, 2010 – Dejan

Ne prođe skoro nijedan dan, a da me barem jedan programer ne gnjavi da mu ubijem zablokiranu sesiju. Pošto nemam baš vremena da se cimam i oko toga, odlučio sam da svakom programeru dozvolim ubijanje vlastitih sesija.

Takođe ne volim otkrivati toplu vodu, pa sam za ovaj problem malo proguglao i našao sasvim zadovoljavajuće rješenje od Toma Kyte-a, a ono izgleda ovako:

1. svakom programeru dodijeliti privilegiju, da može selektovati potrebne podatke iz v_$session (sid, serial#):

grant select on v_$session to programer;

2. Ako već nemate nekog “poweruser” korisnika (”non-SYS user with a DBA role“), onda kreirajte jednog, pa s tim korisničkim nalogom kreirajte jednu proceduru, koja će ubijati željenu sesiju:

create or replace procedure poweruser.kill_session( p_sid     in number,
                                                    p_serial# in number)
  is
      ignore          pls_integer;
  BEGIN
      select count(*) into ignore
        from V$session
       where username = USER
         and sid = p_sid
         and serial# = p_serial#;

      if ( ignore = 1 )
      then
          execute immediate '
              alter system kill session ''' ||
              to_char(p_sid,'999999')||','||
              to_char(p_serial#,'999999')||'''';
      else
          raise_application_error( -20001,
                                 'You do not own session ''' ||
                                  p_sid || ',' || p_serial# ||
                                 '''' );
      end if;
  END;
  /

3. dozvolite izvršavanje te procedure svim programerima:

grant execute on kill_session to programer;

To je to - nema više svakodnevnog cimanja u vezi ubijanja sesija.


Sertifikati + praksa + redovno usavršavanje = bolji posao

March 5, 2010 – Dejan

Ko kaže da se pored prakse sertifikati i usavršavanje u kontinuitetu ne isplate?

Meni su se već u prošlosti isplatili, a sad evo opet. Naime, kao što sam već par puta napominjao, dobio sam par zanimljivih ponuda za posao, pa sam odabrao jednu, koja mi jamči odgovorniju, zanimljiviju i bolje plaćenu poziciju, tzv. “do penzije ovako - gdje da potpišem”. :)

Ostajem u sklopu Erste banke, ali prelazim u drugu kćerku-firmu pod nazivom “Erste Asset Management”, koja se bavi finansijskim menadžmentom, odnosno upravljanjem uloženog kapitala privatnih i pravnih lica - ukratko fondovi, akcije i sve ostalo što ide uz berzu.

Biću glavni i odgovorni za administraciju Oracle baza i za koordinaciju development tima, uključujući pisanje tehničke projektne specifikacije i obučavanje programera.

Osim dobre finansijske ponude, odobren mi je i budžet za daljnje usavršavanje i sticanje sertifikata, jer sam se pokazao dobrim i nesebičnim u prenošenju novostečenog znanja (iz prakse, sa Oracle kurseva i iz stručne literature) manje iskusnim kolegama.

Ukratko - finansijsko i vremensko ulaganje u usavršavanje svog znanja se nadasve isplati!

Nažalost, nova pozicija će mi oduzimati i mnogo vremena, tako da neću moći aktivno pisati na blogu (eh, kao da sam i do sada pisao nešto pretjerano aktivno ;) ), ali gledaću da s vremena na vrijeme ubacim neki koristan tekst.

A sad u nove radne pobjede!


ISIN validation code in PL/SQL

February 22, 2010 – Dejan

ISIN = International Securities Identification Number http://en.wikipedia.org/wiki/International_Securities_Identification_Number

CREATE OR REPLACE FUNCTION sfCheckISIN(pISIN IN VARCHAR2) RETURN NUMBER
IS
  s number := 0;
  a number;
  c number;
begin
  a := case length(pISIN) when 12 then 1 else 2 end;

  for i in reverse 1..length(pISIN) loop
    c := ascii(substr(pISIN, i, 1));
    if c > ascii('9') then
        c := c - (ascii('A')-10);
        s := s + trunc((3 - a) * trunc(c / 10) + a * c + (a - 1) * (trunc(mod(c,10))) / 5);
    else
      c  := c - ascii('0');
      s :=  s + (a * c + (a - 1) * trunc(c / 5));
      a := 3 - a;
    end if;

  end loop;

  s := trunc(mod(s, 10));

  return trunc(mod(10 - trunc(mod(s, 10)), 10));

end sfCheckISIN;
/

Oblikujte novi Oracle Forms builder

February 4, 2010 – Darko

Nedavno je na Oracle-ovom forumu pokrenuta tema na kojoj možete predložiti šta bi bilo dobro da se doda u Oracle Forms.

http://forums.oracle.com/forums/thread.jspa?threadID=1021732&start=0&tstart=0

Na ovaj način je ljudima koji koriste ovaj alat je data sjajna prilika da oblikuju narednu verziji Forms-a.
Naravno, neće se svaki predlog prihvatiti, ali vrijedi pokušati…

Lično, prve stvari koje su mi pale na pamet su

- dodavanje kalendarčića ( ovo trenutno radim preko Java binova, ali bi bilo puno bolje imati neki gotovi formsov objekat )
- poboljšanje editora PL/SQL-a ( trenutni editor je više nego smiješan. Čak kada razmislim - ne znam za gori )
- ugrađena podrška za webutil ( nepotrebno zakomplikovano )

- bolje odrađena podrška za slike ( slike importovane preko Image item-a su neprihvatljivo loše )

- bolje urađena podrška za kreiranje i importovanje Java binova ( nepotrebno zakomplikovano, bez ozbiljnog modula u samom IDE-u koji bi developerima pomogao pri kreiranju binova )

- veća sloboda pri kreiranju i oblikovanju data blokova. ( Npr. da se može zadati upit na osnovu kojeg će se u run time-u izgenerisati data blok ( ok, koji bi bio read-only ) . Npr. kao data grid koji imamo u BCB-u, .NET-u… .)

Naravno, ima još toga čime bi se trebalo pozabaviti u formsu, kao što je npr. debugger, VCS , prelaženje sa aplet aplikacija na ajax aplikacije , standardizacija IDE-a itd i još dosta dosta toga…

Dakle, ko ima ideje - neka predloži…


Oracle okončao akviziciju Sun-a

January 27, 2010 – Dejan

Nakon zabrinute diskusije oko budućnosti Sun-a, a samim tim Solarisa, Jave i MySQL-a, Larry je stavio tačku na “i” i najavio pozitivni razvoj postojećih tehnologija i proizvoda u sklopu Sun-a, što bi trebalo unijeti malo optimizma glede opstanka dotičnih, te ukloniti strahove i strepnje unutar Open Source zajednice. Usputno je Larry najavio IBM-u borbu na području hardware-a.

sun_customers_lg


FormatOracle2Excel - Kako prebaciti podatke iz Oracle baze u Excel

November 24, 2009 – Dejan

… a da podaci budu uredno posloženi u odgovarajućem formatu, sa raznim bojama, linkovima i sl. karakefama !?

Vjerujem da ste mnogo puta pravili export podataka u CSV formatu (Comma Separated Values) namijenjenih za korištenje u Excelu, a da su vaši korisnici često priželjkivali podatke u određenom formatu ili sa nekom bojom u pozadini.
Da li ste od onih, koji su svojim korisnicima odgovarali: “Nažalost, tehnički to nije moguće…” ?

Ako je tako, onda ćete nakon čitanja kompletnog teksta moći taj odgovor promijeniti u :”Naravno da je moguće! Recite nam samo, kakav format želite i koje boje da uzmemo? Želite li podatke odvojene u više tablica (sheets) ? Da Vam pošaljemo Excel datoteku na email ili da bude prikazana direktno u browseru? Nema problema - sve se može obaviti!!

Pročitaj kompletan tekst »


REF CURSOR IN and OUT

November 10, 2009 – Noctua4u

Obećao jesam nastavak o tipovima, ali obzirom da sam zatrpan nekim poslovima, ne stižem da dovršim započeto. Lepa stvar je što sam u tim poslovima naučio nešto novo, naravno na ličnim greškama i PIG metodom (metoda Probe I Greške), što se “nadovezuje” na priču o tipovima.

Naime, nedavno sam dobio zadatak da prebacim podatke sa jedne Oracle DB na drugu Oracle DB. Obzirom da se serveri fizički “ne vide”, tj. nisu na istoj mreži, to je nametalo neka rešenja. Takođe, neki od “projektnih zadataka” su takođe uticali na izbor načina prenosa i obrade tih podataka.

Najlogičniji pristup (sa aspekta DBA) koji odgovara svim uslovima je bio:

  1. Na SOURCE bazi spakuj podatke u neki RECORDSET koji će preko jedne stored procedure da bude dostupan klijentu
  2. Klijent preuzima podatke i samo ih prosleđuje ih drugoj bazi
  3. Na TARGET bazi bazi prihvati podatke, isti RECORDSET, isto stored procedurom i obradi ih (i na kraju upiši u odgovarajuće tabele)

Krajnje jednostavno, ne?
E, ne! Sa stane developera nemoguć posao!
Da kratim priču, zbog ograničenja “klijentske arhitekture” susrećemo se sa REF CURSOR-ima.

Šta je REF CURSOR?

Treba praviti razliku između kursora (CURSOR) i kursorske varijable ili kursorske promeljive (REF CURSOR). Kursorska varijabla ukazuje na trenutni red (ROW) u skupu podataka koji se dobija izvršenjem nekog upita. Kursorska varijabla {u daljem textu CVR} je fleksibilnija jer nije vezana za određeni upit (kao CURSOR), već se može koristiti više puta za različite upite.
CVR se može tretirati kao pointer.

Zašto koristiti REF CURSOR?

Logično pitanje koje se nameće iz definicije CVR je: zašto bih koristio REF CURSOR kada mogu da koristim CURSOR ili neki strogo definisani skup podataka ili neki moj tip?
Odgovori su mahom vezani za koncepciju manipulaciju i strukturu podataka:

  • Rad sa različitim upitima u različito vreme korišćenjem samo jednog CVR-a. Drugim rečima, jedna CVR se može koristiti za “sakupljanje” podataka iz različitih upita.
  • Kada želimo da izvršimo upit u jednom programskom modulu (procedura, funkcija) i procesuriramo rezultate u drugi podprogram (najčešće pisan u drugom jeziku!) na klijentu. Vidi sliku.
    REFCURSOR
  • Ukoliko postoji PL/SQL engine na strani klijenta nema restrikcija u komunikaciji između klijenta i servera. Npr. možete deklarisati CVR na strani klijenta, otvoriti je i popuniti podacima na strani servera, vratiti klijentu, nastaviti “popunjavanje” na strani klijenta, vratiti serveru da je zatvori itd. Moguće su sve kombinacije.

Posebno je potrebno obratiti pažnju na deo “pisan u drugom jeziku”, videćemo posle i zašto.

Deklaracija REF CURSOR tipa i kursorske varijable (promenljive):

DECLARE
TYPE RFC_Slab IS REF CURSOR; -- Deklarisanje TIPA kursora (slab tip)
TYPE RFC_Jak IS REF CURSOR RETURN odeljenja%ROWTYPE; -- Deklarisanje TIPA kursora (jak tip)
in_cursor RFC_Slab; -- Deklaracija CVR
out_cursor RFC_Jak; -- Deklaracija CVR
BEGIN
OPEN in_cursor FOR SELECT * FROM gradovi;
OPEN out_cursor FOR SELECT * FROM odeljenja;
END;

JAK TIP REF CURSORA ima u deklaraciji RETURN neka_tabela%ROWTYPE što označava kako mora da izgleda u trenutku deklaracije. To praktično znači da bilo koji SQL upit, koji koristi CVR, mora da vrati strukturu (kolone) kao što je ima neka_tabela. O prednosti jakog tipa nad slabim nećemo ovom prilikom, ali jedna od njih je i ta što komplajler može da odredi da li je developer ispravno “upario” podatke iz CVR-a.

SLAB TIP onaj koji nije vezan za neku strukturu podataka i može se koristiti sa bilo kojim upitom.

Ograničenja REF CURSORA (CVR):

Veoma bitno je znati šta NE možete raditi:

  1. CVR se ne može deklarisati u paketu (nema stvarnu vrednost već je samo “pointer” na nešto što će se kasnije koristiti). Deklariše se samo TIP podataka kao REF CURSOR!
  2. Ne može se prosleđivati preko Remote Procedure Calls (zaboravite DB link) sa jednog na drugi server
  3. Ukoliko se prosleđuje kao “bind” ili host varijabla u PL/SQL, ne može se uraditi FETCH na serveru ukoliko CVR nije otvorena u istom pozivu (Praktično: da bi stored procedura mogla da koristi podatke koje joj šaljete u REF CURSORu, morate u okviru poziva i da ga otvorite!)
  4. Ne može se testirati jednakost, nejednakost ili da li je NULL pomoću operatora komparacije.
  5. Ne može se dodeliti NULL vrednost CVR
  6. Kolone ne mogu biti tipa RFC (u CREATE TABLE/VIEW ne možete staviti tip REF CURSOR. Takođe, ništa VARRAY i ostali tipovi)
  7. Ne mogu se koristiti u dinamički generisanom SQL-u

Evo još nekih stvari koje su bitne za REF CURSOR a koje NE možete:

  1. Iz klijentskih jezika ne možete prihvatiti nikakve podatke ukoliko nisu u REF CURSORu (zapravo, ponekad i možete, ali to zahteva mnogo više akcija nego kod REF CURSOR-a)
  2. Ne možete da “prosledite” REF CURSOR natrag u bazu!!! (php, java, perl provereno, a za .Net i ostale samo pročitao u dokumentaciji)

Upotreba REF CURSOR-a kao IN/OUT parametra

Znači, ukoliko morate da, npr. “napunite TREE” komponentu na strani klijenta, neki logičan sled bi bio:

  • Pripremite podatke (CONNECT BY PRIOR možda?)
  • Smestite ih u REF CURSOR
  • Iz klijentskog jezika pozivate neki modul (funkcija, procedura…) koji vam isporučuje podatke
  • Dalje radite sa njim (menjate čvorove, potege, veze, šta-god..)

Šta ako baš, baš, morate da pošaljete podatke nazad u bazu (recimo, gore pometnuti TREE koji je izmenjenog oblika)??

Odgovor je jednostavan: NE MOŽE!

Mada…

Evo malog trika koji je primenljiv nad jednom konekcijom u ISTOJ bazi (uzimamo u obzir treću stavku iz dela Zašto koristiti REF CURSOR). Pretpostavimo da ste u okviru paketa deklarisali REF CURSOR i proceduru koja “prihvata” REF CURSOR.

create or replace package test_Pkg as
type cur_test is REF CURSOR;
end test_Pkg;

create or replace procedure testSP(param1 IN test_Pkg.cur_test, param2 OUT NUMBER)
as
begin
FETCH param1 into param2;
-- Mozda insert into neka_tabela... sta god...
end;

Uzimajući u obzir sve gore pomenuto u kodu je moguće uraditi sledeću stvar (kod nije prilagođen jeziku već je samo opisan postupak):

...
# Prethodni otvaranje konekcije i podesavanje parametara
#
# Pripremamo kod za izvrsenje
cmdTxt1 = "begin open :1 for select * from neka_tabela; end;";
# U zavisnosti od jezika se radi BIND za cmdTxt1
# nakon BIND-a, a u zavisnosti od jezika
conn.execute(cmdTxt1);
# Ovim smo otvorili kursor na strani klijenta!!!
# Radimo nesto sa tim podacim
...
# pripremamo kursor za povratak u Bazu
cmdTxt2 = "begin testSP (:1, :2); end;";
# pri cemu bind prvog parametra predstavlja obradjeni REF CURSOR!!!
conn.execute(cmdTxt2);
...

Da ponovim, nije moguće prosleđivati REF CURSOR među bazama! Na meta-linku sam pročitao da je postavljen zahtev za tom mogućnošću u JDBCu… da li će i kada će biti… videćemo.

Do tada, nadam se da će vam ovaj “trik” pomoći.


Oracle ROWNUM

October 19, 2009 – Darko

Kada bi vas pitali da razmislite I navedete koja je to bila najmanja i najtrivijalnija stvar koja je vašim kolegama i vama prilikom pisanja upita stvarala nevolje koje su obrnuto proporcionalne njenoj veličini, šta bi odgovorili?

Pa…?

Evo dok razmislite, ja ću reći šta bih ja odgovorio da ste me isto pitali prije par dana dok sam radio paginaciju u jednoj web aplikaciji: “ rad sa rownum-om!”.

Postoji li nešto što vas je više navelo na pomisao kako  u potpunosti shvatate šta znači i kako se sa tim radi, kao što je slučaj sa rownum-om, kada ga prvi put vidite?
A na kraju uhvatite sebe kako ne možete da shvatite zašto vaš najjednostavniji mogući upit ne radi kada upotrebljavate ovu riječ?

Ma ustvari , rownum i jeste izuzetno jednostavna stvar ali  zna da pravi velike probleme ljudima koji ne uđu u srž prirode ove pseudokolone…

Šta je rownum?

Rownum je upravo to  - pseudo kolona. Kolona koja ne postoji fizički u bazi već je RDBMS dinamički dodaje selektovanim kolonama dobijenih upitom , jedinstveno označavajući svaki od dobijenih redova autoinkrementirajućim brojem.

Kada i kako upotrebljavati rownum?

Rownum je sjajna funkcionalnost Oracle RDBMS-a ( naravno , slične i iste funkcionalnosti imaju i druge baze ) koja ima mnogo primjena.
Dvije vjerovano najveće primjene su prilikom

-    Prikazivanja N top vrsta u nekom upitu
-    Kreiranje paginacije u web aplikacijama

Implementacija paginacije u jednoj web aplikaciji me je upravo i navela da napišem ovaj tekst. Dakle, trebalo je izvesti da se klikom na strelicu navigatora , npr. udesno, selektuje samo N kolona , počevši od K-tog reda nekog upita.

Da vidimo kako bi to izgledalo. Recimo da je N=10 , a K=31.
Ono što nama treba je, svakako:

Select * from moja_tabela where rownum between 31 and 40;

Ovaj upit, naravno, vraća  0 vrsta.
Ali postavlja se pitanje zašto vraća nula vrsta?

Zašto npr. upit

Select * from moja_tabela where rownum < 10

vraca rezultat – 9 prvih vrsta.

a upit

Select * from moja_tabela where rownum > 10

ne vraca nista ( iako u rezultatu postoji vise od 10 vrsta )?

Da bi to znali, vratimo se na priču o prirodi rownum-a.

Rownum se prilikom izvršavanja upita vezuje ( ali se ne setuje odmah ) za vrstu  prije ispitivanja uslova i bilo kakvog sortiranja, i vrlo je važno znati da:

1.    Prva vrsta uvijek ima rownum = 1
2.    Rownum se dalje inkrementira tek nakon što je uspješno setovan u početnoj/prethodnoj vrsti.

Zbog ovoga npr. upit

select * from moja_tabela where rownum = 2

nikada neće vratiti rezultat. Šta se dešava: upit će selektovati prvu vrstu, i provjeriti da li je 1 = 2. Ovo nije tačna tvrdnja i rownum se neće inkrementirati, niti će se prva vrsta selektovati. Prema tome, ni jedna naredna vrsta neće ispunjavati ovaj uslov.

Isto je i za upit

Select * from moja_tabela where rownum > 10

Ali zato, ako kažemo

Select * from moja_tabela where rownum < 2

selektovaće se prva vrsta iz tabele moja_tabela, provjeriće se da li je 1 < 2. Pošto je ova tvrdnja istinita i vrsta će se selektovati a rownum će joj se setovati na 1.
Rownum se zatim inkrementira ( pošto je uspješno setovan ) i tako dalje za sljedeću vrstu…

Zbog ove osobine ćete sresti dosta ljudi koji tvrde da se sa rownum-om ne mogu selektovati bilo koje vrste iz upita, već samo prvih N , upotrebljavajući “where rownum < N “.

Dakle, kako ovo prevazići?

Veoma lako!
Podupitom!

Jednostavno:

Select * from
(
Select moja_tabela.* , rownum as vrsta from moja_tabela
)
where vrsta > 2

Dodijelimo alijas koloni rownum, selektujmo je sa originalnim upitom i onda profiltrirajmo rezultat.

Takođe, kada se radi o npr. grupisanju (sjećate li se, dodjela rownum-a se vrši prije grupisanja pa se može desiti da je rownum totalno izmješan nakon grupisanja ) , vrlo je važno znati postaviti stvari po pravom redoslijedu.
Npr:


select * from
(
Select a.*, rownum as vrsta from
(
Select *  from moja_tabela order by id asc
) a
)
where vrsta > 2

Kao sto sam na početku rekao, zaista se radi o “najmanjoj i najtrivijalnijoj stvari” , ali i kao takva zna da stvori nevolje i otvori pitanja…
Do prije paginacije nisam ni ulazio mnogo u razmišljanje o ovoj temi. Možda jer nikad ranije nisam imao potrebu pisati upite sa rownum-om osim sa “where rownum = 1“ ili “where rownum < N“…
Međutim, kada su problemi počeli da se pojavljuju, ispalo je da rad sa rownum-om baš i nije kakav sam zamišljao da jeste…
E sad, da li je ovo moglo biti urađeno malo jednostavnije za upotrebu – mislim da jeste…
Po meni, provjera uslova „where rownum > N“ se trebao implementirati onako kako korisnik zamišlja da treba da radi: da se svi uslovi isprovjeravaju, sve se izgrupiše pa tek onda selektuju vrste na osnovu ovog uslova… Ipak bi  ( po meni ) rownum trebao biti tu samo da “izbroji” vrste koje smo željeli selektovati.

I, kakav bi bio vaš odgovor na početno pitanje?


Transparent Gateway problem: Oracle NUMBER -> MS SQL DECIMAL

October 16, 2009 – Dejan

Ovih dana smo imali jedan neočekivan problem prilikom prebacivanja podataka iz Oracle baze preko Transparent Gateway-a u jednu MS SQL Server bazu. Pojavljivala se nejasna greška:

ORA-28500: connection from ORACLE to a non-Oracle system returned this message

Pošto je sam tekst greške uopšten i ne prikazuje njen stvarni uzrok, izgubio sam nekoliko sati dok nisam otkrio u čemu je problem… A otkrio sam sasvim slučajno šta je uzrokovalo tu grešku, posmatrajući u debugging režimu podatke, koji se šalju MS SQL Serveru…

Naime, jedna od naših aplikacija se vrti na Windows platformi, gdje su lokalna podešavanja naštimana za njemački jezik (GERMAN_AUSTRIA.WE8MSWIN1252). Ta aplikacija se spaja na Oracle bazu sa podešavanjem AMERICAN_AMERICA.AL32UTF8, uzima određene podatke i preko TG4MSQL (Transparent Gateway for MS SQL) prebacuje ih u MS SQL Server bazu. Sve je radilo savršeno dok u igru nisu došli brojevi sa decimalama (npr. 104,589). Kada se pošalje cijeli broj (npr. 104), onda je sve u redu… MS SQL Server je bio podešen na AMERICAN_AMERICA.WE8MSWIN1252.

Posumnjao sam da MS SQL Server, tj. Transparent Gateway, ne prepoznaje decimalni separator kako treba… Pokušao sam simulirati drugačiji decimalni separator sa
TO_NUMBER(kolona,’999999999999999D999999′,’NLS_NUMERIC_CHARACTERS=”.,”’)
i sa
EXECUTE IMMEDIATE ‘alter session set NLS_NUMERIC_CHARACTERS=”.,”’;
, ali nije donijelo pozitivan rezultat…

Nakon googleanja i metalinkovanja uspio sam pronaći putokaz, koji me doveo do rješenja.

Ključni parametar, koji se mora podesiti u konfiguracijskoj init.ora datoteci (%ORACLE_HOME%\tg4msql\admin\initExampleMSSQL_SID.ora) je HS_LANGUAGE !

Nakon što sam taj parametar podesio na:

HS_LANGUAGE=AMERICAN_AMERICA.WE8MSWIN1252

mogli su se prebaciti i decimalni brojevi, a greška se više nije pojavljivala…


Ponuda za posao (Beč, Austrija): Oracle Database Administrator

October 9, 2009 – Dejan

U zadnje vrijeme sam dobio nekoliko zanimljivih ponuda za posao, od kojih sam jednu prihvatio, tako da uskoro prelazim u drugu firmu (u sklopu Erste banke u Austriji). Od preostalih firmi sam zamoljen da se raspitam, ima li još kandidata za poziciju Oracle DBA, pa ako je neko zainteresovan da radi u Beču kao Oracle DBA, neka mi se javi. Trenutno je ova ponuda najzanimljivija:

Naziv firme: Vienna Insurance Group (Wiener Städtische -  http://www.wienerstaedtische.at/ , http://www.wienerstaedtische.com/group/unternehmen/konzernstruktur/)
Mjesto: Beč
Pozicija: Oracle DBA
Vrsta zaposlenja: interno na neodređeno vrijeme
Plata: 4 000 - 4 500 EUR bruto mjesečno (14 puta godišnje) + jednom godišnje bonus u iznosu jedne mjesečne plate, znači ukupno 15 plata godišnje
Uslovi: min. 2 godine radnog iskustva, solidno znanje njemačkog jezika, radna viza za Austriju

Zainteresovani neka mi pošalju svoj CV na njemačkom jeziku na adresu dejanATbaze-podataka.net.

Edit (04.11.2009.): Mjesto je popunjeno, hvala svima, koji su se javili…