Oracle functionality

Z PostgreSQL
Skočit na navigaci Skočit na vyhledávání

V jednu chvíli to vypadalo, že se vývojáři snaží z PostgreSQL udělat kopii Oracle. Do PostgreSQL naimplementovali řadu NON ANSI funkcí, které nabízí Oracle. Tato doba je ale již minulostí. Do distribuce se funkce, která není definovaná ANSI SQL, prakticky nemá šanci dostat. Řešením je použití EnterpriseDB, která má za cíl kompatibilitu s Oraclem, nebo použití doplňujícího balíku funkcí Orafce. Kromě řady základních uživateli PostgreSQL požadovaných funkcí obsahuje také část frameworku PLVision, a balíčky dbms_alert, dbms_output a dbms_pipe. Cílem není plná kompatibilita s Oraclem, to ani není technicky možné, ale rozšíření PostgreSQL o pokročilé funkce, které nabízí RDBMS Oracle. Řadu příkladů můžete nalézt v dokumentu Napište si debugger PL/pgSQL aneb pokročilé techniky programování v PostgreSQL.

Základní funkce

Funkce pro práci s typem date

Většina těchto funkcí má jako jeden z parametrů období, které je určené znakovým kódem z následující tabulky:

  SELECT add_months(date '2005-05-31',1);  -- > 2005-06-30
  SELECT last_day(date '2005-05-24');      -- > 2005-05-31
  SELECT next_day(date '2005-05-24', 'monday'); -- > 2005-05-30
  SELECT months_between(date '1995-02-02', date '1995-01-01'); -- > 1.0322580645161
  SELECT trunc(date '2005-07-12', 'iw');   -- > 2005-07-11
  SELECT round(date '2005-07-12', 'yyyy'); -- > 2006-01-01


Y,YY,YYY,YYYY,SYYY,SYEAR rok
I,IY,IYY,IYYY iso rok
Q, kvartál
WW týden, první den v týdnu odpovídá prvnímu dnu v roce
IW týden, prvním dnem je pondělí
W týden, prvním dnem je první den v měsíci
DAY,DY,D týden, první dnem v týdnu je neděle
MONTH,MON,MM,RM měsíc
CC,SCC století
DDD,DD,J den
HH,HH12,HH24 hodina
MI minuta

Funkce round zaokrouhluje na 1. července pro roční období, 16-tý den pro měsíc a čtvrtek pro týden.


add_months(date, integer) date Přičte n měsíců
last_date(date) date Vrací poslední den v měsíci
next_day(date, text) date Vrací první následující den v týdnu po určeném dnu, např. první následující čtvrtek
months_between(date, date) float8 Vrací počet měsíců mezi dvěma dny. Výpočet je založen na měsíci s 31 dny.
trunc(date, text) date Ořízne datum podle zadaného formátu
round(date, text) date Zaokrouhlí datum podle zadaného formátu

Byla provedena verifikace těchto funkcí s Oraclem 10i.

Funkce nlssort

PostgreSQL nyní umožňuje třídit pouze podle jednoho, předem vybraného, pravidla. Toto omezení by mělo být odstraněno ve verzi 8.2 se zavedením tzv. COLLATE. Do té doby můžete použít funkci nlssort, která umožňuje použít další pravidla (předpokladem je nainstalování požadované národní podpory (locales)). Funkci můžeme volat buďto s parametrem určujícím pravidlo pro třídění, nebo tento parametr nastavit předem voláním funkce set_nls_sort. Funkci nlssort pracuje korektně, pouze když používáte locales s relevantním kódováním. Je chybou mít data v kódování latin2 a třídit podle německého locales s kódováním latin1. Naopak je korektní používat české i německé řazení s kódováním UTF8. Pro tuto funkci se použil kód Jana Pazdziory z balíčku nls_string.

 SELECT * FROM peoples ORDER BY nlssort(surname, 'de_DE.UTF-8');
 SELECT set_nls_sort('cs_CZ.UTF-8');
 SELECT * FROM peoples ORDER BY nlssort(surname);

Funkce pro práce s řetězci

Tyto funkce byly do balíku zahrnuty jen s účelem zjednodušit portování aplikací z Oracle. K těmto funkcím zpravidla existují ANSI SQL ekvivalenty.

