Advertisement
Guest User

Untitled

a guest
Nov 13th, 2019
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.97 KB | None | 0 0
  1. Laborator 5-6 PL/SQL
  2. Oracle
  3. Introducere in PL/SQL
  4. 1. Structuri de bază în PL/SQL 1
  5. 2. Programe simple în PL/SQL 3
  6. 3. Instrucţiuni de control în PL/SQL 4
  7. 1.Instrucţiunea IF 4
  8. 2. Instructiunea CASE 6
  9. 3. Instructiunea LOOP 7
  10. 4. Comanda EXIT-WHEN 7
  11. 5. Etichetarea unei blucle PL/SQL 7
  12. 6. Bucla WHILE-LOOP 8
  13. 7. Instructiunea FOR-LOOP 8
  14.  
  15.  
  16. 1. Structuri de bază în PL/SQL
  17. PL înseamnă Procedural Language (deci limbaj procedural). Acesta este mai puternic decât SQL-ul. Unitatea de bază din PL/SQL se numeşte bloc. Toate programele sunt constituite din blocuri, care pot fi imbricate. Fiecare bloc are următoarea structură:
  18.  
  19. DECLARE
  20. /* Sectiunea de declarare: variabile, tipuri de date, subprograme locale */
  21. BEGIN
  22. /* Secţiunea executabilă: declaraţii SQL sau proceduri*/
  23. /* Este singura secţiune din bloc care trebuie să apară */
  24. EXCEPTION
  25. /* Secţiunea de lucru cu excepţiile: declaraţii de lucru cu erorile */
  26. END;
  27.  
  28. Observaţii:
  29. Singura secţiune necesară este cea de execuţie; celelalte secţiuni sunt opţionale.
  30. Singurele declaraţii SQL permise sunt SELECT, INSERT, UPDATE, DELETE şi alte manipulări de date sau controale legate de tranzacţie. Totuşi, fraza SELECT are o formă specială în care un singur tuplu este salvat în variabile. Restul instrucţiunilor de definire de date, cum ar fi CREATE, DROP, sau ALTER nu sunt permise.
  31. Secţiunea executabilă poate conţine asignări, decizii, cicluri, apeluri de proceduri, şi triggere.
  32. PL/SQL nu este Case Sensitive (nu face diferenţe între litere mici şi mari).
  33. Pot fi utilizate comentariile /* ... */.
  34. functia DBMS_OUTPUT.PUT_LINE este folosita pentru a afisa rezultatul din programul PL/SQL
  35. Pentru a executa un program PL/SQL, textul în sine trebuie fie încheiat cu un punct “.”, urmată de o linie pe care se tastează run;
  36. Informaţiile sunt transmise între programul PL/SQL şi baza de date prin intermediul unor variabile. Fiecare variabilă are un tip specific asociat acesteia Tipurile pot fi:
  37. Unul din tipurile utilizate în SQL pentru câmpurile tabelei;
  38. Un tip generic utilizat în PL/SQL cum ar fi NUMBER
  39. Declarat ca să fie de acelaşi tip cu câmpul din baza de date.
  40.  
  41. Observaţii
  42. Cel mai utilizat tip este NUMBER. Variabilele de tip NUMBER pot reţine fie un întreg, fie un număr real.
  43. Pentru şiruri de caractere, cel mai utilizat este VARCHAR(n), unde n este lungimea maximă a şirului în bytes. Lungimea trebuie neapărat precizată, nu există o valoarea implicită. De exemplu, putem declara:
  44. DECLARE
  45. pret NUMBER;
  46. denumire VARCHAR(20);
  47.  
  48. PL/SQL permite variabile BOOLEAN (logice), chiar dacă Oracle nu suportă acest tip pentru câmpurile tabelei.
  49.  
  50. De obicei, se foloseşte operatorul %TYPE. De exemplu:
  51.  
  52. DECLARE
  53. v_nume Stud.nume%TYPE;
  54.  
  55. defineşte pentru variabila v_nume acelaşi tip de dată ca şi câmpul nume din tabela Stud.
  56. Dacă există o variabilă care este de tip articol, cu mai multe câmpuri, cea mai simplă posibilitate de declarare a acestei variabile este utilizarea operatorului %ROWTYPE. Rezultatul este un tip articol (înregistrare) în care câmpurile au acelaşi nume şi tip ca şi numele câmpurilor din tabelă. De exemplu:
  57. DECLARE
  58. v_date_stud Stud%ROWTYPE;
  59.  
  60. defineşte variabila v_date_stud ca un articol cu exact aceleaşi câmpuri ca şi tabela Stud, fiind selectată pe rând câte o înregistrare.
  61. Valoarea iniţială a oricărei variabile, indiferent de tipul ei, este Null.
  62. Putem asocia valori unei variabile utilizând operatorul de atribuire ":=". Asignarea poate surveni imediat după declararea tipului variabilei, sau oriunde în cadrul porţiunii executabile a programului. De exemplu:
  63. DECLARE
  64. a NUMBER := 3;
  65. BEGIN
  66. a := a + 1;
  67. END;
  68. .
  69. run;
  70.  
  71. Programul nu are nici un efect, pentru că asupra bazei de date nu se efectuează nici o modificare.
  72.  
  73. Alt exemplu:
  74.  
  75. CREATE TABLE angajati (coda NUMBER (4) constraint pk_coda PRIMARY KEY,
  76. nume VARCHAR2(15), pren VARCHAR2(15),orel NUMBER (3), bonus NUMBER(5,2),
  77. salar NUMBER(6));
  78.  
  79. set serveroutput on;
  80.  
  81. DECLARE
  82. v_salar NUMBER;
  83. v_ore_lucrate NUMBER := 40;
  84. v_salar_orar NUMBER := 22.50;
  85. v_bonus NUMBER := 150;
  86. v_ang1 angajati%ROWTYPE;
  87. BEGIN
  88. v_salar := (v_ore_lucrate * v_salar_orar) + v_bonus;
  89. v_ang1.pren := 'Ion';
  90. v_ang1.nume := 'POP';
  91. DBMS_OUTPUT.PUT_LINE ('Nume'||' '||'Prenume'||' '||'Salar');
  92. DBMS_OUTPUT.PUT_LINE (v_ang1.nume||' '||v_ang1.pren||' '||v_salar);
  93. END;
  94. /
  95. run;
  96.  
  97. Alt exemplu:
  98.  
  99. INSERT INTO angajati VALUES (100, 'POP', 'Ion', 2.5, 500);
  100. INSERT INTO angajati VALUES (101, 'LUSTREA', 'Anca', 3.5, 600);
  101.  
  102. set serveroutput on;
  103.  
  104. DECLARE
  105. v_bonus NUMBER(8,2);
  106. v_coda NUMBER(4) := 100;
  107. BEGIN
  108. SELECT salar * 0.10 INTO v_bonus FROM angajati
  109. WHERE coda=v_coda;
  110. DBMS_OUTPUT.PUT_LINE ('Bonus 10% pt. ang cu codul 100:'||' '||v_bonus);
  111. END;
  112. /
  113. run;
  114.  
  115.  
  116.  
  117. 2. Programe simple în PL/SQL
  118. Cel mai simplu mod de lucru este efectuarea unor declaraţii urmată de o secţiune executabilă care constă în una sau mai multe enunţuri SQL cu care suntem obişnuiţi. Diferenţa majoră este forma instrucţiunii SQL: după clauza SELECT, trebuie să avem o clauză INTO în care să enumerăm variabilele, pentru fiecare atribut din SELECT câte o variabilă.
  119. Instrucţiunea SELECT în PL/SQL funcţionează doar dacă rezultatul interogării este un singur tuplu. Situaţia este identică cu SELECT -ul care furnizează o singură înregistrare despre care am vorbit la interogări. Dacă interogarea returnează mai mult de un tuplu, trebuie să folosim o tabelă cursor. De exemplu:
  120. DROP TABLE T1;
  121. CREATE TABLE T1(
  122. nume VARCHAR(20),
  123. salar INTEGER
  124. );
  125. DELETE FROM T1;
  126. INSERT INTO T1 VALUES(’POPESCU Ion’, 600);
  127. INSERT INTO T1 VALUES(’BALAJ Maria’, 500);
  128. INSERT INTO T1 VALUES(’AVRAM Alina’, 700);
  129. SELECT * FROM T1;
  130. /* Deasupra e SQL simplu, mai jos este un program PL/SQL */
  131. DECLARE
  132.     v_nume VARCHAR(20);
  133.     v_salar NUMBER;
  134. BEGIN
  135. /* Pentru cei care au salarul=500, acesta se mareste cu 100*/
  136. SELECT nume, salar INTO v_nume,v_salar FROM T1 WHERE salar=500;
  137. Delete from t1 where salar=500;
  138. INSERT INTO T1 VALUES(v_nume,v_salar+100);
  139.  
  140. END;
  141. .
  142. run;
  143. /* din nou SQL simplu */
  144. SELECT * FROM T1;
  145.  
  146. Din fericire, un singur cuplu din tabela T1 verifică condiţia ca salarul să fie egal cu 500, şi anume (BALAJ Maria, 500). Comanda DELETE şterge înregistrarea respectivă, urmând ca INSERT sa o introducă din nou în tabelă, de data asta cu salarul mărit.
  147.  
  148. Alt exemplu:
  149.  
  150. CREATE TABLE T2 (nr1 INTEGER, nr2 INTEGER);
  151.  
  152. DELETE FROM T2;
  153.  
  154. INSERT INTO T2 VALUES(1, 3);
  155. INSERT INTO T2 VALUES(2, 4);
  156.  
  157. /* Deasupra este SQL; mai jos program PL/SQL */
  158.  
  159. DECLARE
  160. v_nr1 NUMBER;
  161. v_nr2 NUMBER;
  162. BEGIN
  163. /* daca primul numar este mai mare ca 1, se inverseaza insereaza o
  164. inregistrare noua in care numerele sunt inversate*/
  165. SELECT nr1,nr2 INTO v_nr1,v_nr2 FROM T2 WHERE nr1>1;
  166. INSERT INTO T2 VALUES (v_nr2,v_nr1);
  167. END;
  168. .
  169. run;
  170.  
  171. 3. Instrucţiuni de control în PL/SQL
  172. PL/SQL permite crearea unor decizii sau cicluri.
  173.  
  174. 1.Instrucţiunea IF
  175. are formatul general:
  176. IF <conditie> THEN <lista_declaratii> ELSE <lista_declaratii> END IF;
  177.  
  178. Partea ELSE este opţională. Dacă se doreşte imbricarea:
  179.  
  180. IF <conditie_1> THEN ...
  181. ELSIF <conditie_2> THEN ...
  182. ... ...
  183. ELSIF <conditie_n> THEN ...
  184. ELSE ...
  185. END IF;
  186. Exemplu IF fără ELSE:
  187.  
  188. SELECT * FROM T1;
  189.  
  190. DECLARE
  191. v_nume VARCHAR2(20);
  192. v_salar NUMBER;
  193.  
  194. BEGIN
  195. /* Celor care au salarul=700, li se va mari salarul cu 100 lei */
  196. SELECT nume,salar INTO v_nume,v_salar FROM T1 WHERE salar=700;
  197. IF v_salar=700 THEN
  198. DELETE FROM T1 WHERE SALAR=700;
  199. INSERT INTO T1 VALUES(v_nume,v_salar+100);
  200. END IF;
  201. END;
  202. .
  203. run;
  204.  
  205. SELECT * FROM T1;
  206.  
  207. Alt exemplu:
  208.  
  209. SELECT * FROM T1;
  210.  
  211. DECLARE
  212. v_nume VARCHAR2(20);
  213. v_salar NUMBER;
  214.  
  215. BEGIN
  216. /* Celor care au salarul=700, li se va mari salarul cu 100 lei */
  217. SELECT nume,salar INTO v_nume,v_salar FROM T1 WHERE salar=700;
  218. IF v_salar=700 THEN
  219. DELETE FROM T1 WHERE SALAR=700;
  220. INSERT INTO T1 VALUES(v_nume,v_salar+100);
  221. END IF;
  222. END;
  223. .
  224. run;
  225.  
  226. OPERATORII
  227. Operator
  228. Description
  229. + - / *
  230. arithmetic
  231. =
  232. equality
  233. != or <>
  234. inequality
  235. ||
  236. string concatenation
  237. :=
  238. assignment
  239.  
  240. Function
  241. Description
  242. String Functions
  243.  
  244. upper(s), lower(s)
  245. convert string s to upper/lower-case
  246. initcap(s)
  247. capitalise first letter of each word
  248. ltrim(s), rtrim(s)
  249. remove blank char. from left/right
  250. substr(s,start,len)
  251. sub-string of length len from position start
  252. length(s)
  253. length of s
  254. Date Functions
  255.  
  256. sysdate
  257. current date (on Oracle server)
  258. to_date(date, format)
  259. date formatting
  260. Number Functions
  261.  
  262. round(x)
  263. round real number x to integer
  264. mod(n,p)
  265. n modulus p
  266. abs(x)
  267. absolute value of x
  268. dbms_random.random()
  269. generate a random integer
  270. Type Conversion Functions
  271.  
  272. to_char()
  273. convert to string
  274. to_date()
  275. convert to date
  276. to_number()
  277. convert to number
  278. Miscellaneous Functions
  279.  
  280. user
  281. current Oracle user
  282.  
  283.  
  284.  
  285. 2. Instructiunea CASE
  286. Exemplu
  287. DECLARE
  288. grade CHAR(1);
  289. BEGIN
  290. grade := 'B';
  291. CASE grade
  292. WHEN 'A' THEN DBMS_OUTPUT.PUT_LINE('Excellent');
  293. WHEN 'B' THEN DBMS_OUTPUT.PUT_LINE('Very Good');
  294. WHEN 'C' THEN DBMS_OUTPUT.PUT_LINE('Good');
  295. WHEN 'D' THEN DBMS_OUTPUT.PUT_LINE('Fair');
  296. WHEN 'F' THEN DBMS_OUTPUT.PUT_LINE('Poor');
  297. ELSE DBMS_OUTPUT.PUT_LINE('No such grade');
  298. END CASE;
  299. END;
  300.  
  301. Exemplu:
  302.  
  303. DECLARE
  304. grade CHAR(1);
  305. BEGIN
  306. grade := 'B';
  307. CASE
  308. WHEN grade = 'A' THEN DBMS_OUTPUT.PUT_LINE('Excellent');
  309. WHEN grade = 'B' THEN DBMS_OUTPUT.PUT_LINE('Very Good');
  310. WHEN grade = 'C' THEN DBMS_OUTPUT.PUT_LINE('Good');
  311. WHEN grade = 'D' THEN DBMS_OUTPUT.PUT_LINE('Fair');
  312. WHEN grade = 'F' THEN DBMS_OUTPUT.PUT_LINE('Poor');
  313. ELSE DBMS_OUTPUT.PUT_LINE('No such grade');
  314. END CASE;
  315. END;
  316. -- in loc de folosi ELSE in CASE se poate folosi
  317. -- EXCEPTION
  318. -- WHEN CASE_NOT_FOUND THEN
  319. -- DBMS_OUTPUT.PUT_LINE('No such grade');
  320.  
  321. Tema:
  322. dati 3 exemple de programe in PL/SQL care folosesc structura de control CASE, folosind obiectele din baza de date creata de voi.
  323.  
  324.  
  325. 3. Instructiunea LOOP
  326. Exista 3 forme pentru LOOP:
  327. LOOP
  328. WHILE-LOOP
  329. FOR-LOOP
  330. Exemplu
  331. LOOP
  332.   sequence_of_statements
  333. END LOOP;
  334.  
  335.  
  336. Folosirea comenzii EXIT
  337. Comanda EXIT statement forteaza ca iesirea din blucla .
  338. Exemplu
  339. DECLARE
  340. credit_rating NUMBER := 0;
  341. BEGIN
  342. LOOP
  343. credit_rating := credit_rating + 1;
  344. IF credit_rating > 3 THEN
  345. EXIT; -- iesirea din blucla
  346. END IF;
  347. END LOOP;
  348. IF credit_rating > 3 THEN
  349. RETURN; --se foloseste RETURN si nu EXIT cand suntem in afara LOOP
  350. END IF;
  351. DBMS_OUTPUT.PUT_LINE ('Credit rating: ' || TO_CHAR(credit_rating));
  352. END;
  353.  
  354. Comanda EXIT trebuie plasata in interiorul buclei.
  355. 4. Comanda EXIT-WHEN
  356. Comanda EXIT-WHEN determina iesirea din bucla in urma unei conditii..
  357. Exemplu
  358. IF count > 100 THEN EXIT; ENDIF;
  359. sau
  360. EXIT WHEN count > 100;
  361. Cele 2 constructii de mai sus sunt echivalente, dar EXIT-WHEN este mai usor de inteles.
  362. Tema: dati 2 exemple de programe in PL/SQL care folosesc structurile de control LOOP, folosind obiectele din baza de date creata de voi.
  363.  
  364. 5. Etichetarea unei blucle PL/SQL
  365. Ca si blocurile PL/SQL, buclele pot fi etichetate. Eticheta optionala inchisa intre << >> trebuie sa apara la inceputul buclei. Numele etichetei trebuie sa apara si la sfarsitul buclei.
  366. Exemplu
  367. DECLARE
  368. s PLS_INTEGER := 0;
  369. i PLS_INTEGER := 0;
  370. j PLS_INTEGER;
  371. BEGIN
  372. <<outer_loop>>
  373. LOOP
  374. i := i + 1;
  375. j := 0;
  376. <<inner_loop>>
  377. LOOP
  378. j := j + 1;
  379. s := s + i * j;
  380. EXIT inner_loop WHEN (j > 5);
  381. EXIT outer_loop WHEN ((i * j) > 15);
  382. END LOOP inner_loop;
  383. END LOOP outer_loop;
  384. DBMS_OUTPUT.PUT_LINE ('The sum of products equals: ' || TO_CHAR(s));
  385. END;
  386.  
  387. 6. Bucla WHILE-LOOP
  388. Bucla WHILE-LOOP se executa pana atata timp cat conditia este adevarata.
  389. WHILE condition LOOP
  390.   sequence_of_statements
  391. END LOOP;
  392. Aceasta este echivalenta cu:
  393. LOOP
  394.   sequence_of_statements
  395.   EXIT WHEN boolean_expression;
  396. END LOOP;
  397.  
  398. Tema: dati 2 exemple de programe in PL/SQL care folosesc structurile de control WHILE-LOOP, folosind obiectele din baza de date creata de voi.
  399.  
  400. 7. Instructiunea FOR-LOOP
  401. Bucla FOR itereaza peste un anumit interval de intregi. Numarul de iteratii este cunoscut inainte de intrarea in blucla. Operatorul (..) serveste ca operator de domeniu. Domeniul este calculat cand se intra prima data in bucla si nu mai este niciodata reevaluat.
  402. Exemplu:
  403. DECLARE
  404. p NUMBER := 0;
  405. BEGIN
  406. FOR k IN 1..500 LOOP – calcularea lui pi cu 500 termeni
  407. p := p + ( ( (-1) ** (k + 1) ) / ((2 * k) - 1) );
  408. END LOOP;
  409. p := 4 * p;
  410. DBMS_OUTPUT.PUT_LINE( 'pi is approximately : ' || p ); -- print result
  411. END;
  412. Exemplu:
  413. BEGIN
  414. FOR i IN REVERSE 1..3 LOOP
  415. DBMS_OUTPUT.PUT_LINE (TO_CHAR(i));
  416. END LOOP;
  417. END;
  418.  
  419. In interiorul unei blucle FOR, variabila cu care se itereaza i nu poate schimbata,ci numai citita.
  420. BEGIN
  421. FOR i IN 1..3 LOOP -- assign the values 1,2,3 to i
  422. IF i < 3 THEN
  423. DBMS_OUTPUT.PUT_LINE (TO_CHAR(i));
  424. ELSE
  425. i := 2; -- nu este permisa, produce o eroare
  426. END IF;
  427. END LOOP;
  428. END;
  429.  
  430. Tema: dati 2 exemple de programe in PL/SQL care folosesc structurile de control FOR-LOOP, folosind obiectele din baza de date creata de voi.
  431.  
  432.  
  433.  
  434.  
  435. 1.
  436. DROP TABLE angajati;
  437. CREATE TABLE angajati (
  438. coda NUMBER (4) constraint pk_coda PRIMARY KEY,
  439. nume VARCHAR2(15),
  440. pren VARCHAR2(15),
  441. orel NUMBER (3),
  442. bonus NUMBER(5,2),
  443. salar NUMBER(6));
  444.  
  445. set serveroutput on;
  446.  
  447. DECLARE
  448. v_salar NUMBER;
  449. v_ore_lucrate NUMBER := 40;
  450. v_salar_orar NUMBER := 22.50;
  451. v_bonus NUMBER := 150;
  452. v_ang1 angajati%ROWTYPE;
  453. BEGIN
  454. v_salar := (v_ore_lucrate * v_salar_orar) + v_bonus;
  455. v_ang1.pren := 'Ion';
  456. v_ang1.nume := 'POP';
  457. DBMS_OUTPUT.PUT_LINE ('Nume'||' '||'Prenume'||' '||'Salar');
  458. DBMS_OUTPUT.PUT_LINE (v_ang1.nume||' '||v_ang1.pren||' '||v_salar);
  459. END;
  460.  
  461.  
  462. 2.
  463.  
  464. DECLARE
  465. x NUMBER(7,2);
  466. BEGIN
  467. SELECT sal INTO x FROM emp WHERE empno = 7788;
  468. IF x < 3000 THEN UPDATE emp SET sal = 3000
  469. WHERE empno = 7788;
  470. END IF;
  471. END;
  472.  
  473. 3. Exemplu de FOR
  474.  
  475. SET SERVEROUTPUT ON;
  476. DECLARE someone emp%ROWTYPE;
  477. BEGIN
  478. FOR someone IN (SELECT * FROM emp WHERE empno < 7900 )
  479. LOOP
  480. DBMS_OUTPUT.PUT_LINE('name = ' || someone.ename ||
  481. ', job = ' || someone.job);
  482. END LOOP;
  483. END;
  484.  
  485. 4 Exemplu de doua LOOP etichetate.
  486.  
  487. SET SERVEROUTPUT ON;
  488. DECLARE
  489. s PLS_INTEGER := 0;
  490. i PLS_INTEGER := 0;
  491. j PLS_INTEGER;
  492. BEGIN
  493. <<outer_loop>>
  494. LOOP
  495. i := i + 1;
  496. j := 0;
  497. <<inner_loop>>
  498. LOOP
  499. j := j + 1;
  500. s := s + i * j;
  501. EXIT inner_loop WHEN (j > 5);
  502. EXIT outer_loop WHEN ((i * j) > 15);
  503. END LOOP inner_loop;
  504. END LOOP outer_loop;
  505. DBMS_OUTPUT.PUT_LINE ('The sum of products equals: ' || TO_CHAR(s));
  506. END;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement