Sunteți pe pagina 1din 56

Sisteme de Gestiune a Bazelor de Date

— an3, s2, 2010 —

A Grila postata – 44 subiecte


B Din Lab 1 – 17 subiecte
C Culese dupa examen – 3 subiecte
verner
Blocul urmator afiseaza:

DECLARE
v_x NUMBER(9,2):=10;
v_y NUMBER(9,2);
v_message VARCHAR2(20);
BEGIN
A 10 v_y:= NULL; c
IF v_x !=v_y THEN
v_message := ‘ NOT EQUAL’;
ELSE v_message := ‘EQUAL’;
END IF;
DBMS_OUTPUT.PUT_LINE(v_message);
END;
c. EQUAL
Care din urmatoarele declaratii de valabilitate este corecta?

b. v_id_student NUMBER(5);
A 2 b
v_nume_student VARCHAR2(35) NOT NUL:=’Ionescu’;
v_prenume_student studenti.prenume%TYPE;
v_data DATE:=SYSDATE+1;
Care dintre urmatoarele afirmatii este corecta?
A 38 a
a. Blocul PL/SQL care descrie actiunea unui trigger nu poate contine
comanda COMIT
Care dintre urmatoarele afirmatii nu este corecta?
A 37 d
d. Un trigger la nivel de linie este executat o singura data, indiferent de
numarul de linii afectate de comanda declansatoare

1 din 29
Care dintre urmatoarele blocuri se executa cu erori?

d. DECLARE
alfa interval month;
A 14 d
BEGIN
alfa :=interval ‘8’ month;
DBMS_OUTPUT.PUT_LINE(‘alfa = ‘|| alfa);
END;
Care dintre urmatoarele variante apeleaza corect functia F_TEST care are
un singur parametru numeric?
A 28 a
a. SELECT F_TEST (80)
FROM DUAL ;
Care dintre urmatoarele vizualizari poate fi folosita în urmatoarea coman-
da pentru a vizualiza codul complet al subprogramului P1:

A 29 SELECT TEXT d
FROM ….
WHERE NAME = UPPER(’P1’);
d. USER_SOURCE
Care este varianta corecta care defineste un trigger la nivel de comanda
ce determina inserarea în tabelul audit_angajati a unui mesaj corespunza-
tor tipului de comanda LMD executata asupra tabelului angajati?

c. CREATE TRIGGER trigger_audit_angajati


AFTER INSERT OR DELETE OR UPDATE ON angajati
BEGIN
IF INSERTING THEN
INSERT INTO audit_angajati (actiune)
A 40 c
VALUES (‘Inserare’);
ELSIF DELETING THEN
INSERT INTO audit_angajati (actiune)
VALUES (‘Stergere’);
ELSE
INSERT INTO audit_angajati (actiune)
VALUES (‘Actualizare’);
END IF;
END;

2 din 29
Care este varianta corecta de cod PL/SQL care sterge din tabelul joburi,
joburile pentru care salariul minim este 4000 sau 8200, daca aceste valori
sunt mentinute intr-un vector?

a. DECLARE
TYPE min_sal IS VARRAY(20) OF NUMBER;
A 21 a
v_min_sal min_sal:=min_sal(4000,8200);
BEGIN
FORALL i IN v_min_sal.FIRST..v_min_sal. LAST
DELETE FROM joburi
WHERE salariu_min=v_min_sal(i);
END;
Care este varianta corecta pentru a crea specificatia unui pachet, care de-
fineste un cursor pentru obtinerea datelor şi o procedura ce actualizeaza
câmpul id_job al unui angajat cu un anumit cod?

c. CREATE OR REPLACE PACKAGE manager_pkg IS


A 34 CURSOR joburi_curs IS c
SELECT id_angajat, id_job FROM angajati;
PROCEDURE update_job(p_ang_id IN
angajati.id_angajat%TYPE,
P_id_job OUT angajati.id_job%TYPE);
END manager_pkg;

3 din 29
Care este varianta corectă pentru a defini doi vectori avand dimensiunea
maximă 3, iniţializaţi prin liste de valori, şi un al treilea, care va avea ca
elemente, produsul pe componente a celor doi vectori?

a. DECLARE
TYPE vector IS VARRAY(3) OF NUMBER
v_1 vector :=vector(1,2,3); v_2 vector :=vector(100,200,300)
v_produs vector :=vector();
BEGIN
FOR i in 1..3 LOOP
v_produs(i)* v_2(i)
END LOOP;
END

b. DECLARE
TYPE vector IS VARRAY(3) OF NUMBER
C 3 v_1 vector :=vector(1,2,3); v_2 vector :=(100,200,300) ?
v_produs vector:=vector();
BEGIN
FOR i in 1..3 LOOP
v_produs.EXTEND; v_produs(i):=v_1(i)* v_2(i);
END LOOP;
END

c. DECLARE
TYPE vector IS VARRAY(3) OF NUMBER
v_1 vector:=vector(1,2,3); v_2 vector:=vector(100,200,300)
v_produs vector:=vector();
BEGIN
FOR i in 1:3 LOOP
v_produs(i) :=v_produs(i)* v_1(i)* v_2(i)
END LOOP;
END
Care este varianta corecta pentru a defini un tablou imbricat de numere
care are ca elemente primele 10 numere naturale?

b. DECLARE
TYPE tablou IS TABLE OF NUMBER;
A 19 b
tab tablou:= tablou();
BEGIN FOR i IN 1…10 LOOP
tab.EXTEND; tab(i) := i;
END LOOP;
END;

4 din 29
Care este varianta corecta pentru afisarea variabilei v_mesaj ?

b. VARIABLE v_mesaj VARCHAR2 (30)


A 9 b
BEGIN
:v_mesaj := ‘Invat PL/SQL’;
END;
/
Care este varianta corecta pentru declararea urmatoarelor variabile?

A 1 c. v_valoare NUMBER(15) NOT NULL := 0; c


v_data_achizitie DATE DEFAULT SYSDATE;
c_valoare CONSTANT NUMBER:= 1000;
v_ cod_opera opere.cod_opera%TYPE;
Care este varianta corecta prin care se adauga în tabelul angajati un nou
camp numit telefon de tip tablou imbricat, pt care se vor stoca pt fiecare
salariat numerele sale de telefon, şi apoi se insereaza o linie noua în ta-
bel?
a
A 22 a. CREATE TYPE lista AS TABLE OF VARCHAR2(20);
?
ALTER TABLE angajati
ADD (telefon lista) NESTED TABLE telefon STORE AS
tabel_tel;
INSERT INTO angajati
VALUES(200,’xxx’,4000,40000,lista(0214567898,0214567899));

5 din 29
Care este varianta corecta prin care se afiseaza numele şi prenumele pri-
melor 5 persoane angajate în luna martie în anul 1997?

b. DECLARE
v_nume angajati.nume%TYPE; v_prenume
angajati.prenume%TYPE;
CURSOR c IS
SELECT nume, prenume FROM angajati
WHERE TO_CHAR(data_angajarii, ‘MM-YYYY’)=’03-
1997’
A 25 b
ORDER BY data_angajarii;
BEGIN
OPEN c;
LOOP
FETCH c INTO v_nume, v_prenume;
EXIT WHEN c%ROWCOUNT>5 OR c%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_nume||’ ‘|| v_prenume);
END LOOP;
CLOSE c;
END;
Care este varianta corecta prin care se incarca date dintr-un cursor într-o
colectie?

b. DECLARE
TYPE tip_job IS TABLE OF joburi.nume_job%TYPE;
v_nume tip_job;
A 23 b
CURSOR c_joburi IS SELECT nume_job FROM joburi;
BEGIN
OPEN c_joburi;
FETCH c_joburi BULK COLLECT INTO v_nume;
CLOSE c_joburi;
END;
Care este varianta de bloc PL/SQL corecta pentru a mentine intr-un vec-
tor codurile angajatilor care au salariul mai mic decat 20000 şi lucreaza
în departamentul 90?

b. DECLARE
TYPE t_id IS VARRAY(100) OF angajati.id_angajat%TYPE;
A 20 b
v_id t_id :=t_id();
BEGIN
SELECT id_angajat BULK COLLECT INTO v_id
FROM angajati
WHERE id_departament=90 AND salariu < 20000;
END;
6 din 29
Care este varianta incorecta prin care se obtin numele şi salariul angajati-
lor care au salariul mai mic decat 2500 şi nu lucreaza în departamentul a-
vand codul 80?

a. DECLARE
v_nume angajati.nume%TYPE;
v_sal angajati.salariu%TYPE;
CURSOR c(var_sal NUMBER, var_dept NUMBER) IS
SELECT nume, salariu
FROM angajati
WHERE salariu<var_sal AND id_departament<>var_dept;
BEGIN
OPEN c(2500,80);
LOOP
FETCH c INTO v_nume, v_sal;
EXIT WHEN c%NOTFOUND; b
DBMS_OUTPUT.PUT_LINE(‘Salariatul ’||v_nume||’ are a
A 24
salariul ‘|| v_sal); ?
END LOOP;
CLOSE c;
END;

b. DECLARE
v_sal :=2500;
v_dept := 80;
BEGIN
FOR ind IN (SELECT nume, salariu
FROM angajati
WHERE salariu<var_sal AND
id_departament<>var_dept) LOOP
DBMS_OUTPUT.PUT_LINE(‘Salariatul ’||ind_nume||’ are
salariul ‘|| ind_salariu);
END LOOP;
END;
Care tabel / vizualizare poate fi folosit/folosita în urmatoarea comanda
pentru a obtine informatii despre procedurile şi functiile detinute de utili-
zatorul curent?

A 32 SELECT * d
FROM …..
WHERE OBJECT_TYPE IN (‘PROCEDURE’ , ‘FUNCTION’);

d. USER_OBJECTS

7 din 29
Ce comanda SQL*Plus ar putea sa preceada blocul de mai jos pentru ca
în acesta să se utilizeze valoarea data variabilei sem ?

DECLARE
v_sem CHAR(2):=UPPER(‘&sem’);
BEGIN
CASE v_sem a
A 15
WHEN ‘I’ THEN DBMS_OUTPUT.PUT_LINE(‘SEMESTRUL I’); ?
WHEN ‘II’ THEN DBMS_OUTPUT.PUT_LINE(‘SEMESTRUL
II’);
ELSE DBMS_OUTPUT.PUT_LINE(‘este o eroare!’);
END CASE;
END;
a. ACCEPT sem PROMPT ‘sem=’
Ce trebuie adaugat la linia 11 pentru ca în următorul bloc PL/SQL să se
foloseasca corect cursorul?

1. DECLARE
2. CURSOR c_ang IS
3. SELECT *
4. FROM angajati
5. WHERE TO_CHAR(data_angajarii,’YYYY’)=2000
A 35 6. FOR UPDATE OF salariu NOWAIT; b
7. BEGIN
8. FOR v_c_ang IN c_ang LOOP
9. UPDATE angajati
10. SET salariu=salariu+1000
11. ………………………..
12. END LOOP;
13. END;
b. WHERE CURRENT OF c_ang;

8 din 29
Ce trebuie adaugat la linia 9 pentru ca urmatoarea functie sa fie corect
creata?

1. CREATE OR REPLACEFUNCTION nr_sal(v_dept NUMBER)


2. RETURN NUMBER IS
3. v_numar NUMBER(3);
4. BEGIN ?
A 30
5. SELECT COUNT(*) c
6. INTO v_numar
7. FROM angajati
8. WHERE id_departament=v_dept;
9 …………………………………………
10. END nr_sal;
c. RETURN v_numar;

9 din 29
Codul sursa de mai jos defineste un pachet cu ajutorul caruia, utilizand un
subprogram functie şi un cursor, se poate obtine salariul minim inregistrat
pentru angajati şi lista angajatilor care au salariul mai mare sau egal decat
acel minim +1000.