instr (text, text, [int[, int]]) Hledá n-tý výskyt vzoru v řetězci
reverse (text) Zrcadlově převrátí řetězec
oracle.substr (text, [int [,int]]) Vrací část řetězce (PostgreSQL popdporuje funkci substr nekompatibilní s Oraclem

Ostatní funkce

Tyto funkce byly do balíku zahrnuty jen s účelem zjednodušit portování aplikací z Oracle. Místo nich používejte univerzálnější a ANSI standardní funkci COALESCE.

nvl (anyelement, anyalement) Vrací první neprázdný parametr
nvl2 (anyelement, anyememet, anyelement) Vrací první neprázdný parametr
concat (text, text) Slučuje řetězce. Oproti operátoru || ignoruje NULL

DBMS_ALERT

Tento balík podporuje asynchronní vyžádanou notifikaci. Funkcionalita je velice podobná PostgreSQL SQL notifikaci realizovanou prostřednictvím příkazů LISTEN/NOTIFY. dbms_alert představuje řešení, které je 100% realizováno na straně serveru, LISTEN/NOTIFY je vyžaduje podporu klientské aplikace (a tudíž jej nemůže použít např. v PL uložených procedurách). Notifikaci si uživatelská session musí vyžádat registrací zpráv, o které má zájem. To je hlavní rozdíl vůči dbms_pipe, což je také řešení intersession komunikace, které je ale broadcast a kde zprávu převezme pouze první session, která se k ní dostane. dbms_alert doručí zprávu všem zaregistrovaným příjemcům. Jinak, dbms_pipe se používá hlavně pro obousměrnou komunikaci mezi dvěma uživatelskými sessions, a dbms_alert pro jednosměrnou komunikaci jedné session s dalšími.

  -- session pavel
  pavel# SELECT dbms_alert.register('ahoj');
  pavel# SELECT * FROM dbms_alert.waitany(NULL);
  
  -- session root
  root# SELECT dbms_alert.signal('ahoj','Gertrudo');

Funkce

dbms_alert.register(name text) Zaregistruje si posílání oznámení o výskytu události name
dbms_alert.remove(name text) Odtraní registraci příjmu oznámení události name
dbms_alert.removeall() Odstraní všechny registrace
dbms_alert.signal(name text, message text) Signalizuje událost
dbms_alert.waitany(OUT name text, OUT message text, OUT status integer, n float8) Čeká max. n sekund na libovolnou signalizovanou událost
dbms_alert.waitone(name text, OUT message text, OUT status integer, n float8) Čeká max. n sekund na signalizovanou událost name
dbms_alert.set_defaults Není implementováno

Událost se signalizuje v okamžiku ukončení transakce, bohužel nikoliv po dokončení transakce, tak jak je to v případě LISTEN/NOTIFY nebo originálního Oracle. V čem může být problém: a) falešná signalizace - je signalizována událost ale není zajištěno dokončení transakce (při výjimce v AFTER TRIGGERu), b) pokud je signalizována změna v datech, tak tato změna ještě nemusí být pro příjemce viditelná (pro tento účel je doporučeno zavolat po funkcích waitany nebo waitone funkci pg_sleep(n) - počkat 0.1 až 1 sec dle zatížení systému). Odložená transakce může mít ještě jeden negativní dopad. Transakce, které opakovaně signalizují libovolnou událost během jedné transakce, mohou pak v okamžiku commitu, zahltit sdílenou pamět. Pokud by docházelo k této situaci, pak zvedněte limity v pipe.h a přeložte znovu knihovnu.

DBMS_OUTPUT

Tento balík zajišťuje v Oraclu notifikaci z PL/SQL. V PostgreSQL můžeme nalézt analogii v příkazu RAISE NOTICE. Na rozdíl od PostgreSQL se jedná o server side řešení, kdy skripty běžící na serveru plní session proměnné. Po dokončení běhu skriptu si klient vyzvedne obsah proměnných a zobrazí je obsluze. PostgreSQL má notifikaci řešenou na úrovni protokolu, kde server posílá na klienta asynchronní zprávu, a je jen na klientu, jestli tuto zprávu zobrazí nebo nikoliv. Pokud by se tento balíček používal pouze pro notifikace, tak pak by pravděpodobně nebyl důvod pro to, ho zahrnout do tohoto frameworku. Kromě notifikace se ale může použít i jako implementace fronty (FIFO) v PL/pgSQL, a to díky tomu, že PL procedury mohou nejen do této fronty zpráv zapisovat, ale mohou z ní i číst (fronta zpráv může docela dobře zastoupit dočasnou tabulku).

  -- new session
  select dbms_output.enable();
  select dbms_output.put_line('first_line');
  select dbms_output.put_line('next_line');
  select * from dbms_output.get_lines(0);

  -- new sesion
  select dbms_output.serveroutput('on');
  select dbms_output.put_line('first_line');

Stejně jako u Oracle je implementována redukce signálů událostí, tj. pokud v rámci jedné transakce signalizujete opakovaně stejnou událost se stejným parametrem (stejný signál), tak se tyto opakující se signály zruší a příjemce získá pouze unikátní signály.

Funkce

dbms_output.enable([buffer_size int4]) Zapíná podporu dbms_output, volitelná buffer_size nastavuje maximální velikost vyrovnávací paměti
dbms_output.disable() Vypíná podporu dbms_output, příkazy put, put_line, new_line nebudou mít žádný efekt
dbms_output.serveroutput(bool) Zapíná požadavek na zobrazení výstupu klientovi, zároveň zapíná podporu dbms_output
dbms_output.put(text) Vloží text do výstupního bufferu
dbms_output.put_line(text) Vloží řádek (text včetně symbolu pro konec řádku)
dbms_output.new_line() Vloží symbol konce řádku
dbms_output.get_line(OUT line text, OUT status int4) Přečte jeden řádek z bufferu. Pokud je buffer prázdný, pak status = 0 nebo status = 1
dbms_output.get_lines(OUT lines text[], INOUT numlines int4) Přečte pole řádku z bufferu. Parametr numlines obsahuje max. počet řádků, pak skutečný počet řádků

UTL_FILE

Tento balíček obsahuje sadu funkcí podporující operace (čtení a záps) s textovými soubory. Do jisté míry kopíruje styl C knihovny pro práci se streamy (FILE) a víceméně obaluje tuto knihovnu. Adresáře ze kterých lze soubory číst nebo zapisovat jsou omezeny a proto je použití knihovny při rozumné konfiguraci bezpečné. API věrně odpovídá Oracle. Pokud se vyskytují rozdíly, tak důvodem je chybějící podpora předávání parametrů referencí v PostgreSQL. Limity jsou stejné. Max. 10 otevřených souborů v rámci jedné session. Textový řádek může být dlouhý max. 32K. Při odhlášení uživatele dochází k ukončení procesu PostgreSQL a tím i k automatickému zavření všech otevřených souborů. Je třeba dbát na explicitní zavírání souborů. Pokud je ukončena funkce, obsahující proměnnou s deskriptorem souboru ztrácíme možnost explicitního zavření souboru. Jediným řešením je spustit funkci utl_file.fclose_all(), která zajistí uzavření všech otevřených souborů v rámci session,

CREATE OR REPLACE FUNCTION read_file(loc text, filename text)
RETURNS SETOF text AS $$
DECLARE
  f utl_file.file_type;
BEGIN
  f := utl_file.fopen(loc, filename, 'r');
  LOOP
    RETURN NEXT utl_file.get_line(f);
  END LOOP;
EXCEPTION 
  WITH NO_DATA_FOUND THEN
    f := utl_file.fclose(f);
    RETURN;
  WITH OTHERS THEN
    IF utl_file.is_open(f) THEN
      f := utl_file.fclose(f);
    END IF;
    RAISE EXCEPTION '%', SQLERRM;
END;
$$ LANGUAGE plpgsql VOLATILE;

Funkce

