TRIGGERE PL/SQL

Aceasta anexa trateaza PL/SQL ca pe un limbaj de definire a triggerelor de tipul V3. Toate materialele de aici sun tcuprinse in cursurile ORACLE RDBMS, SQL, SQL Plus si PL/SQL. Problemele discutate:

Acest capitol nu va va transforma intr-un expert in PL/SQL. El acopera sintaxa PL/SQL intr-o masura suficienta pentru a va permite sa scrieti triggere. Probleme complexe cum ar fi blocuri 'nested' sau gestionarea cursorului nu sunt tratate.

Rolul PL/SQL in triggere


Ce este PL/SQL ?


PL/SQL este un limbaj de programare bazat pe ADA. El combina capacitatea de a lucra cu proceduri a limbajelor de programare cu facilitatile SQL. Aceasta inseamna ca PL/SQL este capabil sa extinda puterea SQL cu logica procedurala cum ar fi cicluri sau ramificari conditionale. Intr-un mediu SQL*Forms este un limbaj puternic pentru triggere.

PL/SQL este, de asemeni, disponibil ca un limbaj de programare in afara SQL*Forms.

Iata un exemplu de utilizare a PL/SQL. Acest bloc gestioneaza o comanda de rachete de tenis.
        DECLARE num_in_stock NUMBER (5);
        BEGIN
          SELECT quantity INTO num_in_stock FROM inventory_table
            WHERE product = 'TENNIS RACQUET'
          IF num_in_stock > 0 THEN
            UPDATE inventory_table SET quantity = quantity - 1
            WHERE product = 'TENNIS RACQUET';
            INSERT INTO puchase_record
            VALUES ('TENNIS RACKET PURCHASED', SYSDATE);
          ELSE
            INSERT INTO purchase_record
            VALUES ('OUT OF TENNIS RACKET', SYSDATE);
          ENDIF;
        END

N.B.: Termenul bloc se refera la o constructie PL/SQL si nu are nici o legatura cu blocurile SQL*Forms.

CE STITI DEJA DESPRE PL/SQL :


Elemente comune intre SQL si PL/SQL


Stiti deja destule despre PL/SQL prin simpla cunoastere a SQL. Instructiunile executabile specifice PL/SQL folosesc facilititati SQL:

Identificatori


Regulile de denumire a obiectelor PL/SQL sunt similare conventiilor ORACLE, de exemplu maxim 30 de caractere incepand cu o litera, urmata de maximum 29 de litere, cifre sau oricare din caracterele #, _ si $.

Tipuri de date


PL/SQL accepta tipurile de date ORACLE: DATE, CHAR si NUMBER. In plus, PL/SQL suporta tipul boolean pentru memorarea valorilor TRUE, FALSE si NULL.

Predicate


PL/SQL permite accesul la cele mai multe predicate SQL; cu alte cuvinte puteti utiliza in PL/SQL instructiuni conditionale pe care le-ati plasa in clauza SQL `WHERE'. In formarea predicatelor folositi operatorii de comparatie, inclusiv `BETWEEN', `ISNULL', `LIKE' si `IN', ca si < , >, =, !=, >=, < = si operatorii logici OR, AND si NOT.

Functii


Cele mai multe functii SQL, cu exeptia functiilor grup pot fi folosite in instructiunile PL/SQL. Acestea includ functii de tipurile : `numeric', `character', `date' si `data conversion'.

Pseudo-coloane


Un subset al pseudo-coloanelor SQL (SYSDATE, USER, UID) este accesibil din instructiuni specifice PL/SQL. Cand sunt referite, ele se comporta ca functii predefinete fara argumente.

Format liber


Ca si SQL, PL/SQL permite adaugare de spatii suplimentare oriunde in interiorul comenzilor, exceptand interiorul cuvintelor (de ex. `BEGIN' si nu `BE GIN') sau operatorilor (de ex. `:=' si nu `: =').

UN BLOC PL/SQL


Unitatea de programare a PL/SQL este blocul

        DECLARE
                Declaratii

        BEGIN
                Instructiuni executabile

        EXCEPTION
                Tratare exceptii

        END


Corpul unui trigger se compune din unul sau mai multe blocuri PL/SQL. Un bloc PL/SQL este definit ca mai sus.
Cuvintele cheie `DECLARE', `BEGIN', `EXCEPTION' SI `END' impart blocul in trei parti. Dintre acestea trei, singura obligatorie este cea executabila.
O sectiune de declaratii este necesara doar daca blocul utilizeaza variabile locale. Tratarea exceptiilor se face daca o instructiune select dintr-un bloc va face altceva decat sa intoarca o inregistrare.

Exemplu de bloc PL/SQL :

        DECLARE location CHAR (10);
        BEGIN
          SELECT loc
            INTO location
            FROM dept
            WHWRE dname = :dept.dname;
        EXCEPTION
          WHEN no_data_found THEN
            MESSAGE ('no departament of that name exists');
            Raise Form_Trigger_Failure;
          WHEN too_many_rows THEN
            MESSAGE ('more then one departement of that name exists');
        END;


BEGIN/END sunt, cateodata, optionale.

Daca triggerul se compune dintr-un bloc fara sectiune DECLARE se pot omite cuvintele cheie BEGIN si END.

ATRIBUIREA DE VALORI VARIABILELOR


Sunt patru moduri de a seta sau scu\imba valoarea variabilei de pe un camp al ecranului.

Operatorul de atribuire (`:=')


Pentru a seta valoarea unei variabile PL/SQL dispune de un operator de atribuire. Destinatia este lpasata in dreapta operatorului; sursa, care poate fi o expresie PL/SQL, se afla la dreapta operatorului de atribuire.
De exemplu:
        :GLOBAL.flag := 1;
        : item.actualprice := :item.stdprice * .80;
        salary := 12 * :emp.sal;
        name := initcap (name)

Initializarea variabilelor


PL/SQL va permite sa initializati variabilele la momentul declararii lor.
        DECLARE COUNTER NUMBER := 0;
                FIN_FLAG BOOLEAN := FALSE;

Instructiunea `SELECT'


Valoarea unei variabile poate fi setata, de asemenea, cu ajutorul lui `SELECT'.
        SELECT name
        INTO   : ord.name
        FROM   customers
        WHERE  :ord.custid = custid

Procedura package COPY


Exista o procedura care este folosita atunci cand oprratorul de atribuire nu este potrivit.

CONTROLUL CONDITIILOR : IF, ELSE, ELSEIF, ENDIF


Instructiunea IF


Instructiunea IF executa in mod conditionat o secventa de instructiuni. Secventa ce urmeaza a fi executata depinde de evaluarea conditiei. Formatul este
        IF  THEN ;
        ENDIF

Cuvantul cheie ELSEIF


Cuvantul cheie `ELSEIF' este folosit pentru a introduce o noua conditie pentru a fi evaluata daca conditia IF-ului initial este evaluata ca FALSE.

Cuvantul cheie ELSE


Cuvantul cheie ELSE ofera alternativa executiei unei secvente de instructiuni daca instructiunile IF/ELSEIF precedente sunt false. Dupa ELSE nu urmeaza nici o conditie.
Exemplu :
        ON_VALIDATE_FIELD
        ---------------------
        IF :emp.sex = 'M'
          THEN EXECUTE_TRIGGER ('male patient');
        ELSEIF :emp.sex = 'F'
          THEN EXECUTE_TRIGGER ('female patient');
        ELSE
          MESSAGE ('Invalid response; please enter M or F');
          RAISE FORM_TRIGER_FALURE;
        ENDIF

ENDIF

ENDIF este necesar pentru a incheia o instructiune if.

CONTROL CONDITIONAL


Conditii IF valide
        IF :cus.state = 'CA' THEN ...

        IF :item.actualprice < minimum OR
           :item.actualprice < .80 * :item.stdprice THEN ...

        IF job_is_clerk = TRUE THEN ...

Fiecare cinditie a unei instructiuni IF trebue sa fie evaluata cu TRUE sau FALSE (NULL este interpretat ca FALSE). TRUE, FALSE si NULL sunt cuvinte rezervare PL/SQL.

Testarea valorilor NULL


Compararea variabilelor care pot contine valoarea NULL trebuie facuta cu atentie. In urmatorul exemplu ambele campuri contin valori NULL.
        IF :field_1 = :field_2 THEN ...                         FALSE
        IF nv1 (:field_1, 0) = nv1 (:field2, 0) THEN ...        TRUE
        IF :field_1 = :field_2 OR
           (:field_1 is NULL and :field_2 is NULL) THEN ...     TRUE