5.    Identificatori, operatori, expresii

 

5.1.          Identificatori

 

A.   Forma unui identificator

 

Identificatorii obisnuiti folositi in blocurile PL/SQL trebuie sa indeplineasca urmatoarele conditii:

 

§        Lungimea maxima este de 30 de caractere.

§        Trebuie sa inceapa cu o litera.

§        Pot contine litere, cifre si caracterele _ $ #

§        In cazul literelor nu conteaza daca sunt mari sau mici. De exemplu identificatotul NUME este acelasi cu Nume sau nume.

§        Nu trebuie sa fie identici cu numele unei coloane dintr-o tabela a bazei de date

§        Cuvintele rezervate pot fi folosite ca identificatori dar trebuiesc puse intre ghilimele (exemplu "SELECT", "INSERT", "UPDATE", etc.). Lista cuvintelor rezervate se gaseste in Anexa 1.

 

Exemple de identificatori valizi:

v_ename VARCHAR2(10);

v$ename#_    VARCHAR2(40);

v1_$ NUMBER;

 

Exemple de identificatori invalizi:

1_ename VARCHAR2(10);

v-ename&    VARCHAR2(40);

v/t beta NUMBER;

end BOOLEAN;

In exemplele de mai sus exista caracterele invalide -, &, / si spatiu. De asemenea, primul identificator nu incepe cu o litera iar ultimul este cuvant rezervat.

 

B.   Identificatori intre ghilimele

 

Desi nu sunt recomandati, in PL/SQL sunt permisi si operatori care contin orice caracter tiparibil (inclusiv spatiu) daca sunt pusi intre ghilimele. Lungimea maxima este tot de 30 de caractere (exclusiv ghilimelele) si in continutul lor nu poate apare caracterul ghilimele.

 

Exemple de astfel de identificatori:

"1_ename" VARCHAR2(10);

"v-ename& "   VARCHAR2(40);

"v/t=beta" NUMBER;

"end" BOOLEAN;

 

Ghilimelele sunt necesare si atunci cand in cererile SQL apar cuvinte rezervate PL/SQL dar care nu sunt rezervate in SQL. De exemplu, daca o coloana a unei tabele se numeste BEGIN (cuvant rezervat doar in PL/SQL) atunci o cerere SQL care este parte a unui bloc PL/SQL de tipul:

SELECT EVENT, BEGIN . . .

va genera o eroare. Corect cererea trebuie scrisa astfel:

SELECT EVENT, "BEGIN" . . .

 

 

C.   Domeniul de valabilitate al identificatorilor

 

Un identificator definit intr-un bloc este local acelui bloc si global in toate subblocurile sale. In cazul in care un subbloc redefineste un identificator, in subbloc poate fi folosit doar acesta din urma.

 

Exemplu:

declare

  a NUMBER;

  b VARCHAR2(10);

begin

  declare

     a VARCHAR2(20);

c NUMBER

begin

   -- pot fi folositi a (VARCHAR2(10)), b si c

  end;

-- pot fi folositi a (NUMBER) si b

end;

 

 

5.2.         Operatori

 

In expresii se pot folosi operatori de comparatie, aritmetici, logici, de concatenare precum si cei patru operatori specifici SQL (IS NULL, LIKE, BETWEEN si IN).

Precedenta operatorilor este urmatoarea:

 

**

ridicare la putere

*, /

inmultire, impartire

+, -, ||

adunare, scadere, concatenare

=, <, >, <=, >=, <>, !=, ~=, ^=,IS NULL, LIKE, BETWEEN, IN

comparatie

NOT

negatie logica

AND

SI logic

OR

SAU logic

 

Pentru a preintampina eventualele erori de semantica in scrierea expresiilor se recomanda folosirea parantezelor pentru a specifica explicit ordinea de efectuare a operatiilor.

De exemplu, urmatoarele doua expresii logice sunt echivalente dar recomandata este a doua forma:

v_a > 1 and v_b < 10 or v_nr = 20

 