utl_file.fclose(file utl_file.file_type) file utl_file.file_type Uzavře soubor přiřazený k deskriptoru file a uvolňuje tento deskriptor. V případě úspěchu vrací NULL, což je ekvivalent volného deskriptoru souboru. Pokud používáte funkci is_open je třeba po zavření souboru nastavit proměnnou nesoucí deskriptor souboru na hodnotu NULL.
utl_file.fclose_all() Zavře všechny otevřené soubory v rámci jedné session. Jelikož nemění obsah proměnných nesoucích deskriptory souborů, stane se jejich obsah po provedení tohoto příkazu nekonzistentní (správně by měli obsahovat hodnotu NULL), a nemá smysl používat funkci is_open.
utl_file.fflush(file utl_file.file_type) Zajistí uložení obsahu vyrovnávací paměti na disk.
utl_file.fopen(adresar text, nazev text, rezim text [, max_velradku]) file utl_file.file_type Vrací deskriptor otevřeného souboru. Soubor lze otevřít v režimech "r" čtení, "w" zápis a "a" append. V případě chyby vyvolá výjimku. Tato funkce umožní přístup pouze k souborům z adreářů vyjmenovaných v tabulce utl_file.utl_file_dir.
utl_file.get_line(file utl_file.file_type) text Přečte jeden řádek z textového souboru. V případě, že je řádek delší než nastavený limit (výchozí nastavení 1KB) vyvolá výjimku. Výjimku NO_DATA_FOUND vyvolá také v případě, že je soubor prázdný nebo se již přečetl celý. Vrácený řetězec neobsahuje znak konce řádku.
utl_file.get_nextline(file utl_file.file_type) text Obdoba předchozí funkce. V případě, že se pokoušíte číst z přečteného souboru, vrací NULL.
utl_file.is_open(file utl_file.file_type) boolean Vrací true pokud je descriptor souboru je platný. Ve skutečnosti se neověřuje, zda-li je skutečně file odkaz na platný descriptor souboru pomocí prostředků operačního systému, ale jednoduše se testuje, zda-li proměnná file obsahuje hodnotu NULL nebo nikoliv.
utl_file.new_line(file utl_file.file_type [, radku int]) Vloží symbol pro nový řádek so souboru. Volitelně lze určit, kolik těchto symbolů se vloží.
utl_file.put(file utl_file.file_type, buffer text) Vloží obsah bufferu do souboru. Kontroluje se maximální délka řádku.
utl_file.put_line(file utl_file.file_type, buffer text) Za vložený text přidá ještě symbol nového řádku.
utl_file.putf(file utl_file.file_type, format text, arg1..arg5 text) Vloží formátovaný text. Formátovací řetězec může obsahovat symbol %s, za který se dosadí obsah n-tého parametru. Jejich počet je omezen na pět.

Rozdíly vůči Oracle

  • utl_file.fclose(file utl_file.file_type) .. výsledek je třeba předat do proměnné obsahující desc. souboru
  • utl_file.get_line(file utl_file.file_type) .. vrací text, v Oracle procedura
  • utl_file.get_nextline(file utl_file.file_type) .. stejné jako předchozí funkce, jen v případě EOF vrací NULL (get_line je ukončeno výjimkou NO_DATA_FOUND)

DBMS_PIPE

Funkce z balíčku dbms_pipe umožňují asynchronní intersession komunikaci. PostgreSQL nemá žádný analogický mechanismus, kterým by umožnil přenos dat z jedné session do druhé. Zpráva může být prázdná nebo může obsahovat libovolný počet položek (omezeno velikostí dostupné sdílené paměti). Funkce z tohoto balíčku lze použít k testování (přenos ladících hlášení), k synchronizaci aplikací a také k simulaci architektury klient-server pro PL/pgSQL aplikace. Hlavní rozdíly od služeb dbms_alert, které také zajišťují intersession komunikaci jsou:

  • nedochází k redukci zpráv,
  • nečeká se na dokončení transakce,
  • zprávu získá pouze první příjemnce,
  • zprávy jsou přenášeny binárně v odpovídajících datových formátech (pokud spolu komunikují dvě sessions s rozdílným kódováním, a přenášíte text, je na Vás, abyste si zajistili odpovídající překódování na kódování příjemce)