CREATE OR REPLACE PACKAGE pachet_min_sal AS


CURSOR c_ang(nr NUMBER) RETURN angajati % ROWTYPE;
FUNCTION f_min RETURN NUMBER ;
END pachet_min_sal;
CREATE OR REPLACE PACKAGE BODY pachet_min_sal AS
CURSOR c_ang(nr NUMBER) RETURN angajati % ROWTYPE IS
SELECT * FROM angajati WHERE salariu >nr+1000;
FUNCTION f_min
RETURN NUMBER IS
minim NUMBER ;
BEGIN
A 33 c
SELECT Min(salariu) INTO minim FROM angajati;
RETURN minim;
END f_min;
END pachet_min_sal;

Care este varianta corecta de apelare pentru a obtine lista dorita?

c. DECLARE
val_min NUMBER ;
BEGIN
val_min:=pachet_min_sal.f_min;
DBMS_OUTPUT.PUT_LINE(‘Salariul minim ’ || ’ ‘ || val_min);
FORv_cursor IN pachet_min_sal .c_ang(val_min)
DBMS_OUTPUT.PUT_LINE(v_cursor.nume||’ ‘||
v_cursor.salariu);
END;

10 din 29
Codul următor:

DECLARE
PROCEDURE p1(val NUMBER)
IS
BEGIN
UPDATE angajaţi
SET salariu=salariu+val
WHERE cod_departament=10; ?
C 1
END; c
BEGIN
p1(700);
END

a. declară o procedura stocată cu un parametru de tip IN


b. declară o procedura stocată cu un parametru de tip OUT
c. declară o procedura locală cu un parametru de tip IN
d. conţine erori
Creati un bloc anonim care să afiseze propoziţia "Invat PL/SQL" pe
ecran. Varianta 2 — Afisare folosind procedurile din pachetul
standard DBMS_OUTPUT

B 9 SET SERVEROUTPUT ON
BEGIN
DBMS_OUTPUT.PUT_LINE('Invat PL/SQL');
END;
/
Creaţi un bloc anonim care să afiseze propoziţia "Invat PL/SQL" pe
ecran. Varianta 1 — Afisare folosind variabile de legătură

VARIABLE g_mesaj VARCHAR2(50)


B 8 BEGIN
:g_mesaj := 'Invat PL/SQL';
END;
/
PRINT g_mesaj
Evaluati următoarele declaratii de variabile:

DECLARE
v_nume, v_prenume VARCHAR2(35);
B 4
Corect:
DECLARE
v_nume VARCHAR2(35);
v_prenume VARCHAR2(35);
11 din 29
Evaluati următoarele declaratii de variabile:

DECLARE
B 5 v_nr NUMBER(5,2) = 10;
Corect:
DECLARE
v_nr NUMBER(5,2) := 10;
Evaluati următoarele declaratii de variabile:

DECLARE
B 6 v_test BOOLEAN:= SYSDATE;
Corect:
DECLARE
v_test BOOLEAN:=TRUE;
Evaluati următoarele declaratii de variabile:

DECLARE
v1 NUMBER(5) :=10;
v2 NUMBER(5) :=15;
B 7 v3 NUMBER(5) := v1< v2;
Corect:
DECLARE
v1 NUMBER(5) :=10;
v2 NUMBER(5) :=15;
v3 BOOLEAN := v1< v2;
În blocul PL/SQL de mai jos

VARIABLE rows_deleted VARCHAR(20)


DECLARE
v_dep_id angajati.id_departament%TYPE:=80;
BEGIN
DELETE FROM angajati
A 36 WERE id_departament=v_dep_id; c
:rows_deleted:=SQL%ROWCOUNT||’rows deleted’;
END;
/
PRINT rows_deleted

apare:
c. un cursor implicit
Parametrii unei functii pot fi:
A 27 b
b. Numai de intrare (IN)

12 din 29
Pentru ca următorul bloc PL/SQL sa fie corect şi sa afiseze codul, salaria-
tul şi jobul angajatului cu codul 100, trebuie adaugat la linia 10 următorul
cod:

SQL> DECLARE
2 TYPE type_ang IS RECORD (
3 ang_cod angajati.id_angajat%TYPE,
4 sal angajati.salariu%TYPE,
5 job angajati.id_job%TYPE);
6 v_ang type_ang;
A 12 c
7 BEGIN
8 DELETE FROM angajati
9 WHERE id_angajat=100
10 ………………….
11 INTO v_ang;
12 DBMS_OUTPUT.PUT_LINE (‘ Angajatul cu codul :’||
v_ang.ang_cod ||
13 ‘ şi jobul ‘ || v_ang.job || ‘ are salariul ‘ || v_ang.sal);
14 END;
c. RETURNING id_angajat, salariu, id_job
Pentru ca următorul bloc PL/SQL sa fie corect trebuie adaugat la linia 8
următorul cod:

SQL > DECLARE


2 TYPE ang_record_type IS RECORD (
3 nume VARCHAR2(20),
4 departament NUMBER);
5 ang_record ang_record_type;
A 11 6 BEGIN d
7 SELECT nume, id_departament
8 …………………….
9 FROM angajati WHERE id_angajat = 100;
11 DBMS_OUTPUT.PUT_LINE (‘Nume’ || ang_record.nume ||’
Departament ‘ ||
13 ang_record.departament);
14 END;
d. INTO ang_record

13 din 29
Pentru ca următorul bloc PL/SQL sa fie corect trebuie adaugat la linia 6
următorul cod:

1 DECLARE
2 TYPE typetablou IS TABLE OF NUMBER;
3 tablou typetablou:= typetablou();
A 13 4 BEGIN a
5 FOR i IN 1..10 LOOP
6
7 tablou(i) :=i;
8 END LOOP;
9 END;
a. tablou.EXTEND
Să se creeze tabelul test_***(cod NUMBER(4)). Să se introducă în tabe-
lul test_*** 5 înregistrări, pentru care codul va fi generat printr-un con-
tor.
DECLARE
v_contor NUMBER(6) := 1;
BEGIN
B 15 LOOP
INSERT INTO test_*** VALUES (v_contor);
v_contor := v_contor + 1;
EXIT WHEN v_contor > 5;
END LOOP;
END;
/
Să se creeze tabelul test_***(cod NUMBER(4)). Să se introducă în tabe-
lul test_*** 5 înregistrări, pentru care codul va fi generat printr-un con-
tor. Să se rezolve cerinţa folosind comanda WHILE … LOOP.

DECLARE
v_contor NUMBER(6) := 1;
BEGIN
B 16
WHILE v_contor < 6
LOOP
INSERT INTO test_*** VALUES (v_contor);
v_contor := v_contor + 1;
END LOOP;
END;
/

14 din 29
Să se creeze un bloc anonim în care se declară o variabilă v_job de tip
job_title (%TYPE) a cărei valoare va fi titlul jobului salariatului având
codul 200.

DECLARE
v_job jobs.job_title%TYPE;
BEGIN
B 1 SELECT job_title
INTO v_job
FROM employees e, jobs j
WHERE e.job_id=j.job_id
AND employee_id=200;
DBMS_OUTPUT.PUT_LINE('jobul este '|| v_job);
END;
/
Să se creeze un bloc anonim în care se declară o variabilă v_job de tip
job_title (%TYPE) a cărei valoare va fi titlul jobului salariatului având
codul 200.

DECLARE
v_job jobs.job_title%TYPE;
BEGIN
B 10 SELECT job_title
INTO v_job
FROM employees e, jobs j
WHERE e.job_id=j.job_id
AND employee_id=200;
DBMS_OUTPUT.PUT_LINE('jobul este '|| v_job);
END;
/

15 din 29
Să se creeze un bloc anonim în care se declară o variabilă v_job de tip
job_title (%TYPE) a cărei valoare va fi titlul jobului salariatului având
codul 200.

Să se rezolve problema anterioară utilizând variabile de legătură. Să se


afiseze rezultatul atât din bloc, cât şi din exteriorul acestuia.

VARIABLE rezultat VARCHAR2(35)


B 11 BEGIN
SELECT job_title
INTO :rezultat
FROM employees e, jobs j
WHERE e.job_id=j.job_id AND employee_id=200;
DBMS_OUTPUT.PUT_LINE('rezultatul este '|| :rezultat);
END;
/
PRINT rezultat
Să se creeze un bloc anonim în care se declară o variabilă v_job_hiredate
de tip hire_date%TYPE şi o variabil v_emp_salary de tip salary%TYPE
pentru angajatul care are ID=100.

DECLARE
v_emp_hiredate employees.hire_date%TYPE;
v_emp_salary employees.salary%TYPE;
BEGIN
B 3 hire_date, salary
INTO v_emp_hiredate, v_emp_salary
FROM employees
WHERE employee_id = 100;
DBMS_OUTPUT.PUT_LINE('Data_angajarii este: ' ||
v_emp_hiredate ||
' şi Salariu este: ' || v_emp_salary);
END;
/

16 din 29
Să se creeze un bloc anonim prin care în functie de abrevierea anotimpu-
rilor (P, V, T, I) introdusă de utilizator, se afisează un mesaj care specifi-
ca anotimpul respectiv.

ACCEPT a PROMPT 'a='


DECLARE
v_a CHAR(2):=UPPER('&a');
BEGIN
B 14 CASE v_a
WHEN 'P' THEN DBMS_OUTPUT.PUT_LINE('primavara');
WHEN 'V' THEN DBMS_OUTPUT.PUT_LINE('vara');
WHEN 'T' THEN DBMS_OUTPUT.PUT_LINE('toamna');
WHEN 'I' THEN DBMS_OUTPUT.PUT_LINE('iarna');
ELSE DBMS_OUTPUT.PUT_LINE('este o eroare!');
END CASE;
END;
/

17 din 29
Să se introducă în structura tabelului salariat_*** câmpul stea. Să se cre-
eze un bloc PL/SQL care va reactualiza acest câmp, introducând o steluţă
pentru fiecare 1000$ din valoarea salariului unui angajat al cărui cod este
specificat.

ALTER TABLE salariat_***


ADD stea VARCHAR2(20);
DEFINE p_cod_ang = 1
DECLARE
v_cod_ang salariat_***.cod_ang%TYPE := &p_cod_ang;
v_salariu salariat_***.salariu%TYPE;
v_stea salariat_***.stea%TYPE := NULL;
BEGIN
SELECT NVL(ROUND(salariu/1000),0)
B 17
INTO v_salariu
FROM salariat_***
WHERE cod_ang = v_cod_ang;
IF v_salariu > 0 THEN
FOR i IN 1..v_salariu LOOP
v_stea := v_stea || '*';
END LOOP;
END IF;
UPDATE salariat_***
SET stea = v_stea
WHERE cod_ang = v_cod_ang;
COMMIT;
END;
/
Să se introduca în tabelul testare(cod NUMBER(2)) 5 inregistrari, avand
codurile egale cu 1, 2, 3, 4 respectiv 5. Care din urmatoarele variante nu
executa acest deziderat?

c. DECLARE
A 16 v_contor NUMBER(2) := 1; c
BEGIN
FOR i IN 1…5 LOOP
INSERT INTO testare VALUES (v_contor);
END LOOP;
END;

18 din 29
Să se rezolve problema anterioară utilizând variabile de legătură. Să se
afişeze rezultatul atât din bloc, cât şi din exteriorul acestuia.

VARIABLE rezultat VARCHAR2(35)