((v_a > 1) and (v_b < 10)) or (v_nr = 20)

 

5.3.         Expresii

 

A.   Constante (literali)

 

Literalii pot fi:

 

§       Numerici. Exemple: -12.9, 9E2 (= 9 * 102 = 900)

§       Logici: Pot avea valoarea TRUE, FALSE si NULL.

§       Sir de caractere. Se pun intre apostrofi. Exemple: 'A', 'Buna ziua', 'Don''t do that'. Intre apostrofi poate fi orice caracter tiparibil. Includerea unui apostrof in sir se face prin dublarea sa, ca in ultimul exemplu

§       Data calendaristica. Se pun intre apostrofi in formatul standard si se foloseste tipul lor generic in genul cast-ului din C (Oracle9).

 

Exemple de literali de tip data:

 

   declare

 

d date := date '2004-05-25';

t timestamp := timestamp '2004-06-20 11:00:00';

u timestamp with time zone :=

       timestamp '2004-06-20 11:00:00.25 +01:00';

i interval year to month :=

       interval '1-4' year to month;

j interval day to second :=

       interval '2 01:02:03.04' day to second;

 

 

Obs: In Oracle8 sirul de caractere reprezentand data nu se prefixeaza cu numele tipului.

 

 

B.   Evaluarea expresiilor logice

 

In cazul unei expresii logice complexe evaluarea se opreste in momentul in care valoarea expresiei este cunoscuta. Acest lucru inseamna ca restul expresiei nu se mai evalueaza si deci nici nu se genereaza exceptii in cazul in care acestea ar fi putut sa apara in partea neprocesata a expresiei.

 

 

 

Exemplu:

declare

  a NUMBER;

  b NUMBER;

begin

    .  .  .

  if (a = 0) or ((b/a) < 1) then

    .  .  .

  end if

    .  .  .

end;

 

In cazul in care variabila a are valoarea 0 expresia logica se evalueaza la TRUE si nu se mai testeaza a doua parte a ei care ar genera o exceptie de tip ZERO_DIVIDE.

 

C.   Tratarea valorilor nule

 

§       O comparatie care implica o valoare nula returneaza NULL.

§       Negarea unei valori de NULL returneaza NULL.

§       O conditie care se evalueaza la NULL e tratata ca FALSE.

§       In cazul expresiilor CASE (prezentate mai jos) nu se poate scrie WHEN NULL ci sintaxa este WHEN expresie IS NULL.

§       Un sir de caractere de lungime 0 este tratat de PL/SQL ca o valoare de NULL.

§       Operatorul de concatenare || ignora valorile nule.

§       Operatorul IN (lista de valori) ignora valorile nule din lista

§       Operatorul NOT IN (lista de valori) intoarce FALSE daca lista contine o valoare nula.

 

Cand o valoare de NULL este transmisa ca parametru unei functii SQL sau PL/SQL rezultatul este NULL in afara de cazurile urmatoare:

 

§        Functia DECODE aflata intr-o cerere SQL poate contine argumente nule

§        Functia NVL poate avea primul argument NULL

§        Functia REPLACE poate avea al doilea argument NULL (intoarce primul argument indiferent de al treilea) sau al treilea argument NULL (elimina din primul argument aparitiile celui de-al doilea)

 

D.   Expresii CASE (Oracle9)

 

Expresiile CASE sunt folosite pentru a returna o valoare in functie de una sau mai multe conditii. Ele suplinesc faptul ca in instructiunile PL/SQL nu se poate folosi functia DECODE (aceasta poate fi prezenta doar in cereri SQL).

 

Exista doua forme ale acestora. Prima dintre ele este exemplificata in continuare:

 

DECLARE

codjudet VARCHAR2(2) := 'CJ';

numejudet VARCHAR2(20);

BEGIN

numejudet :=

  CASE codjudet

WHEN 'MM' THEN 'Maramures'

WHEN 'CT' THEN 'Constanta'

WHEN 'CJ' THEN 'Cluj'