Podporováno je dělení rour na privátní a veřejné, na explicitně vytvořené a implicitní. S veřejnými rourami může pracovat kdokoliv, s privátními pouze jejich zřizovatel. Pokud odešleme zprávu do dosud neregistrované roury, automaticky se vytvoří implicitní roura. Ta zaniká okamžitě po jejím vyprázdnění. Explicitní roury existují trvale (do explicitního zrušení, nebo do restartu serveru).

  -- Session A
  SELECT dbms_pipe.pack_message(CURRENT_DATE);
  SELECT dbms_pipe.pack_message('Servus, Rupert');
  SELECT dbms_pipe.send_message('boo',4,10);

  -- Session B
  SELECT dbms_pipe.receive_message('boo',4);
  SELECT dbms_pipe.unpack_message_date();
  SELECT dbms_pipe.unpack_message_text();

Oracle dokáže pracovat s proměnnými i referenčně a také dokáže přetěžovat OUT parametry funkcí. To v PostgreSQL není možné, přímo z názvu funkce (vyjímkou jsou record funkce) musí být zřejmý výstupní datový typ. Proto v balíčku je originální funkce unpack_message nahrazena sadou funkcí unpack_message_text, unpack_message_date, unpack_message_timestamp, unpack_message_number, unpack_message_bytea a unpack_message_record. Lze přenášet pouze hodnoty typu record s definovaným typem (viz. příklad).

  CREATE TYPE info AS (x integer, y integer);

  CREATE OR REPLACE FUNCTION send_info(x int, y int)
  RETURNS void AS $$
  DECLARE i info;
  BEGIN i.x := x; i.y := y;
    PERFORM dbms_pipe.pack_message(i);
    PERFORM dbms_pipe.send_message('info');
  END; 
  $$ LANGUAGE plpgsql;

  CREATE OR REPLACE FUNCTION get_info() 
  RETURNS info AS $$
  DECLARE i info;
  BEGIN
    PERFORM dbms_pipe.receive_message('boo');
    SELECT INTO i * FROM dbms_pipe.unpack_message_record() AS (x integer, y integer);
    RETURN i;
  END;
  $$ LANGUAGE plpgsql;

Rozdíly vůči Oracle:

  • Omezení kapacity roury není v bytech, ale v počtu zpráv
  • Můžete poslat zprávu s nulovým timeoutem
  • Můžete poslat prázdnou zprávu
  • Funkce next_item_type může vracet dále TIMESTAMP (13) a RECORD(24)
  • Formát RAW není podporován, místo toho je podpora BYTEA(23)

Funkce

dbms_pipe.pack_message(value text|date|timestamp|numeric|record|bytea) Do lokálního odchozího bufferu přidá obsah.
dbms_pipe.unpack_message_text() text Z lokálního bufferu získá hodnotu typu text.
dbms_pipe.unpack_message_date() date Z lokálního bufferu získá hodnotu typu date.
dbms_pipe.unpack_message_timestamp() timestamp Z lokálního bufferu získá hodnotu typu timestamp.
dbms_pipe.unpack_message_number() numeric Z lokálního bufferu získá hodnotu typu numeric.
dbms_pipe.unpack_message_record() record Z lokálního bufferu získá hodnotu typu record. Pravděpodobně bude nutné provést přiřazení typu (viz ukázka).
dbms_pipe.unpack_message_bytea() bytea Z lokálního bufferu získá hodnotu typu bytea.
dbms_pipe.send_message(pipe text [,timeout int] [,limit int]) int Pokusí se odeslat zprávu (obsah lokálního bufferu) do roury pipe. Pokud roura daného jména dosud neexistuje, bude vytvořena. Pokud se nepovede odeslat zprávu v timeoutu vrací hodnotu 1, jinak hodnotu 0. Timeout je zadán v sec. Limit v maximálním počtu zpráv, které může roura držet. Přípustná je i hodnota 0. Implicitně vytvořená roura je vždy veřejná.
dbms_pipe.receive_message(pipe text [,timeout int]) int Pokusí se získat zprávu z roury pipe. Pokud zprávu nezíská v timeoutu vrací hodnotu 1, jinak 0. Timeout se zadává v sec (def. hodnota odpovídá 1 roku)
dbms_pipe.create_pipe(pipe text, limit int [,private bool])
dbms_pipe.create_pipe(pipe text [,limit int])
Vytvoří explicitní rouru. Pokud jsou zadány parametry roury, nastaví je (limit v počtu zpráv, a private - omezení přístupu).
dbms_pipe.remove_pipe(pipe text) Odstraní rouru
dbms_pipe.reset_buffer() Reset vyrovnávací paměti (obsahuje neodeslané zabalené nebo přijate nerozbalené hodnoty)
dbms_pipe.purge(pipe text) Vyprázdní rouru
dbms_pipe.next_item_type() int Vrací typ následující hodnoty (0 žádná další, 9 numeric, 11 text, 12 date, 13 timestamp, 23 bytea, 24 record)
dbms_pipe.unique_session_name() text Vrací unikátní identifikátor session ve tvaru PG$PIPE$id$pid (id - identif. proceu používající sdílenou paměť pro implementaci rour, pid - identifikátor procesu)