BEGIN
SELECT job_title
B 2 INTO :rezultat
FROM employees e, jobs j
WHERE e.job_id=j.job_id AND employee_id=200;
DBMS_OUTPUT.PUT_LINE('rezultatul este '|| :rezultat);
END;
/
PRINT rezultat
Scrieţi un bloc PL/SQL în care stocaţi prin variabile de substituţie un cod
de angajat, un cod de departament şi procentul cu care se măreste salariul
acestuia. Să se mute salariatul în noul departament şi să i se crească sala-
riul în mod corespunzător. Dacă modificarea s-a putut realiza (există în
tabelul emp_*** un salariat având codul respectiv) să se afiseze mesajul
“Actualizare realizata”, iar în caz contrar mesajul “Nu exista un angajat
cu acest cod”

DEFINE p_cod_sal= 200


DEFINE p_cod_dept = 80
DEFINE p_procent =20
DECLARE
v_cod_sal emp_***.employee_id%TYPE:= &p_cod_sal;
B 13
v_cod_dept emp_***.department_id%TYPE:= &p_cod_dept;
v_procent NUMBER(8):=&p_procent;
BEGIN
UPDATE emp_***
SET department_id = v_cod_dept,
salary=salary + (salary* v_procent/100)
WHERE employee_id= v_cod_sal;
IF SQL%ROWCOUNT =0 THEN
DBMS_OUTPUT.PUT_LINE('Nu exista un angajat cu acest cod');
ELSE DBMS_OUTPUT.PUT_LINE('Actualizare realizata');
END IF;
END;
/

19 din 29
Scrieţi un bloc PL/SQL în care stocaţi salariul unui angajat într-o variabi-
lă de substituţie. În partea executabilă a blocului să se calculeze salariul
anual şi bonusul pe care îl primeste salariatul (dacă salariul anual >=
20000 atunci bonusul este 2000, dacă salariul anual este cuprins între
10000 şi 20000 bonusul este 1000, iar dacă salariul anual < 10000 atunci
bonusul este 500. Să se afiseze bonusul.

DEFINE p_salariu = 5000


DECLARE
v_salariu NUMBER(8):=&p_salariu;
v_bonus NUMBER(8);
B 12 v_salariu_anual NUMBER(8);
BEGIN
v_salariu_anual:= v_salariu*12;
IF v_salariu_anual>=20000
THEN v_bonus:=2000;
ELSIF v_salariu_anual >10000 AND v_salariu_anual<20000
THEN v_bonus:=1000;
ELSE v_bonus:=500;
END IF;
DBMS_OUTPUT.PUT_LINE('Bonusul este ' || v_bonus);
END;
/
Se dă functia de mai jos ,care permite calcularea unui impozit pe salariu
de 10%.

CREATE FUNCTION impozit(p_value IN NUMBER)


RETURN NUMBER IS
BEGIN
A 31 RETURN(p_value*0.1); c
END impozit;
Care este sintaxa corecta pentru a apela aceasta functie?

c. SELECT id_angajat, nume, salariu, impozit(salariu) tax


FROM angajati
WHERE id_departament=50;

20 din 29
Se dă următorul bloc PL/SQL

DECLARE
v_salariu NUMBER(8):=&p_salariu;
v_bonus NUMBER(8);
v_salariu_anual NUMBER(8);
BEGIN
v_salariu_anual:=v_salariu*12;
IF v_salariu_anual>=20000
THEN v_bonus:=0.01 * v_salariu_anual;
a
A 5 ELSIF v_salariu_anual >10000 AND v_salariu_anual <20000
?
THEN v_bonus:=0.02* v_salariu_anual;
ELSE v_bonus:=100;
END IF;
DBMS_OUTPUT.PUT_LINE(Bonusul este'|| v_bonus);
END;

Care din urmatoarele afirmatii nu este corecta?

a. Blocul genereaza o eroare, deoarece variabila p_salariu nu este


initializata
Se dă următorul bloc PL/SQL

DECLARE
TYPE tablou_numar IS TABLE OF NUMBER
INDEX BY PLS_INTEGER;
v_tablou tablou_numar;
BEGIN
FOR i IN 1...10 LOOP
v_tablour(i) := i*i*i;
END LOOP;
FOR i IN v_tablou.FIRST..v_tablou.LAST LOOP
A 18 v_tablour(i) := NULL; c
END LOOP;
DBMS_OUTPUT.PUT_LINE(‘tabloul are ‘ || v_tablou.COUNT ||
‘elemente’);
v_tablou.delete;
DBMS_OUTPUT.PUT_LINE(‘tabloul are ‘ || v_tablou.COUNT ||
‘elemente’);
END;
În urma executiei blocului se obtine următorul rezultat:

c. tabloul are 10 elemente


tabloul are 0 elemente
21 din 29
Se dă următorul bloc PL/SQL:
DECLARE
TYPE tabimb IS TABLE OF VARCHAR2(50);
tab1 tabimb;
tab2 tabimb:= tabimb ();
BEGIN
IF tab1 IS NULL THEN
DBMS_OUTPUT.PUT_LINE(‘tab1 este NULL’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘tab1 este NOT NULL’);
A 17 END IF; b
IF tab2 IS NULL THEN
DBMS_OUTPUT.PUT_LINE(‘tab2 este NULL’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘tab2 este NOT NULL’);
END IF;
END;
În urma executiei acestui bloc se obtine următorul rezultat:

b. tab1 este NULL


tab2 este NOT NULL
Se dă următorul bloc PL/SQL:

DECLARE
carte VARCHAR2(20);
autor VARCHAR(15) DEFAULT 'Eminescu' ;
BEGIN
A 3 d
DBMS_OUTPUT.PUT_LINE(carte||' '||autor);
END;

Care din urmatoarele afirmatii este corecta?

d. Blocul se executa fără erori şi afiseaza 'Eminescu'

22 din 29
Se dă următorul bloc PL/SQL:

DECLARE
nume VARCHAR2(15);
v_nr INTEGER;
BEGIN
SELECT LENGTH(nume) INTO v_nr
A 4 b
FROM dual;
DBMS_OUTPUT.PUT_LINE('Sirul are '||v_nr||'caractere');
END;

Care din urmatoarele afirmatii este adevarata?

b. Blocul se executa fără erori şi afisaza 'Sirul are caractere')


Se dă următorul bloc PL/SQL:

BEGIN
SELECT nume_job
INTO :rezultat
FROM angajat a, joburi b
WHERE a.id_job=b.id_job
A 6 AND id_angajat=100; b
DBMS_OUTPUT_LINE('Numele jobului este'|| :rezultat);
END;

Care din urmatoarele afirmatii este adevarata?

b. Executia blocului se incheie cu o eroare, deoarece variabila de


legatura rezultat nu este declarata în afara blocului PL/SQL

23 din 29
Se dă următorul bloc PL/SQL:

DECLARE
v_cod_sal angajati.id_angajat%TYPE:= 100;
v_cod_dept angajati.id_departament%TYPE:= 10;
v_procent NUMBER(8):=20;
BEGIN
UPDATE angajati
SET id_departament = v_cod_dept,
salariu=salariu + (salariu* v_procent/100)
WHERE id_angajat = v_cod_sal;
IF SQL%ROWCOUNT = 0 THEN
A 7 d
DBMS_OUTPUT.PUT_LINE (‘Nu exista un angajat cu acest cod’);
ELSE
COMMIT;
DBMS_OUTPUT.PUT_LINE (‘Actualizare realizata’);
END IF;
END;

Care dintre urmatoarele afirmatii este adevarata?

d. Blocul se va executa fără erori şi afiseaza mesajul ‘Nu exista un


angajat cu acest cod’ daca angajatul avand codul 100 nu exista în
tabelul angajati sau mesajul ‘Actualizare realizata’ în caz contrar.

24 din 29
Se dă următorul bloc PL/SQL:

DECLARE
v_nume angajati.nume%TYPE;
v_data angajati.data_angajarii%TYPE;
CURSOR c IS
SELECT nume, data_angajarii
FROM angajati;
BEGIN
OPEN c;
LOOP
A 26 INSERT INTO informatii (nume_angajat, data_angajarii) a
VALUES (v_nume, v_data);
EXIT WHEN c%NOTFOUND;
END LOOP;
COMMIT;
END;

Care dintre urmatoarele afirmatii este adevarata?

a. Blocul se executa fără erori, introducandu-se în tabelul


informatii o linie cu toate valorile null , respectiv toate liniile din
tabelul angajati

25 din 29
Se dă urmatorul bloc PL-SQL:

DECLARE
TYPE typetablou IS TABLE OF NUMBER;
tablou typetablou:=typetablou();
BEGIN
FOR; IN 1..10 LOOP
tablou(i):=i;
END LOOP;
DBMS_OUTPUT.PUT_LINE (Tabloul are’||tablou.COUNT||’elemente’);
FOR:in tablou.FIRST..tablou.LAST LOOP
tablou(i):=NULL;
END LOOP;
DBMS_OUTPUT.PUT_LINE(Tabloul are’||tablou.COUNT||’elemente’);
tablou.TRIM(tablou.COUNT);
?
C 2 DBMS_OUTPUT.PUT_LINE(Tabloul are’||tablou.COUNT||’elemente’);
c
END;

Ce se va afişa la execuţia blocului de mai sus?

a. Tabloul are 10 elemente


Tabloul are 10 elemente
Tabloul are 0 elemente

b. Nu afiseaza nimic

c. Tabloul are 10 elemente


Tabloul are 0 elemente
Tabloul are 10 elemente

d. EROARE

26 din 29
Se defineste un trigger care determina inserarea unei linii în tabelul anga-
jati_log atunci cand salariul unui angajat este marit. Care dintre urmatoa-
rele variante este corecta?

a. CREATE TRIGGER trigger_salariu


AFTER UPDATE OF salariu ON angajati
FOR EACH ROW
A 41 BEGIN a
IF :NEW.salariu>:OLD.salariu THEN
INSERT INTO angajati_log (utilizator, data, angajat, salariu_vechi,
salariu_nou)
VALUES (USER, SYSDATE, :OLD.id_angajat, :OLD.salariu,
:NEW.salariu);
END IF;
END;
Se presupune ca a fost creat tabelul dept(id_depatament, nr_angajati),
care mentine pentru fiecare departament numarul de angajati care lucrea-
za în acesta. Prin comanda urmatoare se defineste vizualizarea
view_angajati:

CREATE VIEW view_angajati AS


SELECT id_angajat, nume, prenume, id_departament FROM angajati;

Care este varianta corecta prin care se defineste un trigger care va deter-
mina incrementarea cu 1, a numarului de angajati din tabelul dept daca în
vizualizare este inserata o inregistrare, respective decrementarea cu 1 a
numarului de angajati din tabelul dept daca din vizualizare este stearsa o
A 42 inregistrare? b

b. CREATE TRIGGER trig_dept


INSTEAD OF INSERT OR DELETE ON view_angajati
FOR EACH ROW
BEGIN
IF INSERTING THEN
UPDATE dept SET nr_angajati = nr_angajati +1;
WHERE id_departament = :NEW.id_departament;
ELSE
UPDATE dept SET nr_angajati = nr_angajati -1;
WHERE id_departament = :OLD.id_departament;
END IF;END;

27 din 29
Se presupune ca asupra tabelului angajati au fost definiti urmatorii 4
triggeri LMD:

- trigger 1 de tip BEFORE INSERT la nivel de comanda;


- trigger 2 de tip BEFORE UPDATE la nivel de comanda;
- trigger 3 de tip AFTER UPDATE la nivel de linie;
- trigger 4 de tip AFTER DELETE la nivel de comanda.
A 39 c
O comanda UPDATE actualizeaza 3 inregistrari din tabelul angajati. În
acest caz, de cate ori este executat fiecare trigger (în dreptul numelui
triggerului este trecut numar de executii al acestuia)?

c. Trigger1 - 0
Trigger2 - 1
Trigger3 - 3
Se presupune că într-o sală a unui muzeu pot fi expuse maximum 10 ope-
re de artă. Pentru aceasta, se creează următorul trigger:

CREATE TRIGGER trigger_opere


BEFORE INSERT OR UPDATE OF cod_sala ON opera
FOR EACH ROW
DECLARE
v_max NUMBER := 10;
v_nr NUMBER;
BEGIN
SELECT COUNT(*) INTO v_nr
A 44 FROM opera d
WHERE cod_sala =:NEW.cod_sala;
IF v_nr + 1>v_max THEN
RAISE_APPLICATION_ERROR(-20000,’Prea multe opere de arta);
END IF;
END;

Care dintre urmatoarele variante este corecta?

d. Triggerul este creat fără erori la compilare, dar în cazul anumitor


comenzi LMD asupra tabelului opera va genera eroarea “table
mutating”.

28 din 29
Urmatoarea comanda creaza tabelul audit :

CREATE TABLE audit


(actiune VARCHAR2(20),
utilizator VARCHAR2(30) DEFAULT USER,
data DATE DEFAULT SYSDATE);

Apoi, este definit următorul trigger:

CREATE TRIGGER trig_audit


A 43 AFTER ALTER ON SCHEMA a
BEGIN
INSERT INTO audit(actiune)
VALUES(‘Obiect modificat’);
END;

Care dintre actiunile urmatoare va determina declansarea triggerului creat


şi inserarea unei inregistrari în tabelul audit ?

a. O comanda prin care se adauga o constrangere de cheie primara unui


table existent
Variabila g_mesaj declarata ca mai jos este:

VARIABLE g_mesaj VARCHAR2 (50)


A 8 BEGIN c
:g_mesaj := ‘Invat PL/SQL;
END;
c. Variabila de legatura

29 din 29
10. Blocul urmator afiseaza:
DECLARE
v_x NUMBER(9,2):=10; v_y NUMBER(9,2);
v_message VARCHAR2(20); BEGIN
v_y:= NULL; IF v_x !=v_y THEN
v_message := ‘ NOT EQUAL’;
ELSE v_message := ‘EQUAL’; END IF;
DBMS_OUTPUT.PUT_LINE(v_message); END;
c. EQUAL
EX. Care din urmatoarele afirmatii este adevarata:
a. Pentru a insera un element nou intr-un tablou imbricat, dimensiunea acestuia
trebuie extinsa cu ajutorul metodei EXTEND
14. Care dintre urmatoarele blocuri se executa cu erori?
d. declare alfa interval month;
begin alfa :=interval ‘8’ month;
DBMS_OUTPUT.PUT_LINE(‘alfa = ‘|| alfa); end;
28. Care dintre urmatoarele variante apeleaza corect functia F_TEST care are un
singur parametru numeric?
a. SELECT F_TEST (80) FROM DUAL ;
16[1]. Care dintre urmatoarele declaratii de variabile este corecta?
b. v1 NUMBER(5,2)=10,25; v2 BOOLEAN:=10<20;
v3 DATE=SYSDATE;
29. Care dintre urmatoarele vizualizari poate fi folosita in urmatoarea comanda
pentru a vizualiza codul complet al subprogramului P1:
SELECT TEXT FROM ….
WHERE NAME = UPPER(’P1’);
d. USER_SOURCE
9. Care este varianta corecta pentru afisarea variabilei v_mesaj ?
b. VARIABLE v_mesaj VARCHAR2 (30) BEGIN
:v_mesaj := ‘Invat PL/SQL’; END;
PRINTv_mesaj
1. Care este varianta corecta pentru declararea urmatoarelor variabile?
c v_valoare NUMBER(15) NOT NULL := 0;
v_data_achizitie DATE DEFAULT SYSDATE;
c_valoare CONSTANT NUMBER:= 1000;
v_ cod_opera opere.cod_opera%TYPE;
19. Care este varianta corecta pentru a defini un tablou imbricat de numere care
are ca elemente primele 10 numere naturale?
b. DECLARE TYPE tablou IS TABLE OF NUMBER;
tab tablou:= tablou(); BEGIN FOR i IN 1…10 LOOP
tab.EXTEND; tab(i) := i; END LOOP; END;
15[1] Care este varianta corecta prin care se obtine pentru fiecare department
fisa angajatilor care lucreaza in acesta in rezultat incluzandu-se si departamentele
in care nu lucreaza nimeni?
c. BEGIN
FOR d IN(SELECT nume_departament, id_departament FROM
departamente)LOOP
BDMS_OUTPUT.PUT_LINE(’Departamentul’|| d. nume_departament);
FOR a IN( SELECT nume FROM angajati
WERE id_departament=d. id_departament)LOOP
DBMS_OUTPUT.PUT_LINEA(’Angajatul’||a.nume);
END LOOP; END LOOP; END;
20. Care este varianta de bloc PL/SQL corecta pentru a mentine intr-un vector
codurile angajatilor care au salariul mai mic decat 20000 si lucreaza in
departamentul 90?
b. DECLARE
TYPE t_id IS VARRAY(100) OF angajati.id_angajat%TYPE;
v_id t_id :=t_id();
BEGIN
SELECT id_angajat BULK COLLECT INTO v_id
FROM angajati
WHERE id_departament=90 AND salariu < 20000; END;
21. Care este varianta corecta de cod PL/SQL care sterge din tabelul joburi,
joburile pentru care salariul minim este 4000 sau 8200, daca aceste valori sunt
mentinute intr-un vector?
a. DECLARE
TYPE min_sal IS VARRAY(20) OF NUMBER;
v_min_sal min_sal:=min_sal(4000,8200);
BEGIN
FORALL i IN v_min_sal.FIRST..v_min_sal. LAST
DELETE FROM joburi
WHERE salariu_min=v_min_sal(i); END;
22. Care este varianta corecta prin care se adauga in tabelul angajati un nou
camp numit telefon de tip tablou imbricat, pt care se vor stoca pt fiecare salariat
numerele sale de telefon, si apoi se insereaza o linie noua in tabel?
a. CREATE TYPE lista AS TABLE OF VARCHAR2(20);
ALTER TABLE angajati
ADD (telefon lista) NESTED TABLE telefon STORE AS tabel_tel;
INSERT INTO angajati
VALUES(200,’xxx’,4000,40000,lista(0214567898,0214567899));
23. Care este varianta corecta prin care se incarca date dintr-un cursor intr-o
colectie?
b. DECLARE
TYPE tip_job IS TABLE OF joburi.nume_job%TYPE;
v_nume tip_job;
CURSOR c_joburi IS SELECT nume_job FROM joburi;
BEGIN
OPEN c_joburi;
FETCH c_joburi BULK COLLECT INTO v_nume;
CLOSE c_joburi; END;
34. Care este varianta corecta pentru a crea specificatia unui pachet, care
defineste un cursor pentru obtinerea datelor si o procedura ce actualizeaza campul
id_job al unui angajat cu un anumit cod?
c. CREATE OR REPLACE PACKAGE manager_pkg IS
CURSOR joburi_curs IS
SELECT id_angajat, id_job FROM angajati;
PROCEDURE update_job(p_ang_id IN angajati.id_angajat%TYPE,
P_id_job OUT angajati.id_job%TYPE);
END manager_pkg;
24. Care este varianta incorecta prin care se obtin numele si salariul angajatilor
care au salariul mai mic decat 2500 si nu lucreaza in departamentul avand codul
80?
b. DECLARE
v_sal :=2500;
v_dept := 80;
BEGIN
FOR ind IN (SELECT nume, salariu
FROM angajati
WHERE salariu<var_sal AND id_departament<>var_dept)
LOOP
DBMS_OUTPUT.PUT_LINE(‘Salariatul ’||ind_nume||’ are salariul ‘||
ind_salariu);
END LOOP;
END;
EX. Care este varianta corecta pentru declararea urmatoarelor variabile?
c. c_valoare CONSTANT NUMBER := 1000;
v_cod_dep departamente.id_departament%TYPE;
v_dep departamente%ROWTYPE;
40. Care este varianta corecta care defineste un trigger la nivel de comanda ce
determina inserarea in tabelul audit_angajati a unui mesaj corespunzator tipului de
comanda LMD executata asupra tabelului angajati?
c. CREATE TRIGGER trigger_audit_angajati
AFTER INSERT OR DELETE OR UPDATE ON angajati
BEGIN
IF INSERTING THEN
INSERT INTO audit_angajati (actiune)
VALUES (‘Inserare’);
ELSIF DELETING THEN
INSERT INTO audit_angajati (actiune)
VALUES (‘Stergere’);
ELSE
INSERT INTO audit_angajati (actiune)
VALUES (‘Actualizare’);
END IF;
END;
25. Care este varianta corecta prin care se afiseaza numele si prenumele primelor
5 persoane angajate in luna martie in anul 1997?
b. DECLARE
v_nume angajati.nume%TYPE; v_prenume angajati.prenume%TYPE;
CURSOR c IS
SELECT nume, prenume FROM angajati
WHERE TO_CHAR(data_angajarii, ‘MM-YYYY’)=’03-1997’
ORDER BY data_angajarii;
BEGIN
OPEN c;
LOOP
FETCH c INTO v_nume, v_prenume;
EXIT WHEN c%ROWCOUNT>5 OR c%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_nume||’ ‘|| v_prenume);
END LOOP;
CLOSE c;
END;
EX. Care este varianta corecta de definire a unui pachet care contine o constanta
avand valoarea 600 si o functie care verifica, folosind acea constanta, daca un
angajat lucreaza in companie de mai mult de 50 de ani?
b. CREATE OR REPLACE PACKAGE check_ang_pkg IS
g_max_length_of_service CONSTANT NUMBER := 600;
PROCEDURE check_data_angajarii
(p_date OUT angajati.data_angajarii%TYPE);
END check_ang_pkg;
CREATE OR REPLACE PACKAGE check_ang_pkg IS
PROCEDURE check_data_angajarii
(p_date IN angajati.data_angajarii%TYPE) IS
BEGIN
IF MONTHS_BETWEEN(SYSDATE, p_date) >
g_max_length_of_service THEN
RAISE_APPLICATION_ERROR(-20202, 'Varsta de pensionare');
END IF;
END check_data_angajarii;
EX. Care este varianta corectă pentru a defini doi vectori avand dimensiunea
maximă 3, iniţializaţi prin liste de valori, şi un al treilea, care va avea ca
elemente, produsul pe componente a celor doi vectori?
a. DECLARE
TYPE vector IS VARRAY(3) OF NUMBER
v_1 vector :=vector(1,2,3); v_2 vector :=vector(100,200,300)
v_produs vector :=vector();
BEGIN
FOR i in 1..3 LOOP
v_produs(i)* v_2(i)
END LOOP; END
37. Care dintre urmatoarele afirmatii nu este corecta?
d. Un trigger la nivel de linie este executat o singura data, indiferent de numarul
de linii afectate de comanda declansatoare.
38. Care dintre urmatoarele afirmatii este corecta?
a. Blocul PL/SQL care descrie act unui trigger nu poate cont com COMIT.
X6. 6.Care din urmatoarele afirmatii este adevarata?'
a.Pentru a insera un element nou intr-un tablou imbricat, dimensiunea
acestuia trebuie extinsa cu ajutorul metodei EXTEND.
2. Care din urmatoarele declaratii de valabilitate este corecta?
b. v_id_student NUMBER(5);
v_nume_student VARCHAR2(35) NOT NUL:=’Ionescu’;
v_prenume_student studenti.prenume%TYPE;
v_data DATE:=SYSDATE+1;
X3. 3. Care este varianta corecta pentru afisarea variabilei v_mesaj?
b.VARIABLE v_mesaj VARCHAR2(50)
BEGIN
:v_mesaj := ' Invat PL/SQL ';
PRINT v_mesaj;
END;
/
X8. 8.Care este varianta corecta pentru a folosi un ciclu cursor cu
subcereri care sa afiseze numele si salariul salariatilor care au
salariul mai mic decat o valoare introdusa de la tastatura?
b.
DECLARE
v_sal number:=&p_sal;
BEGIN
FOR c IN (SELECT nume, salariu
FROM angajati WHERE salariu < v_sal) LOOP
DBMS_OUTPUT.PUT_LINE('Salariatul '||c.nume|| ' are salariul ' ||c.salariu);
END LOOP;
END;
X5. 5.Care este varianta corecta pentru crearea unui cursor explicit care sa
afiseze, ID-ul, numele si salariul angajatilor care lucreaza in
departamentul 30?
a.
DECLARE
CURSOR ang_cursor IS
SELECT nume, salariu FROM angajati
WHERE id_departament =30;
v_ang_id angajati.id_angajat%TYPE;
v_nume angajati.nume%TYPE;
v_sal angajati.salariu%TYPE;
BEGIN
OPEN ang_cursor;
LOOP
FETCH ang_cursor INTO v_ang_id, v_nume, v_sal;
EXIT WHEN ang_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( v_nume||' '||v_sal);
END LOOP;
END;
b.
DECLARE
CURSOR ang_cursor IS
SELECT id_angajat, nume, salariu FROM angajati
WHERE id_departament =30;
v_nume angajati.nume%TYPE;
v_sal angajati.salariu%TYPE;
BEGIN
OPEN ang_cursor;
LOOP
FETCH ang_cursor INTO v_nume, v_sal;
EXIT WHEN ang_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( v_nume||' '||v_sal);
END LOOP;
END;
c.
DECLARE
CURSOR ang_cursor IS
SELECT id_angajat,nume, salariu FROM angajati
WHERE id_departament =30;
v_ang_id angajati.id_angajat%TYPE;
v_nume angajati.nume%TYPE;
v_sal angajati.salariu%TYPE;
BEGIN
OPEN ang_cursor;
LOOP
FETCH ang_cursor INTO v_ang_id,v_nume, v_sal;
EXIT WHEN ang_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( v_nume||' '||v_sal);
END LOOP;
END;
X9. 9.Care este varianta corecta prin care se afiseaza numarul total de
angajati, respectiv numarul de angajati pentru fiecare job?
a.
DECLARE
TYPE tip_job IS TABLE OF joburi.nume_job%TYPE;
TYPE tip_nr IS TABLE OF NUMBER;
t_job tip_job;
t_nr tip_nr;
BEGIN
SELECT nume_job, COUNT(*) BULK COLLECT INTO t_job, t_nr
FROM angajati a, joburi j
WHERE a.id_job = j.id_job
GROUP BY nume_job;
FOR i IN 1..t_job.COUNT-1 LOOP
DBMS_OUTPUT.PUT_LINE ('Pe jobul '||t_job(i) || ' lucreaza ' ||
t_nr(i) || ' angajati');
END LOOP;
DBMS_OUTPUT.PUT_LINE ('Numarul total de angajati este ' || t_nr(t_nr.LAST));
END;
b.
DECLARE
TYPE tip_job IS TABLE OF joburi.nume_job%TYPE;
TYPE tip_nr IS TABLE OF NUMBER;
t_job tip_job;
t_nr tip_nr;
BEGIN
SELECT nume_job, COUNT(*) BULK COLLECT INTO t_job, t_nr
FROM angajati a, joburi j
WHERE a.id_job = j.id_job
GROUP BY GROUPING SETS (nume_job,());
FOR i IN 1..t_job.COUNT-1 LOOP
DBMS_OUTPUT.PUT_LINE ('Pe jobul '||t_job(i)|| ' lucreaza ' ||
t_nr(i) || ' angajati');
END LOOP;
DBMS_OUTPUT.PUT_LINE ('Numarul total de angajati este ' || t_nr(t_nr.LAST));
END;
c.
DECLARE
TYPE tip_job IS TABLE OF joburi.nume_job%TYPE;
TYPE tip_nr IS TABLE OF NUMBER;
t_job tip_job;
t_nr tip_nr;
BEGIN
SELECT nume_job, COUNT(*) BULK COLLECT INTO t_job, t_nr
FROM angajati a, joburi j
WHERE a.id_job = j.id_job
GROUP BY ROLLUP (nume_job, ());
FOR i IN 1..t_job.COUNT-1 LOOP
DBMS_OUTPUT.PUT_LINE ('Pe jobul ' ||t_job(i)|| ' lucreaza ' ||
t_nr(i) || ' angajati');
END LOOP;
DBMS_OUTPUT.PUT_LINE ('Numarul total de angajati este ' || t_nr(t_nr.LAST));
END;
X10. 10. Care este varianta corecta prin care se adauga in tabelul angajati un
nou camp numit telefon de tip tablou imbricat, prin care se vor stoca
pentru fiecare salariat numerele sale de telefon, si apoi se insereaza
o linie noua in tabel?
c.CREATE TYPE lista AS TABLE OF VARCHAR2(20);
ALTER TABLE angajati
ADD (telefon lista) NESTED TABLE telefon STORE AS tabel_tel;
INSERT INTO angajati(telefon)
VALUES(200,'xxx', 4000, 40000, lista(0214567898,0214567899));
X2. 2. Care este varianta corecta pentru declararea urmatoarelor variabil
c_valoare CONSTANT NUMBER := 1000;
v_cod_dep departamente.id_departament%TYPE;
v_dep departamente%ROWTYPE;
X4. 4 Care este varianta incorecta prin care se afiseaza numele si prenumele
primelor 5 persoane angajate in luna martie in anul 1997?
c.
BEGIN
FOR c IN (SELECT * FROM (
SELECT nume v_nume, prenume v_prenume FROM angajati
WHERE TO_CHAR(data_angajarii,'MM-YYYY') = '03-1997'
ORDER BY data_angajarii DESC)
WHERE ROWNUM<=5) LOOP
DBMS_OUTPUT.PUT_LINE(c.v_nume || ' '||c.v_prenume);
END LOOP;
END;
X1. Care nu este varianta corecta de cod PL/SQL care sterge din tabelul
joburi, joburile pentru care salariul minim este 4000 sau 8200, daca
aceste valori sunt mentinute intr-un vector?
b.
DECLARE
TYPE min_sal IS VARRAY(20) OF NUMBER;
v_min_sal min_sal:= min_sal(4000,8200);
BEGIN
FORALL i IN v_min_sal.FIRST..v_min_sal.LAST
DELETE FROM joburi
WHERE salariu_min = v_min_sal(i);
END;
32. Care tabel/vizualizare poate fi folosit/folosita in urmatoarea comanda pentru a
obtine informatii despre procedurile si functiile detinute de utilizatorul curent?
SELECT *
FROM …..
WHERE OBJECT_TYPE IN (‘PROCEDURE’ , ‘FUNCTION’);
d. USER_OBJECTS
15. Ce comanda SQL*Plus ar putea sa preceada blocul de mai jos pentru ca in
acesta sa se utilizeze valoarea data variabilei sem?
DECLARE
v_sem CHAR(2):=UPPER(‘&sem’);
BEGIN
CASE v_sem
WHEN ‘I’ THEN DBMS_OUTPUT.PUT_LINE(‘SEMESTRUL I’);
WHEN ‘II’ THEN DBMS_OUTPUT.PUT_LINE(‘SEMESTRUL II’);
ELSE DBMS_OUTPUT.PUT_LINE(‘este o eroare!’);
END CASE;
END;
a. ACCEPT sem PROMPT ‘sem=’
EX. Ce se va afisa in urma executiei urmatorului bloc?
SQL> DEFINE p_a = 'xxx'SQL>
DECLARE
2 v_a CHAR(3) := UPPER('&p_a');
3 BEGIN
4 CASE v_a
5 WHEN 'UB' THEN DBMS_OUTPUT.PUT_LINE('Univ. Bucuresti');
6 WHEN 'USH' THEN DBMS_OUTPUT.PUT_LINE('Univ. Spiru Haret');
7 ELSE DBMS_OUTPUT.PUT_LINE('Este o eroare!');
8 END CASE;
9 END;
10 /
d. Este o eroare
EX. 30 Ce trebuie adaugat la linia 9 pentru ca urmat func sa fie corect creata?
1 CREATE OR REPLACE FUNCTION nr_sal (v_dept NUMBER)
2 RETURN NUMBER IS3 v_numar NUMBER
(3);
4 BEGIN
5 SELECT COUNT(*)
6 INTO v_numar
7 FROM angajati
8 WHERE id_departament = v_dept;
9 ………………………………………………………..
10 END nr_sal; d. RETURN v_numar
35. Ce trebuie adaugat la linia 11 pentru ca in urmatorul bloc PL/SQL sa se
foloseasca corect cursorul?
1 DECLARE
2 CURSOR c_ang IS
3 SELECT *
4 FROM angajati
5 WHERE TO_CHAR(data_angajarii,’YYYY’)=2000
6 FOR UPDATE OF salariu NOWAIT;
7 BEGIN
8 FOR v_c_ang IN c_ang LOOP
9 UPDATE angajati
10 SET salariu=salariu+1000
11 ………………………..
12 END LOOP;
13 END; b. WHERE CURRENT OF c_ang;
EX. Codul următor:
DECLARE
PROCEDURE p1(val NUMBER)
IS
BEGIN
UPDATE angajaţi
SET salariu=salariu+val
WHERE cod_departament=10;
END;
BEGIN
p1(700);
END c. declară o procedura locală cu un parametru de tip IN
3. Codul sursa de mai jos defineste un pachet cu ajutorul caruia, utilizand un
subprogram functie si un cursor, se poate obtine salariul minim inregistrat pentru
angajati si lista angajatilor care au salariul mai mare sau egal decat acel minim
+1000.
CREATE OR REPLACE PACKAGE pachet_min_sal AS
CURSOR c_ang(nr NUMBER) RETURN angajati % ROWTYPE;
FUNCTION f_min RETURN NUMBER ;
END pachet_min_sal;
CREATE OR REPLACE PACKAGE BODY pachet_min_sal AS
CURSOR c_ang(nr NUMBER) RETURN angajati % ROWTYPE IS
SELECT * FROM angajati WHERE salariu >nr+1000;
FUNCTION f_min
RETURN NUMBER IS
minim NUMBER ;
BEGIN
SELECT Min(salariu) INTO minim FROM angajati;
RETURN minim;
END f_min;
END pachet_min_sal;
Care este varianta corecta de apelare pentru a obtine lista dorita?
a. DECLARE
val_min NUMBER ;
BEGIN
val_min:=pachet_min_sal.f_min;
DBMS_OUTPUT.PUT_LINE(‘Salariul minim ’ || ’ ‘ || val_min);
FORv_cursor IN pachet_min_sal .c_ang(val_min)LOOP
DBMS_OUTPUT.PUT_LINE(v_cursor.nume||’ ‘|| v_cursor.salariu);
END LOOP;
END;
36. In blocul PL/SQL de mai jos
VARIABLE rows_deleted VARCHAR(20)
DECLARE
v_dep_id angajati.id_departament%TYPE:=80;
BEGIN
DELETE FROM angajati
WERE id_departament=v_dep_id;
:rows_deleted:=SQL%ROWCOUNT||’rows deleted’;
END;
PRINT rows_deleted
apare: c. un cursor implicit
EX. In urmatorul bloc PL/SQL se declara variabila v_job de tipul coloanei
nume_job din tabelul joburi,
a carei valoare este numele jobului salariatului avand codul 200.
Pentru ca acest bloc sa fie corect trebuie adaugat la linia 7 urmatorul cod:
SQL> DECLARE
2 v_job joburi.nume_job%TYPE;
3 BEGIN
4 SELECT nume_job
5 INTO v_job
6 FROM angajati a, joburi j
7
8 DBMS_OUTPUT.PUT_LINE('jobul este '|| v_job);
9 END; c. WHERE a.id_job=j.id_job AND id_angajat=200;
EX. Pachetul ang_pkg, a carui spacificatie este data mai jos, contine trei proceduri
overload, denumite gasire_ang.
Parametrii lor de intrare sunt de diferite tipuri de date.
CREATE OR REPLACE PACKAGE ang_pkg IS PROCEDURE
gasire_ang(p_id_angajat IN NUMBER, p_nume OUT VARCHAR2);
-- 1 PROCEDURE gasire_ang(p_id_job IN VARCHAR2, p_nume OUT
VARCHAR2);
-- 2 PROCEDURE gasire_ang(p_data_angajarii IN DATE, p_nume OUT
VARCHAR2);
-- 3 END ang_pkg;
Care varianta este corecta pentru a executa procedura 2?
d. DECLARE v_nume VARCHAR2(30);BEGIN ang_pkg.gasire_ang(sysdate,
v_nume);END;
11. Pentru ca urmatorul bloc PL/SQL sa fie corect trebuie adaugat la linia 8
urmatorul cod:
SQL > DECLARE
2 TYPE ang_record_type IS RECORD (
3 nume VARCHAR2(20),
4 departament NUMBER);
5 ang_record ang_record_type;
6 BEGIN
7 SELECT nume, id_departament
8
9 FROM angajati WHERE id_angajat = 100;
11 DBMS_OUTPUT.PUT_LINE (‘Nume’ || ang_record.nume ||’ Departament ‘
||
13 ang_record.departament);
14 END; d. INTO ang_record
12. Pentru ca urmatorul bloc PL/SQL sa fie corect si sa afiseze codul, salariatul si
jobul angajatului cu codul 100, trebuie adaugat la linia 10 urmatorul cod:
SQL> DECLARE
2 TYPE type_ang IS RECORD (
3 ang_cod angajati.id_angajat%TYPE,
4 sal angajati.salariu%TYPE,
5 job angajati.id_job%TYPE);
6 v_ang type_ang;
7 BEGIN
8 DELETE FROM angajati
9 WHERE id_angajat=100
10
11 INTO v_ang;
12 DBMS_OUTPUT.PUT_LINE (‘ Angajatul cu codul :’|| v_ang.ang_cod ||
13 ‘ si jobul ‘ || v_ang.job || ‘ are salariul ‘ || v_ang.sal);
14 END; c. RETURNING id_angajat, salariu, id_job
EX.12 Pentru ca urmatorul bloc PL/SQL sa fie corect si sa afiseze codul, salariul si
jobul angajatului cu codul 100, trebuie adaugat la linia 8 urmatorul cod:
SQL> DECLARE
2 TYPE typeang IS RECORD ( cod angajati.id_angajat%TYPE,
3 sal angajati.salariu%TYPE, job angajati.id_job%TYPE);
4 v_ang typeang;
5 BEGIN
6 DELETE FROM angajati
7 WHERE id_angajat=100
8 ………………………………………………………..
9 INTO v_ang;
10 DBMS_OUTPUT.PUT_LINE (' Angajatul cu codul :'|| v_ang.cod ||
11 ' si jobul ' || v_ang.job || ' are salariul ' || v_ang.sal);
12 END; b. RETURNING id_angajat, salariu, id_job
13. Pentru ca urmatorul bloc PL/SQL sa fie corect trebuie adaugat la linia 6
urmatorul cod:
1 DECLARE
2 TYPE typetablou IS TABLE OF NUMBER;
3 tablou typetablou:= typetablou();
4 BEGIN
5 FOR i IN 1..10 LOOP
6
7 tablou(i) :=i;
8 END LOOP;
9 END; a. tablou.EXTEND;
27. Parametrii unei functii pot fi: b. Numai de intrare (IN)
EX.31 Se da functia de mai jos, care permite calc unui impozit pe salariu de 10%.
CREATE FUNCTION impozit(p_value IN NUMBER)RETURN NUMBER IS
BEGIN RETURN (p_value * 0.1);
END impozit;
Care este sintaxa corecta pentru a apela acesta functie?
c. SELECT id_angajat, nume, salariu, impozit(salariu) tax
FROM angajati
WHERE id_departament = 50;
EX. .Se da procedura de mai jos, care afla pentru un anume angajat numele si
salariul acestuia.
CREATE OR REPLACE PROCEDURE p_ang (p_id IN
angajati.id_angajat%TYPE,
p_nume OUT angajati.nume%TYPE,
p_salariu OUT angajati.salariu%TYPE)
ISBEGIN SELECT nume,salariu
INTO p_nume, p_salariu
FROM angajati
WHERE id_angajat = p_id;
END p_ang;
Care este sintaxa corecta pentru a apela acesta procedura?
a. DECLAREa_ang_nume angajati.nume%TYPE;
a_ang_sal angajati.salariu%TYPE;
BEGIN
p_ang(180, a_ang_nume, a_ang_sal); END
EX. Se da urmatorul bloc PL/SQL:
DECLARE
v_numar NUMBER;
v_boolean BOOLEAN;
BEGIN v_numar := 25;
v_boolean := NOT(v_numar > 30);
END;
Care dintre urmatoarele afirmatii este adevarata?
b. In urma executiei blocului variabila v_boolean va avea valoarea true.
EX. Se da urmatorul bloc PL/SQL:
DECLARE v_numar NUMBER;
v_boolean BOOLEAN;
BEGIN v_numar := 25;
v_boolean := NOT(v_numar > 30);
END;
Care dintre urmatoarele afirmatii este adevarata?
c. In urma executiei blocului variabila v_boolean va avea valoarea false.
20[2]. Se da urmatorul bloc PL/SQL:
DECLARE
TYPE t_ang IS RECORD(
cod angajati id_angajat%TYPE,
sal angajati.salariu%TYPE,
Job angajati id_job%TYPE);
v_ang t_ang ;
BEGIN
SELECT id_angajat, salariu. Id_job
INTO v_ang
FROM angajati
WHERE id_angajat=100;
DBMS_OUTPUT_LINE('Angalatul cu codul'|| v_ang.cod||
’are salariul in valoare ‘|| v_ang sal);
END;
Stiind ca in tabelul angajati exista angajatul cu codul 100 care are un salariu de
5000 care din urmatoarele afirmatii sunt adevarate?
d. Blocul se executa fara erori si afiseaza ... ’’Angajatul cu codul 100 are salariul
in valoare de 5000
X7._ Se da urmatorul bloc PL/SQL:
DECLARE
TYPE r_ang IS RECORD(
cod angajati id_angajat%TYPE,
sal angajati.salariu%TYPE,
Job angajati id_job%TYPE);
v_ang t_ang ;
BEGIN
SELECT id_angajat, salariu. Id_job
INTO v_ang
FROM angajati
WHERE id_angajat=100;
DBMS_OUTPUT_LINE('Angalatul cu codul'|| v_ang.cod||
’are salariul in valoare ‘|| v_ang sal);
END;
Stiind ca in tabelul angajati exista angajatul cu codul 100 care are
un salariu de 5000, care dintre urmatoarele afirmatii nu este
adevarata?
a.Executia blocului se incheie cu o eroare, deoarece comanda SELECT
utilizeaza coloana id_job care ulterior nu este folosita.
3. Se da urmatorul bloc PL/SQL:
DECLARE
carte VARCHAR2(20);
autor VARCHAR(15) DEFAULT 'Eminescu' ;
BEGIN
DBMS_OUTPUT.PUT_LINE(carte||' '||autor);
END;
Care din urmatoarele afirmatii este corecta?
d. Blocul se executa fara erori si afiseaza 'Eminescu'
4. Se da urmatorul bloc PL/SQL:
DECLARE
nume VARCHAR2(15);
v_nr INTEGER;
BEGIN
SELECT LENGTH(nume) INTO v_nr
FROM dual;
DBMS_OUTPUT.PUT_LINE('Sirul are '||v_nr||'caractere');
END;
Care din urmatoarele afirmatii este adevarata?
c. Blocul se executa fara erori si afisaza 'Sirul are caractere').
5. Se da urmatorul bloc PL/SQL
DECLARE
v_salariu NUMBER(8):=&p_salariu;
v_bonus NUMBER(8);
v_salariu_anual NUMBER(8);
BEGIN
v_salariu_anual:=v_salariu*12;
IF v_salariu_anual>=20000
THEN v_bonus:=0.01 * v_salariu_anual;
ELSIF v_salariu_anual >10000 AND v_salariu_anual <20000
THEN v_bonus:=0.02* v_salariu_anual;
ELSE v_bonus:=100;
END IF;
DBMS_OUTPUT.PUT_LINE(Bonusul este'|| v_bonus);
END;
Care din urmatoarele afirmatii nu este corecta?
a. Blocul genereaza o eroare, deoarece variabila p_salariu nu este initializata.
EX. 6 Se da urmatorul bloc PL/SQL:
BEGIN SELECT nume_job INTO :rezultat
FROM angajati a, joburi b
WHERE a.id_job=b.id_job
AND id_angajat=100;
DBMS_OUTPUT.PUT_LINE('Numele jobului este '|| :rezultat);
END;
Care dintre urmatoarele afirmatii este adevarata?
d. Executia blocului se incheie cu o eroare, deoarece variabila de legatura rezultat
nu este declarata in afara blocului PL/SQL.
7. Se da urmatorul bloc PL/SQL:
DECLARE
v_cod_sal angajati.id_angajat%TYPE:= 100;
v_cod_dept angajati.id_departament%TYPE:= 10;
v_procent NUMBER(8):=20;
BEGIN
UPDATE angajati
SET id_departament = v_cod_dept,
salariu=salariu + (salariu* v_procent/100)
WHERE id_angajat = v_cod_sal;
IF SQL%ROWCOUNT = 0 THEN
DBMS_OUTPUT.PUT_LINE (‘Nu exista un angajat cu acest cod’);
ELSE
COMMIT;
DBMS_OUTPUT.PUT_LINE (‘Actualizare realizata’);
END IF;
END;
Care dintre urmatoarele afirmatii este adevarata?
d. Blocul se va executa fara erori si afiseaza mesajul ‘Nu exista un angajat cu acest
cod’ daca angajatul avand codul 100 nu exista in tabelul angajati sau mesajul
‘Actualizare realizata’ in caz contrar.
26. Se da urmatorul bloc PL/SQL:
DECLARE
v_nume angajati.nume%TYPE;
v_data angajati.data_angajarii%TYPE;
CURSOR c IS
SELECT nume, data_angajarii
FROM angajati;
BEGIN
OPEN c;
LOOP
INSERT INTO informatii (nume_angajat, data_angajarii)
VALUES (v_nume, v_data);
EXIT WHEN c%NOTFOUND;
END LOOP;
COMMIT;
END;
Care dintre urmatoarele afirmatii este adevarata?
a. Blocul se executa fara erori, introducandu -se in tabelul informatii o linie cu
toate valorile null , respectiv toate liniile din tabelul angajati
17. Se da urmatorul bloc PL/SQL
DECLARE
TYPE tabimb IS TABLE OF VARCHAR2(50);
tab1 tabimb;
tab2 tabimb:= tabimb ();
BEGIN
IF tab1 IS NULL THEN
DBMS_OUTPUT.PUT_LINE(‘tab1 este NULL’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘tab1 este NOT NULL’);
END IF;
IF tab2 IS NULL THEN
DBMS_OUTPUT.PUT_LINE(‘tab2 este NULL’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘tab2 este NOT NULL’);
END IF;
END;
In urma executiei acestui bloc se obtine urmatorul rezultat:
b. tab1 este NULL
tab2 este NOT NULL
EX. Se da urmatorul bloc PL/SQL:
DECLARE
nr NUMBER(4) ;
suma NUMBER(4);
info VARCHAR2(50) ;
BEGIN
nr:=0 ;
FOR i IN (SELECT nume_departament nd, nume n, salariu
FROM departmente d, angajati a
WHERE a.id department(+) = d.id department
AND a.id_departament IS NULL) LOOP
nr:=nr+1;
info :=i.nd| |’ ‘| |i.n;
suma:=suma+ i.salariu;
END LOOP;
DBMS_OUTPUT.PUT_LINE(nr);
DBMS_OUTPUT.PUT_LINE(suma);
DBMS_OUTPUT.PUT_LINE(info);
END;
In urma executiei acestui bloc a. apare o eroare
EX. Se da urmatorul bloc PL/SQL
DECLARE
TYPE typetablou IS TABLE OF NUMBER;
tablou typetablou:= typetablou();
BEGIN
FOR i IN 1..10 LOOP
tablou.EXTEND;
tablou(i) :=i;
END LOOP;
DBMS_OUTPUT.PUT_LINE('tabloul are ' || tablou.COUNT || ' elemente');
FOR i IN tablou.FIRST..tablou.LAST LOOP
tablou(i) := NULL;
END LOOP;
DBMS_OUTPUT.PUT_LINE('tabloul are ' || tablou.COUNT || ' elemente');
tablou.TRIM(tablou.COUNT);
DBMS_OUTPUT.PUT_LINE('tabloul are ' || tablou.COUNT || ' elemente');
END;
In urma executiei blocului se obtine urmatorul rezultat:
a. Tabloul are 10 elemente
Tabloul are 10 elemente
Tabloul are 0 elemente
18. Se da urmatorul bloc PL/SQL
DECLARE
TYPE tablou_numar IS TABLE OF NUMBER
INDEX BY PLS_INTEGER;
v_tablou tablou_numar;
BEGIN
FOR i IN 1...10 LOOP
v_tablour(i) := i*i*i;
END LOOP;
FOR i IN v_tablou.FIRST..v_tablou.LAST LOOP
v_tablour(i) := NULL;
END LOOP;
DBMS_OUTPUT.PUT_LINE(‘tabloul are ‘ || v_tablou.COUNT || ‘elemente’);
v_tablou.delete;
DBMS_OUTPUT.PUT_LINE(‘tabloul are ‘ || v_tablou.COUNT || ‘elemente’);
END;
In urma executiei blocului se obtine urmatorul rezultat:
c. tabloul are 10 elemente
tabloul are 0 elemente
EX. Se da urmatorul corp de pachet, care contine doua proceduri overload
denumite add_dept.
CREATE OR REPLACE PACKAGE BODY dept_pkg IS
PROCEDURE add_dept(p_dept NUMBER, p_nume VARCHAR2:=’unknown’)
IS—1
BEGIN
INSERT INTO departamente(id_departament,nume_departament)
VALUES (p_dept, p_nume)
END add_dept;
PROCEDURE add_dept (p_nume VARCHAR:=’unknown’)
IS—2
BEGIN
INSERT INTO departamente (id_departament,nume_departament)
VALUES (departamente_seq.NEXTVAL, p_nume);
END add_dept;
END dept_pkg;
Care varianta este corecta pentru a executa procedura 2?
b. BEGIN
Dept_pkg.add_dept(100,’Training’);
END;
X11. 11. Se defineste un trigger prin care nu se permite micsorarea pretului cartilor
din tabelul “carti”. Care din urmatoarele variante este corecta?
a) CREATE TRIGGER trigger_carti
BEFORE UPDATE OF pret ON carti
FOR EACH ROW
WHEN (NEW.pret<OLD.pret)
BEGIN
RAISE_APPLICATION_ERROR(-20003,’pretul cartilor nu poate fi micsorat’);
END;
16. Sa se introduca in tabelul testare(cod NUMBER(2)) 5 inregistrari, avand
codurile egale cu 1, 2, 3, 4 respectiv 5. Care din urmatoarele variante nu executa
acest deziderat?
c. DECLARE
v_contor NUMBER(2) := 1;
BEGIN
FOR i IN 1..5 LOOP
INSERT INTO testare VALUES (v_contor);
END LOOP;
END;
41. Se defineste un trigger care determina inserarea unei linii in tabelul
angajati_log atunci cand salariul unui angajat este marit. Care dintre urmatoarele
variante este corecta?
a. CREATE TRIGGER trigger_salariu
AFTER UPDATE OF salariu ON angajati
FOR EACH ROW
BEGIN
IF :NEW.salariu>:OLD.salariu THEN
INSERT INTO angajati_log (utilizator, data, angajat, salariu_vechi,
salariu_nou)
VALUES (USER, SYSDATE, :OLD.id_angajat, :OLD.salariu, :NEW.salariu);
END IF;
END;
39. Se presupune ca asupra tabelului angajati au fost definiti urmatorii 4 triggeri
LMD:
- trigger 1 de tip BEFORE INSERT la nivel de comanda;
- trigger 2 de tip BEFORE UPDATE la nivel de comanda;
- trigger 3 de tip AFTER UPDATE la nivel de linie;
- trigger 4 de tip AFTER DELETE la nivel de comanda.
O comanda UPDATE actualizeaza 3 inregistrari din tabelul angajati. In acest caz, de cate
ori este executat fiecare trigger (in dreptul numelui triggerului este trecut numar de
executii al acestuia)?
c. Trigger1 - 0
Trigger2 - 1
Trigger3 – 3
Trigger4 – 0
42. Se presupune ca a fost creat tabelul dept(id_depatament, nr_angajati), care
mentine pentru fiecare departament numarul de angajati care lucreaza in acesta.
Prin comanda urmatoare se defineste vizualizarea view_angajati:
CREATE VIEW view_angajati AS
SELECT id_angajat, nume, prenume, id_departament FROM angajati;
Care este varianta corecta prin care se defineste un trigger care va determina
incrementarea cu 1 a numarului de angajati din tabelul dept daca in vizualizare este
inserata o inregistrare, respective decrementarea cu 1 a numarului de angajati din tabelul
dept daca din vizualizare este stearsa o inregistrare?
b. CREATE TRIGGER trig_dept
INSTEAD OF INSERT OR DELETE ON view_angajati
FOR EACH ROW
BEGIN
IF INSERTING THEN
UPDATE dept SET nr_angajati = nr_angajati +1;
WHERE id_departament = :NEW.id_departament;
ELSE
UPDATE dept SET nr_angajati = nr_angajati -1;
WHERE id_departament = :OLD.id_departament;
END IF;END;
44. Se presupune că într-o sală a unui muzeu pot fi expuse maximum 10 opere de
artă. Pentru aceasta se creează următorul trigger:
CREATE TRIGGER trigger_opere
BEFORE INSERT OR UPDATE OF cod_sala ON opera
FOR EACH ROW
DECLARE
v_max NUMBER := 10;
v_nr NUMBER;
BEGIN
SELECT COUNT(*) INTO v_nr
FROM opera
WHERE cod_sala =:NEW.cod_sala;
IF v_nr + 1>v_max THEN
RAISE_APPLICATION_ERROR(-20000,’Prea multe opere de arta);
END IF;
END;
Care dintre urmatoarele variante este corecta?
d. Triggerul este creat fara erori la compilare, dar in cazul anumitor comenzi
LMD asupra tabelului opera va genera eroarea “table mutating”.
43. Urmatoarea comanda creaza tabelul audit:
CREATE TABLE audit
(actiune VARCHAR2(20),
utilizator VARCHAR2(30) DEFAULT USER,
data DATE DEFAULT SYSDATE);
Apoi, este definit urmatorul trigger:
CREATE TRIGGER trig_audit
AFTER ALTER ON SCHEMA
BEGIN
INSERT INTO audit(actiune)
VALUES(‘Obiect modificat’);
END;
Care dintre actiunile urmatoare va determina declansarea triggerului creat si inserarea
unei inregistrari in tabelul audit?
a. O comanda prin care se adauga o constrangere de cheie primara unui table
existent.
8. Variabila g_mesaj declarata ca mai jos este:
VARIABLE g_mesaj VARCHAR2 (50)
BEGIN
:g_mesaj := ‘Invat PL/SQL;
END; c. Variabila de legatura.
10. Blocul urmator afiseaza:
DECLARE
DBMS_OUTPUT.PUT_LINE(v_message);
END; c. EQUAL
14. Care dintre urmatoarele blocuri se executa cu erori?
d. declare
alfa:= interval’8’ month;
DBMS_OUTPUT.PUT_LINE(‘alfa = ‘|| alfa);
end;
28. Care dint urmat var apel corect func F_TEST care are un singur par num?
a. SELECT F_TEST (80)
FROM DUAL ;
29. Care dintre urmat vizual poate fi fol al subprogr P1: d. USER_SOURCE
9. Care este varianta corecta pentru afisarea variabilei v_mesaj ?
b. VARIABLE v_mesaj VARCHAR2 (30)
END;
3. Care este varianta corectă pentru a defini doi vectori avand dimen maximă 3
c. DECLARE
TYPE vector IS VARRAY(3) OF NUMBER
v_1 vector:=vector(1,2,3); v_2 vector:=vector(100,200,300)
v_produs vector:=vector();
BEGIN
FOR i in 1:3 LOOP
v_produs(i) :=v_produs(i)* v v 2(i)
END LOOP;
END
1. Care este varianta corecta pentru declararea urmatoarelor variabile?
v_valoare NUMBER(15) NOT NULL := 0;
v_data_achizitie DATE DEFAULT SYSDATE;
c_valoare CONSTANT NUMBER:= 1000;
v_ cod_opera opere.cod_opera%TYPE;
19. Care este var corecta pentru a defini un tablou primele 10 numere naturale?
b. DECLARE
tab.EXTEND; tab(i) := i;
END LOOP;
END;
20. Care este var de bloc PL/SQL corecta pentru a mentine angaj care
au salariul mai mic decat 20000 si lucreaza in departamentul 90?
b. DECLARE
TYPE t_id IS VARRAY(100) OF angajati.id_angajat%TYPE;
v_id t_id :=t_id();
BEGIN
SELECT id_angajat BULK COLLECT INTO v_id
END;
21.Care este varianta corecta de cod PL/SQL care sterge din tabelul joburi,
mentinute intr-un vector?
a. DECLARE
TYPE minsal IS VARRAY(20) OF NUMBER; v min sal min sal:=min
sal(4000,8200); BEGIN
FORALL i IN v min sal.FIRST..v min sal. LAST
DELETE FROM joburi
WHERE salariu min=v min sal(i); END;
22. Care este varianta corecta prin care se adauga in tab ang un nou camp
numit telefon de linie noua in tabel?
a. CREATE TYPE lista AS TABLE OF VARCHAR2(20);
ADD (telefon lista) NESTED TABLE telefon STORE AS tabel_tel;
INSERT INTO angajati
VALUES(200,’xxx’,4000,40000,lista(0214567898,0214567899));
23. Care este varianta cor prin care se inca date dintr-un cursor intr-o colectie?
b. DECLARE
TYPE tip_job IS TABLE OF joburi.nume_job%TYPE;
v nume tip_job;
CURSOR c_joburi IS SELECT nume_job FROM joburi;
BEGIN
OPEN c_joburi;
FETCH c_joburi BULK COLLECT INTO v nume; CLOSE c_joburi; END;
34. Care este var corecta pentru a crea specif unui pachet, angajat cu un an cod?
c. CREATE OR REPLACE PACKAGE manager_pkg IS CURSOR joburicurs IS
SELECT id_angajat, id_job FROM angajati; PROCEDURE update_job(p_ang_id IN
angajati.id angajat%TYPE,
P_id_job OUT angajati.id_job%TYPE);
END manager_pkg;
24. Care este var incor prin care se obtin num si salariul angaj care au salariul
mai mic decat 2500 si nu lucreaza in departamentul avand codul 80?
b. DECLARE
v_sal :=2500;
v_dept := 80;
END LOOP;
END;
25. Care este varianta corecta prin care se afiseaza numele si prenumele primelor 5
persoane angajate in luna martie in anul 1997?
b. DECLARE
ORDER BY data_angajarii;
BEGIN
CLOSE c;
END;
37. Care dintre urmatoarele afirmatii nu este corecta?
d. Un trigger la nivel de linie este exec o singura data, indifde numa de linii afectate de
comanda declansatoare.
38. Care dintre urmatoarele afirmatii este corecta?
a. Blocul PL/SQL care descrie act unui trigger nu poate cont com COMIT.
2. Care din urmatoarele declaratii de valabilitate este corecta?
v_id_student NUMBER(5);
v_prenume_student studenti.prenume%TYPE;
v_data DATE:=SYSDATE+1;
40. Care este varianta corecta care def un trigger la niv de com tabel angajati?
c. CREATE TRIGGER trigger_audit_angajati
AFTER INSERT OR DELETE OR UPDATE ON angajati
VALUES (‘Actualizare’);
END IF;
END;
32. Care tabel/vizualizare poate fi folosit/folosita detin de utilizat curent?
SELECT *
FROM …..
WHERE OBJECT_TYPE IN (‘PROCEDURE’ , ‘FUNCTION’);
d. USER_OBJECTS
15. Ce comanda SQL*Plus ar putea sa preceada blocul de mai jos pentru ca in acesta sa
se utilizeze valoarea data variabilei sem?
DECLARE
v_sem CHAR(2):=UPPER(‘&sem’);
END CASE;
END; a. ACCEPT sem PROMPT ‘sem=’
30. Ce trebuie adaugat la linia 9 pentru ca urmat functie sa fie corect creata?
1. CREATE OR REPLACEFUNCTION nr_sal(v_dept NUMBER)
8. WHERE id_departament=v_dept;
9. ………………………………………………………..
10. END nr_sal; c. RETURN v_numar;
35. Ce treb ada la linia 11 in urma bloc PL/SQL sa se folos corect cursorul?
1 DECLARE
2 CURSOR c_ang IS
10 SET salariu=salariu+1000
11 ………………………..
12 END LOOP;
13 END; b. WHERE CURRENT OF c_ang;
33. Codul sursa de mai jos defin un pach mare sau egal decat acel min +1000.
CREATE OR REPLACE PACKAGE pachet_min_sal AS
CURSOR c_ang(nr NUMBER) RETURN angajati % ROWTYPE;
FUNCTION f_min RETURN NUMBER ;
RETURN minim;
END f_min;
END pachet_min_sal;
Care este varianta corecta de apelare pentru a obtine lista dorita?
c. DECLARE
val_min:=pachet_min_sal.f_min;
FORv_cursor IN pachet_min_sal .c_ang(val_min)
END;
36. In blocul PL/SQL de mai jos
VARIABLE rows_deleted VARCHAR(20)
DECLARE
v_dep_id angajati.id_departament%TYPE:=80;
BEGIN
:rows_deleted:=SQL%ROWCOUNT||’rows deleted’;
END;
/
PRINT rows_deleted
apare: c. un cursor implicit
11. Pentru ca urmat bloc PL/SQL sa fie corect trebuie adaug la linia 8 urmat cod:
SQL > DECLARE
2 TYPE ang_record_type IS RECORD (
3 nume VARCHAR2(20),
7 SELECT nume, id_departament
8
9 FROM angajati WHERE id_angajat = 100;
13 ang_record.departament);
14 END; d. INTO ang_record
12. Pentru ca urma bloc PL/SQL sa fie corect si sa afiseze codul, salariatul si jobul
angajatului cu codul 100, trebuie adaugat la linia 10 urmatorul cod:
SQL> DECLARE
2 TYPE type_ang IS RECORD (
3 ang_cod angajati.id_angajat%TYPE,
9 WHERE id_angajat=100
10
11 INTO v_ang;
13 ‘ si jobul ‘ || v_ang.job || ‘ are salariul ‘ || v_ang.sal);
14 END; c. RETURNING id_angajat, salariu, id_job
13. Pentru ca urmat bloc PL/SQL sa fie corect treb adau la linia 6 urmat cod:
1 DECLARE
2 TYPE typetablou IS TABLE OF NUMBER;
3 tablou typetablou:= typetablou();
6
7 tablou(i) :=i;
8 END LOOP;
9 END; a. tablou.EXTEND;
27. Parametrii unei functii pot fi:b. Numai de intrare (IN)
31. Se da functia de mai jos ,care permite de 10%.
CREATE FUNCTION impozit(p_value IN NUMBER)
RETURN NUMBER IS
BEGIN
RETURN(p_value*0.1);
END impozit;
Care este sintaxa corecta pentru a apela aceasta functie?
c. SELECT id_angajat, nume, salariu, impozit(salariu) tax
FROM angajati
WHERE id_departament=50;
3. Se da urmatorul bloc PL/SQL:
DECLARE
carte VARCHAR2(20);
autor VARCHAR(15) DEFAULT 'Eminescu' ;
DBMS_OUTPUT.PUT_LINE(carte||' '||autor);
END;
Care din urmatoarele afirmatii este corecta?
d. Blocul se executa fara erori si afiseaza 'Eminescu'
4. Se da urmatorul bloc PL/SQL:
DECLARE
nume VARCHAR2(15);
v_nr INTEGER;
DBMS_OUTPUT.PUT_LINE('Sirul are '||v_nr||'caractere');
END;
Care din urmatoarele afirmatii este adevarata?
b. Blocul se executa fara erori si afisaza 'Sirul are caractere').
5. Se da urmatorul bloc PL/SQL
DECLARE
v_salariu NUMBER(8):=&p_salariu;
v_bonus NUMBER(8);
v_salariu_anual NUMBER(8);
END IF;
DBMS_OUTPUT.PUT_LINE(Bonusul este'|| v_bonus);
END;
Care din urmatoarele afirmatii nu este corecta?
a. Blocul genereaza o eroare, deoar variab p_salariu nu este initializ.
6. Se da urmatorul bloc PL/SQL:
BEGIN
SELECT nume_job
INTO :rezultat
DBMS_OUTPUT_LINE('Numele jobului este'|| :rezultat);
END;
Care din urmatoarele afirmatii este adevarata?
b. Executia blocului se incheie cu o eroare, deoarece variabila de legatura rezultat nu
este declarata in afara blocului PL/SQL.
7. Se da urmatorul bloc PL/SQL:
DECLARE
v_cod_sal angajati.id_angajat%TYPE:= 100;
v_cod_dept angajati.id_departament%TYPE:= 10;
DBMS_OUTPUT.PUT_LINE (‘Actualizare realizata’);
END IF;
END;
Care dintre urmatoarele afirmatii este adevarata?
d. Blocul se va executa fara erori si afiseaza mesajul ‘Nu exista un angajat cu acest cod’
26. Se da urmatorul bloc PL/SQL:
DECLARE
v_nume angajati.nume%TYPE;
v_data angajati.data_angajarii%TYPE;
CURSOR c IS
EXIT WHEN c%NOTFOUND;
END LOOP;
COMMIT;
END;
Care dintre urmatoarele afirmatii este adevarata?
a. Blocul se executa fara erori, introducandu -se in tabelul informatii o linie cu toate
valorile null , respectiv toate liniile din tabelul angajati
17. Se da urmatorul bloc PL/SQL
DECLARE
TYPE tabimb IS TABLE OF VARCHAR2(50);
tab1 tabimb;
tab2 tabimb:= tabimb ();
DBMS_OUTPUT.PUT_LINE(‘tab2 este NOT NULL’);
END IF;
END;
In urma executiei acestui bloc se obtine urmatorul rezultat:
b. tab1 este NULL
tab2 este NOT NULL
18. Se da urmatorul bloc PL/SQL
DECLARE
TYPE tablou_numar IS TABLE OF NUMBER
INDEX BY PLS_INTEGER;
v_tablou tablou_numar;
DBMS_OUTPUT.PUT_LINE(‘tabloul are ‘ || v_tablou.COUNT || ‘elemente’);
END;
In urma executiei blocului se obtine urmatorul rezultat:
c. tabloul are 10 elemente
tabloul are 0 elemente
16. Sa se introduca in tab testare5 inregistrari, egale cu 1, 2, 3, 4 resp 5. Care din
urmatoarele variante nu executa acest deziderat?
c. DECLARE
BEGIN
FOR i IN 1…5 LOOP
INSERT INTO testare VALUES (v_contor);
END LOOP;
END;
41. Se defin un trigger care determina este marit. Care dintre urmat var e corecta?
a. CREATE TRIGGER trigger_salariu
AFTER UPDATE OF salariu ON angajati
FOR EACH ROW
END IF;
END;
39. Se presup ca asupra tabe angajati au fost defin urmatorii 4 triggeri LMD:
- trigger 1 de tip BEFORE INSERT la nivel de comanda;
- trigger 2 de tip BEFORE UPDATE la nivel de comanda;
- trigger 3 de tip AFTER UPDATE la nivel de linie;
- trigger 4 de tip AFTER DELETE la nivel de comanda.
O comanda UPDATE actualizeaza 3 inregistrari executii al acestuia)?
c. Trigger1 - 0 Trigger2 - 1 Trigger3 – 3
42. Se presupune ca a fost creat tabelul dept care lucreaza in acesta.
Prin comanda urmatoare se defineste vizualizarea view_angajati:
CREATE VIEW view_angajati AS
SELECT id_angajat, nume, prenume, id_departament FROM angajati;
Care este var corecta prin care se defineste un trigger stearsa o inregistrare?
b. CREATE TRIGGER trig_dept
INSTEAD OF INSERT OR DELETE ON view_angajati
FOR EACH ROW
BEGIN
IF INSERTING THEN
UPDATE dept SET nr_angajati = nr_angajati +1;
WHERE id_departament = :NEW.id_departament;
ELSE
UPDATE dept SET nr_angajati = nr_angajati -1;
WHERE id_departament = :OLD.id_departament;
END IF;END;
44. Se presup că într-o sală a unui muzeu 10 opere de artă. următ trigger:
CREATE TRIGGER trigger_opere
BEFORE INSERT OR UPDATE OF cod_sala ON opera
RAISE_APPLICATION_ERROR(-20000,’Prea multe opere de arta);
END IF;
END;
Care dintre urmatoarele variante este corecta?
d. Triggerul este creat fara erori la compilare, dar in cazul anumitor comenzi
LMD asupra tabelului opera va genera eroarea “table mutating”.
43. Urmatoarea comanda creaza tabelul audit:
CREATE TABLE audit
(actiune VARCHAR2(20),
Apoi, este definit urmatorul trigger:
CREATE TRIGGER trig_audit
VALUES(‘Obiect modificat’);
END;
Care dintre actiunile urmat va determina decl triggerului creat inreg in tab audit?
a. O comanda prin care se adauga o constrangere de cheie primara unui table existent.
8. Variabila g_mesaj declarata ca mai jos este:
VARIABLE g_mesaj VARCHAR2 (50)
BEGIN
:g_mesaj := ‘Invat PL/SQL;
END; c. Variabila de legatura.

S-ar putea să vă placă și