ELSE 'Alt judet'

  END;

END;

 

A doua forma este o generalizare a primeia permitandu-ne ca valoarea returnata sa fie aleasa in functie de o conditie generala si nu doar de egalitate cum este in primul caz.

Exemplu:

 

DECLARE

codjud VARCHAR2(2) := 'CJ';

numejud VARCHAR2(20);

BEGIN

numejud :=

  CASE

WHEN codjud = 'MM' THEN 'Maramures'

WHEN codjud ='CT' THEN 'Constanta'

WHEN codjud ='CJ' THEN 'Cluj'

WHEN codjud LIKE 'A%' THEN 'Nume incepand cu A'

WHEN codjud IS NULL THEN 'Cod judet NULL'

ELSE 'Alt judet'

  END;

END;

 

E.   Functii

 

Expresiile SQL si PL/SQL pot contine functii din tabelul urmator. Exista insa restrictiile urmatoare:

 

§        Functiile SQLCODE si SQLERRM nu pot fi folosite in cereri SQL.

 

§        Functiile DEREF, REF, VALUE, DECODE, DUMP, GREATEST, LEAST si VSIZE nu pot fi folosite in instructiunile procedurale ale PL/SQL (in documentatia Oracle9 nu mai sunt amintite in aceasta categorie GREATEST si LEAST).

 

§        Functiile statistice si analitice (ex: AVG, SUM, COUNT, MIN, MAX, etc.) sunt specifice SQL si nu pot fi folosite in instructiunile procedurale ale PL/SQL.

 

 

 

 

Functii recunoscute in PL/SQL

 

Erori

Numar

Caracter

Conversie

Data

Obiect

Diverse

SQLCODE

ABS

ASCII

CHARTOROWID

ADD_MONTHS

DEREF

BFILENAME

SQLERRM

ACOS

CHR

CONVERT

CURRENT_DATE

REF

DECODE

 

ASIN

CONCAT

HEXTORAW

CURRENT_TIMESTAMP

VALUE

DUMP

 

ATAN

INITCAP

RAWTOHEX

DBTIMEZONE

TREAT

EMPTY_BLOB

 

ATAN2

INSTR

ROWIDTOCHAR

EXTRACT

 

EMPTY_CLOB

 

BITAND

INSTRB

TO_BLOB

FROM_TZ

 

GREATEST

 

CEIL

LENGTH

TO_CHAR

LAST_DAY

 

LEAST

 

COS

LENGTHB

TO_CLOB

LOCALTIMESTAMP

 

NLS_CHARSET_DECL_LEN

 

COSH

LOWER

TO_DATE

MONTHS_BETWEEN

 

NLS_CHARSET_ID

 

EXP

LPAD

TO_MULTI_BYTE

NEW_TIME

 

NLS_CHARSET_NAME

 

FLOOR

LTRIM

TO_NCLOB

NEXT_DAY

 

NVL

 

LN

NLS_INITCAP

TO_NUMBER

NUMTODSINTERVAL

 

SYS_CONTEXT

 

LOG

NLS_LOWER

TO_SINGLE_BYTE

NUMTOYMINTERVAL

 

SYS_GUID

 

MOD

NLSSORT

 

ROUND

 

UID

 

POWER

NLS_UPPER

 

SESSIONTIMEZONE

 

USER

 

ROUND

REPLACE

 

SYSDATE

 

USERENV

 

SIGN

RPAD

 

SYSTIMESTAMP

 

VSIZE

 

SIN

RTRIM

 

TO_DSINTERVAL

 

 

 

SINH

SOUNDEX

 

TO_TIMESTAMP

 

 

 

SQRT

SUBSTR

 

TO_TIMESTAMP_LTZ

 

 

 

TAN

SUBSTRB

 

TO_TIMESTAMP_TZ

 

 

 

TANH

TRANSLATE

 

TO_YMINTERVAL

 

 

 

TRUNC

TRIM

 

TZ_OFFSET

 

 

 

 

UPPER

 

TRUNC