Pohled dbms_pipe.db_pipes

Statistika existujících front je k dispozici v pohledu dbms_pipe.db_pipes.

  postgres=# select * from dbms_pipe.db_pipes;
   name | items | size | limit | private | owner
  ------+-------+------+-------+---------+-------
   boo  |     1 |   32 |       | f       |
  (1 row)

PLVdate

Tato sada funkcí je součástí frameworku PLVision (pravděpodobně nejrozšířenější knihovna PL/SQL funkcí, která nepochází z dílen Oracle). Tyto funkce dovolují provádět výpočty nad kalendářem pracovních dnů. Kalendář lze velice snadno modifikovat, např. přizpůsobit pro neevropské prostředí (vypuštění velikonoc, pracovní sobota, atd.). Pro usnadnění práce distribuce obsahuje kalendáře pro Českou republiku, všechny sousední země a některé dálší. Do kalendáře můžeme vložit vlastní svátky (každoroční) nebo vlastní mimopracovní dny.

 SELECT plvdate.plvdate.default_holydays('czech');
 SELECT plvdate.add_bizdays(CURRENT_DATE, 10); 
 SELECT plvdate.isbizday('2006-12-25');
 SELECT plvdate.set_nonbizday('Friday');

Funkce

add_bizdays(day date, days int) date Přičte n pracovních dnů
plvdate.nearest_bizday(day date) date Vrací nejbližší pracovní den
plvdate.next_bizday(day date) date Vrací další pracovní den
plvdate.bizdays_between(day1 date, day2 date) int Vrátí počet pracovních dnů mezi dnem1 a dnem2
plvdate.prev_bizday(day date) date Vrací předchozí pracovní den
plvdate.isbizday(date) bool Testuje, zda-li se jedná o pracovní den
plvdate.set_nonbizday(dow varchar) Nastaví den v týdnu jako mimopracovní
plvdate.unset_nonbizday(dow varchar) Nastaví den v týdnu jako pracovní
plvdate.set_nonbizday(day date) Nastaví den v roce jako mimopracovní
plvdate.unset_nonbizday(day date) Nastaví den v roce jako pracovní
plvdate.set_nonbizday(day date, repeat bool) Nastaví den jako mimopracovní, pokud je repeat true, tak se den bere jako svátek
plvdate.unset_nonbizday(day date, repeat bool) Nastaví den jako pracovní, pokud je repeat true, tak se den bere jako svátek
plvdate.use_easter() Kalendář počítá s Velikonocemi
plvdate.unuse_easter(); Kalendář nepočítá s Velikonocemi
plvdate.use_easter(useit boolean);
plvdate.using_easter() bool Vrací true, pokud kalendář počítá s Velikonocemi
plvdate.include_start() bizdays_between počítá i s prvním dnem
plvdate.noinclude_start();
plvdate.include_start(include boolean);
plvdate.including_start() bool;
plvdate.plvdate.default_holydays(country text); Načte předdefinovaný kalendář - czech, german, slovakia, ...

Funkce pro práci se řetězci PLVstr a znaky PLVchr

PLVision obsahuje několik desítek funkcí pro operace s řetězci a znaky. Balíku orafce obsahuje pouze ty obecnější, vynechává např. funkce pro podporu parsování zdrojového kódu PL procedur. Bezesporu nejzajímavější vlastností implementovaných funkcí je podpora negativního pozicování. Pokud jako pozici uvedeme záporné číslo, pak se pozice v řetězci nebude vztahovat k začátku řetězce, ale k jeho konci.

 plvstr.left('abcdef',2)      -> ab
 plvstr.left('abcdef',-2)     -> abcd
 plvstr.substr('abcdef',1,1)  -> a
 plvstr.substr('abcdef',-1,1) -> f
 plvstr.substr('abcde',-2,1)  -> d

Funkce

plvstr.normalize(str text) Bílé znaky nahradí mezerami, skupiny mezer nahradí mezerou
plvstr.is_prefix(str text, prefix text, cs bool) Vrací true, pokud je prefix prefixem řetězce str. Parametr cs - case sensitive
plvstr.is_prefix(str text, prefix text) Vrací true, pokud je prefix prefixem řetězce str
plvstr.is_prefix(str int, prefix int) Vrací true, pokud je prefix prefixem čísla str
plvstr.is_prefix(str bigint, prefix bigint) Vrací true, pokud je prefix prefixem čísla str
plvstr.substr(str text, start int, len int) Vrací len znaků začínající od pozice start
plvstr.substr(str text, start int) Vrací řetězec znaků od pozice start až do konce
plvstr.instr(str text, patt text, start int, nth int) Hledá vzor v řetězci, nth kolikátý výskyt
plvstr.instr(str text, patt text, start int) Hledá vzor v řetězci
plvstr.instr(str text, patt text) Hledá vzor v řetězci
plvstr.lpart(str text, div text, start int, nth int, all_if_notfound bool) Vrací znaky nalevo od nalezeného vzoru div, hledání začne na pozici start, hledá n-tý výskyt vzoru, pokud je all_if_notfound true, pak když nenajde vzor vrací celý řetězec jinak NULL
plvstr.lpart(str text, div text, start int, nth int) Vrací znaky nalevo od nalezeného vzoru div, hledání začne na pozici start, hledá n-tý výskyt vzoru
plvstr.lpart(str text, div text, start int) Vrací znaky napravo od nalezeného vzoru div, hledání začne na pozici start
plvstr.lpart(str text, div text) Vrací znaky nalevo od nalezeného vzoru div
plvstr.rpart(str text, div text, start int, nth int, all_if_notfound bool) Vrací znaky nalevo od nalezeného vzoru div, hledání začne na pozici start, hledá n-tý výskyt vzoru, pokud je all_if_notfound true, pak když nenajde vzor vrací celý řetězec jinak NULL
plvstr.rpart(str text, div text, start int, nth int) Vrací znaky nalevo od nalezeného vzoru div, hledání začne na pozici start, hledá n-tý výskyt vzoru
plvstr.rpart(str text, div text, start int) Vrací znaky nalevo od nalezeného vzoru div, hledání začne na pozici start
plvstr.rpart(str text, div text) Vrací znaky nalevo od nalezeného vzoru div
plvstr.lstrip(str text, substr text, num int) Odstraní n opakování vzoru substr z řetězce zleva
plvstr.lstrip(str text, substr text) Odstraní opakovaný vzor substr z řetězce zleva
plvstr.rstrip(str text, substr text, num int) Odstraní n opakování vzoru substr z řetězce zprava
plvstr.rstrip(str text, substr text) Odstraní opakovaný vzor substr z řetězce zprava
plvstr.rvrs(str text, start int, _end int) Otočí část řetězce od start do _end
plvstr.rvrs(str text, start int) Otočí část řetězce od pozice start do konce
plvstr.rvrs(str text) Otočí řetězec
plvstr.left(str text, n int) Vrací prvních n znaků zleva. Pokud je n záporné, vrací znaky od začátku řetězce do n znaků zprava
plvstr.right(str text, n int) Vrací prvních n znaků zprava . Pokud je n záporné, vrací znaky od konce řetězce do n znaků zleva
o plvchr.nth(str text, n int) Vrací n-tý znak v řetězci
plvchr.first(str text) Vrací první znak
plvchr.last(str text) Vrací poslední znak
plvchr.is_blank(c int) Je znak prázdným znakem?
plvchr.is_blank(c text) Je znak prázdným znakem?
plvchr.is_digit(c int) Je znak číslicí?
plvchr.is_digit(c text) Je znak číslicí?
plvchr.is_quote(c int) Je znak apostrofem?
plvchr.is_quote(c text) Je znak apostrofem?
plvchr.is_other(c int) Je něčím jiným, ne ASCII7 znak
plvchr.is_other(c text) Je něčím jiným, ne ASCII7 znak
plvchr.is_letter(c int) Je znak písmenem?
plvchr.is_letter(c text) Je znak písmenem?
plvchr.char_name(c text) Vrací název znaku, zajímavé zejména pro bílé znaky
plvchr.quoted1(str text) Vloží text mezi
plvchr.quoted2(str text) Vloží text mezi '"'
plvchr.stripped(str text, char_in text) Odstraní z řetězce všechny znaky z char_in

PLVsubst

Funkce z tohoto balíčku umožňují snadnou substituci určitých symbolů v řetězci. Např. pro transformaci nápovědy, chybových hlášení, záznamů v logu atd. Výchozí substituční symbol je '%s'. Tento symbol lze v rámci sezení změnit. Data lze předávat buďto jako pole nebo v jako řetězec obsahující seznam hodnot oddělených specifickým symbolem (výchozí hodnotou je symbol ',').

postgres=# select plvsubst.string('Jmenuji se %s %s', ARRAY['Pavel','Stěhule']);
          string           
---------------------------
 Jmenuji se Pavel Stěhule
(1 row)

Funkce

plvsubst.setsubst ([varchar = '%s']) Nastaví substituční symbol platný v dané session
plvsubst.subst () Vrátí aktuální substituční symbol
plvsubst.string (text, text[] [, text = '%s']) Nahradí všechny výskyty substitučního symbolu prvky pole
plvsubst.string (text, text [, text = ',' [, text = '%s']]) Nahradí všechny výskyty substitučního symbolu prvky seznamu

DBMS_UTILITY

Funkce

dbms_utility.format_call_stack() Vrací víceřádkový řetězec obsahující obsah zásobníku volání.

PLVlex

Obsahuje pouze jednu funkci vracející tabulku obsahující množinu tokenů zadaného SQL řetězce. Hodnoty code v různých verzích PostgreSQL mohou být rozdílené.

postgres=# SELECT * FROM plvlex.tokens('SELECT t.* FROM tabulka t WHERE t.i = 10',true, true);
 pos |  token  | code |  class  | separator | mod  
-----+---------+------+---------+-----------+------
   0 | select  |  527 | KEYWORD |           | 
   7 | t       |      | IDENT   |           | 
   8 | .       |   46 | OTHERS  |           | self
   9 | *       |   42 | OTHERS  |           | self
  11 | from    |  377 | KEYWORD |           | 
  16 | tabulka |      | IDENT   |           | 
  24 | t       |      | IDENT   |           | 
  26 | where   |  591 | KEYWORD |           | 
  32 | t.i     |      | IDENT   |           | 
  36 | =       |   61 | OTHERS  |           | self
  38 | 10      |      | NCONST  |           | i
(11 rows)

Funkce

plvlex.tokens (text, bool, bool) Provede lexikální analýzu SQL řetězce. Druhým argumentem určujeme, zda se mají přeskakovat bílé znaky, třetím, zda má dojít ke generování kvalifikovaných identifikátorů.

Instalace

Předpokladem je, že máte k dispozici zdrojové kódy PostgreSQL. Do poddresáře contrib rozbalte archiv se zdrojovými kódy orafce..tgz. Z příkazové řádky přejděte do tohoto adresáře. Spusťe překlad a instalaci příkazem make install. Poté restartujte server PostgreSQL. Spusťe si sql konzoli psql nad databázi, kde chcete používat funkce Oracle a naimportujte registrační skript orafunc.sql.

  cp orafce-2.0.1-preview.tgz /usr/loca/src/pgsql/contrib
  cd /usr/local/src/pgsql/contrib
  tar xvfz orafce-2.0.8-pre.tgz
  cd orafce
  make install
  /etc/init.d/postgres restart
  # make installcheck
  psql mojedb
  \i orafunc.sql
  select next_day(current_date,'saturday');

Pro verzi 8.2 je k dispozici rpm balíček (ke stažení z http://developer.postgresql.org/~devrim/rpms/other/orafce/).

Hlášení chyb

Pokud zjistíte chybu u některé funkce, prosím, pošlete mail s popisem chyby a příkladem, na kterém je zřejmé, jak se chyba projevuje Pavlu Stěhulemu

en