Documente Academic
Documente Profesional
Documente Cultură
SQL
Ce sunt si cand folosim procedurile stocate
O procedura stocata (Stored Procedure) este un program compilat si stocat pe un server de baze
de date, local sau la distana, care poate executa comenzi SQL. O procedura stocata este un
obiect al bazei de date, gestionat de DBMS. O procedura stocata poate primi sau transfera
parametri si poate furniza rezultate. Ea incapsuleaza comenzi SQL si instruciuni de manipulare
a datelor scrise in limbajul T-SQL (Transact SQL). O aplicaie client, sau o alta procedura
stocata utilizeaza directiva SQL, exec, pentru a apela procedura.
Inainte de a crea o procedura stocata trebuie sa cunoastem cand este recomandata folosirea ei. O
procedura stocata este recomandata a se utiliza in urmatoarele situaii:
existenta unui numar mare de clieni la care codul aplicaiei se distribuie;
daca se doreste imbunatatirea performanelor aplicaiei;
aplicaia client necesita multe operaii cu baza de date, dar puine intervenii ale
utilizatorului;
codul aplicaiei client se schimba frecvent;
aplicaia client executa multe interogari SQL;
aplicaia client acceseaza variabile de mare importana, pentru care se impune garantarea
securitaii si integritaii, motiv pentru care accesul la codul aplicaiei client se impune a
fi strict controlat;
codul aplicaiei client are un cost mare de intreinere.
Procedurile stocate rezolva situaiile prezentate mai sus, avand urmatoarele avantaje:
Execuie precompilata. SQL Server compileaza fiecare procedura stocata o data si apoi
reutilizeaza planul de execuie stabilit, ceea ce conduce la o imbunataire seminificativa
a performanelor atunci cand o procedura stocata este apelata in mod repetat. O
procedura stocata incapsuleaza multe instruciuni si directive SQL ale aplicaiei intr-un
singur mesaj ce va fi transmis serverului sql (la un apel exec), reducand astfel traficul
prin reea la o singura operaie send-receive pentru mai multe instruciuni SQL, si in
consecinta micsorand costurile de executie si latimea de banda pentru comunicare intre
client si server;
Trafic redus client/server. Utilizarea procedurilor stocate face ca in reea sa se transmita
un mesaj format dintr-o singura linie, cea care solicita execuia unei anumite proceduri
stocare (eventual cu parametrii de intrare necesari), in locul interogarilor propriu-zise,
care pot genera mesaje de dimensiune mare. Procedurile stocate constituie o modalitate
mai comoda de a crea interogari sau taskuri complexe ce pot fi apelate de cate ori e
nevoie;
Cost redus. Costul de intreinere a unei proceduri stocate este mai mic decat al unui
stocata poate returna date din baza de date catre aplicaia client. De exemplu, o aplicaie
web, gen ecommerce poate folosi o procedura stocata pentru a returna informaii despre
produsele specifice bazare pe un criteriu de cautare specificat de un utilizator conectat
online.
procedura stocata CLR este o referina catre o metoda Common Language Runtime
(CLR) scrisa in limbajele platformei Microsoft .NET Framework, care poate accepta si
returna parametrii furnizai de utilizator. Acestea sunt implementate ca metode publice,
statice intr-o clasa din limbajul .NET Framework.
unde:
'optiune' - singura valoare acceptata a acestui argument este startup care permite ca
procedura stocata sa fie declarata "cu autoexecutie" (autoexecution). O procedura
stocata cu autoexecutie este executata imediat dupa pornirea sistemului Microsoft
SQL ServerTM .
'valoare' - poate fi una dintre valorile true, false sau on, off.
Pentru o lista completa a procedurilor stocate sistem se poate apela Books online.
In SQL Server 20012, se pot aplica drepturi gen: GRANT, DENY si REVOKE la procedurile
stocate.
Pentru a crea o noua procedura, se apasa clic dreapta si se face optiunea New Stored Procedure.
END
...
Lista de parametri conine 0 sau mai muli parametri. Fiecare parametru va fi prezent in lista
sub forma:
tip nume_parametru tip_data.
Pentru tip se poate specifica unul dintre urmatoarele doua tipuri posibile:
1.
IN
2.
OUT
parametru de iesire
Explicatii argumente:
schema_name este schema de care apartine procedura;
procedure_name este numele noii proceduri stocate. Numele procedurii trebuie sa fie
conforme cu normele de identificare si trebuie sa fie unic in schema de care apartine
; number este un numar intreg optional care este folosit pentru a grupa procedurile cu
acealsi nume. Procedurile grupate pot fi sterse impreuna.
@parameter este un parametru in procedura. Pot fi declarati unul sau mai multi
parametrii. Valoarea pentru fiecare parametru declarat trebuie sa fie furnizata de
utlizator cind este apelata procedura, daca nu este setata o valoare implicita. O
procedura stocata poate avea maxim 2100 parametrii. Numele oricarui parametru incepe
cu @ si trebuie sa fie conform cu normele de identificare. Parametrii sunt vizibili local
in cadrul unei proceduri. Acelasi nume de parametru poate fi folosit in alte proceduri.
; si numarul intreg de dupa numarul procedurii permite creare de versiuni multiple ale
procedurilor cu acelasi nume. Cand procedura este executata, numarul versiunii poate fi
specificat pentru controlul versiunii. Daca nu este specificata versiunea, va fi executata prima
procedura.
Exemplu de procedura stocata care va intoarce toti angajatii din baza de date AdventureWorks.
Instructiunea DROP se refera la stergerea unei proceduri si va fi explicata detaliat mai tirziu.
USE AdventureWorks;
GO
IF OBJECT_ID ( 'HumanResources.usp_GetAllEmployees', 'P' ) IS NOT NULL
DROP PROCEDURE HumanResources.usp_GetAllEmployees;
GO
CREATE PROCEDURE HumanResources.usp_GetAllEmployees
AS
SELECT LastName, FirstName, JobTitle, Department
FROM HumanResources.vEmployeeDepartment;
GO
Exemplu de procedura stocata cu parametru, care va returna doar angajatul specificat din baza
de date AdventureWorks.
USE AdventureWorks;
GO
IF OBJECT_ID ( 'HumanResources.usp_GetEmployees', 'P' ) IS NOT NULL
DROP PROCEDURE HumanResources.usp_GetEmployees;
GO
CREATE PROCEDURE HumanResources.usp_GetEmployees
@lastname varchar(40),
@firstname varchar(20)
AS
SELECT LastName, FirstName, JobTitle, Department
FROM HumanResources.vEmployeeDepartment
WHERE FirstName = @firstname AND LastName = @lastname;
GO
GO
Pentru rulare se poate folosi urmatoarea constructie deoarece nu este specificata optiunea
WITH ENCRYPTION.
USE AdventureWorks;
GO
SELECT definition FROM sys.sql_modules
WHERE object_id = OBJECT_ID('dbo.usp_vendor_info_all');
Cu argumentele:
schema_name este numele schemei de care apartine procedura. Nu poate fi
specificat un nume de server sau un nume de baza de data
procedure este numele procedurii stocate sau a grupului de proceduri stocate care
se doresc a fi sterse
Exemplu: sterge cele doua versiunii ale procedurii proc 3, create mai sus.
procedure proc3
BEGIN
si
END.
Instruciunea DECLARE
Instruciunea DECLARE este folosita in proceduri stocate pentru declararea variabilelor
locale, a condiiilor, a cursorilor si a handlerelor de tratare a erorilor.
Sintaxa completa:
DECLARE
{{ @local_variable [AS] data_type }
| { @cursor_variable_name CURSOR }
| { @table_variable_name < table_type_definition > }
} [ ,...n]
< table_type_definition > ::=
TABLE ( { < column_definition > | < table_constraint > } [ ,... ]
)
< column_definition > ::=
column_name { scalar_data_type | AS computed_column_expression }
[ COLLATE collation_name ]
[ [ DEFAULT constant_expression ] | IDENTITY [ ( seed,increment ) ] ]
[ ROWGUIDCOL ]
[ < column_constraint > ]
< column_constraint > ::=
{ [ NULL | NOT NULL ]
| [ PRIMARY KEY | UNIQUE ]
| CHECK ( logical_expression )
}
< table_constraint > ::=
{ { PRIMARY KEY | UNIQUE } ( column_name [ ,... ] )
| CHECK ( search_condition )
}
Argumentele:
parametri in timpul procesului de execuie sau pentru a permite efectuarea unor calcule de catre procedura
stocata . Tipurile pentru aceste variabile sunt aceleasi cu tipurile de date care pot apare pe coloanele unei
tabele, adica toate subtipurile pentru tipurile numeric, alfanumeric, data si timp. Numele variabilelor in
MS SQL Server incepe totdeauna cu @.
O problema care apare in legatura cu variabilele locale dintr-o procedura stocata este cea
a ambiguitaii numelui. Ambiguitatea apare atunci cand o variabila are acelasi nume cu o
coloana.
Instructiunea print
Instructiunea PRINT permite transmiterea si afisarea de informatie pe dispozitivul de
iesire definit. Ea poate sa afiseze direct doar valori de tip CHAR, nCHAR, VARCHAR
sau nVARCHAR ori variabila globala @@VERSION. Orice alte valori trebuie sa fie
convertite la un sir de caractere cu lungimea maxima 8000 octeti pentru a putea fi afisat.
Sintaxa:
PRINT 'msg_str' | @local_variable | string_expr | @@global_variable
Pentru afisare se pot utiliza siruri formate prin concatenarea altor siruri, variabile locale
sau globale, functii CONVERT sau CAST.
Instruciuni de atribuire
Instruciunea SET atribuie valori unei variabile in T-SQL.
Sintaxa generala a instruciunii este:
SET nume variabila = expresie;
Expresia din partea dreapta poate fi un literal, un cuvant cheie sau o expresie incluzand o
instruciune SQL.
Exemple:
SET @v_nume=NULL;
SET @v_cod=3;
SET @v_nota=@v_nota*0.9;
SET
@v_nota=(SELECT
nota
CODMATERIE=12);
FROM
NOTE
WHERE
CODSTUDENT=1111
SQLERROR,
AND
in cazul in care
Instruciuni de control
Instruciunile de control din T-SQL sunt similare cu instruciunile de acelasi tip folosite
de limbajele de programare convenionale, cum ar fi C++ sau Java. Aceste instruciuni
sunt: IF..ELSE, WHILE, BREAK, CONTINUE, CASE, GOTO, RETURN,
TRY..CATCH, WAITFOR.
1. Instruciunea IF..ELSE
Instruciunea IF este o instruciune de decizie sau de selecie.
Sintaxa generala a instruciunii este:
IF Boolean_expression
{ sql_statement | statement_block }
[ ELSE
{ sql_statement | statement_block } ]
Argumentele:
boolean_expression este o expresie care dupa evaluare returneaza True sau False.
Daca expresia booleana contine o instructiune SELECT, acesta trebuie inclusa
intre paranteze.
{ sql_statement | statement_block } reprezinta orice instructiune Transact-SQL
sau o multime de instructiuni
Dupa cum se poate observa din sintaxa generala, instruciunea
instruciune de selecie cu doua ramuri.
IF
in T-SQL este o
2. Instruciunea WHILE
Instruciunea WHILE este o instruciune care permite repetarea unui grup de instruciuni
atata timp cat condiia specificata dupa WHILE este adevarata. Mai intai este testata
condiia, iar in caz ca ea este indeplinita se executa corpul ciclului.
Observatie:
este un ciclu cu test anterior, adica este posibil ca, corpul ciclului sa nu se
execute niciodata.
WHILE
Sintaxa generala:
WHILE Boolean_expression
{ sql_statement | statement_block }
[ BREAK ]
{ sql_statement | statement_block }
[ CONTINUE ]
{ sql_statement | statement_block }
Instructiunea, comanda SQL sau blocul care urmeaza dupa cuvantul cheie WHILE va fi
executata atata timp cat expresia de test va avea valoarea TRUE.
Este foarte important ca in urma execuiei ciclului WHILE sa apara o situaie care sa
determine modificarea condiiei testate, in caz contrar aparand o ciclare infinita.
Exemplu: O portiune dintr-o procedura stocata mai complexa, pentru a evidentia folosirea
lui WHILE.
WHILE (SELECT AVG(ListPrice) FROM Production.Product) < $300
BEGIN
UPDATE Production.Product
SET ListPrice = ListPrice * 2
SELECT MAX(ListPrice) FROM Production.Product
IF (SELECT MAX(ListPrice) FROM Production.Product) > $500
BREAK
ELSE
CONTINUE
END
PRINT 'Too much for the market to bear';
3. Instruciunea BREAK
BREAK se utilizeaza in cadrul unui bloc pentru a intrerupe executia blocului. Executia
va continua cu prima instructiune care urmeaza dupa blocul a carui executie a fost
intrerupta.
4. Instruciunea CONTINUE
CONTINUE se utilizeaza in instructiunea conditionala WHILE pentru a forta reluarea
executiei blocului atata timp cat conditia de test are valoarea TRUE. Eventualele
instructiuni din bloc care urmeaza dupa CONTINUE nu vor mai fi executate.
1.
5. Functia CASE
Functia CASE permite utilizarea unei variabile ca argument si testarea valorii acestei
variabile pentru mai multe cazuri specificate explicit. Ca si instruciunea IF, functia CASE
poate utiliza o clauza ELSE pentru specificarea instruciunii care va fi executata daca
valoarea variabilei nu se gaseste in mulimea valorilor specificate explicit. Instruciunea
CASE este preferabila instruciunii IF atunci cand implica un arbore multicai de decizie in
care intrarea pe orice ramura este determinata de valoarea unei aceleiasi expresii.
Functia
de
conditii
si
intoarce
una
sau
mai
multe
Argumentele:
input_expression este o expresie evaluata cand este folosit formatul CASE
simplu. input_expression este orice expresie valida.
WHEN when_expression
este o expresie simpla la care se compara
input_expression pentru un format CASE simplu. when_expression este orice
expresie valida. Tipurile de date pentru input_expression si pentru
when_expression trebuie sa fie identice sau sa poata fi convertite implicit.
n este o valoare care indica cate
WHEN when_expression THEN
result_expression pot fi folosite sau cite WHEN Boolean_expression THEN
result_expression pot fi folosite.
THEN result_expression este o expresie returnata cand egalitatea intre
input_expression si when_expression este evaluata la TRUE sau daca
Boolean_expression este evaluata TRUE. result_expression este orice expresie
valida.
ELSE else_result_expression este expresia returnata daca nici o operatie de
comparatie nu este TRUE. Daca acest argument lipseste sau nici o comparatie nu
este evaluata TRUE, CASE va returna valoarea NULL. else_result_expression
este orice expresie valida. Tipurile de date ale else_result_expression si
result_expression trebuie sa fie identice.
WHEN Boolean_expression este o expresie booleana care este evaluata atunci
cand se foloseste formatul CASE cautat. Boolean_expression este orice expresie
booleana valida.
6. Instruciunea GOTO
Aceasta instructiune permite saltul neconditionat la instructiunea, comanda sau blocul ce
urmeaza dupa eticheta specificata. Instructiunile GOTO si etichetele pot fi utilizate
oriunde intr-o procedura, batch sau declaratie de bloc. Instructiunile GOTO pot fi
imbricate.
Sintaxa:
Define the label:
label : Alter the execution:
GOTO label
Argumente:
label este punctul dupa care incepe procesarea, daca GOTO specifica aceasta
eticheta. Etichetele trebuie sa respecte normele de identificare. Daca este folosita
GOTO, o eticheta poate fi folosita ca o metoda de comentare.
7. Instruciunea RETURN
Instructiunea RETURN este folosita pentru a iesi neconditionat dintr-o interogare sau o
procedura. Instructiunea RETURN este imediata si completa, ea poate fi folosita la orice
moment pentru a iesi dintr-o procedura , batch sau instructiune bloc. Declaratiile care
urmeaza dupa RETURN nu sunt executate.
Sintaxa:
RETURN [ integer_expression ]
Argumentul:
integer_expression este o valoare intreaga care va fi returnata. Procedurile stocate
pot intoarce o valoare intreaga la apelul unei proceduri sau a unei aplicatii.
8. Instruciunea TRY..CATCH
Instructiunea TRY..CATCH implemneteaza tratarea erorilor pentru Transact-SQL care
este similara cu cea din limbajele C# si C++. Un grup de declaratii Transact-SQL pot fi
incluse intr-un bloc TRY. Daca apare o eroare in cadrul blocului TRY, controlul este
trecut la un alt grup de instructiuni din cadrul blocului CATCH.
Sintaxa:
BEGIN TRY
{ sql_statement | statement_block }
END TRY
BEGIN CATCH
{ sql_statement | statement_block }
END CATCH
[ ; ]
Argumente:
sql_statement reprezinta orice declaratie Transact-SQL.
statement_block reprezinta orice grup de declaratii Transact-SQL dintr-un batch
sau din cadrul unui bloc BEGINEND.
9. Instruciunea WAITFOR
Intructiunea WAITFOR blocheaza executia unui batch, a unei proceduri stocate sau a
unei tranzactii pina la un moment de timp specificat, dupa expirarea unui interval de
timp, sau pina ce se modifica o declaratie specificata sau se intoarce cel putin un rind.
Sintaxa:
WAITFOR
{
DELAY 'time_to_pass'
| TIME 'time_to_execute'
| ( receive_statement ) [ , TIMEOUT timeout ]
}
Argumentele:
DELAY este specificata o perioada de timp, de asteptare de pina la maxim 24 de
ore, inaintea executiei unui batch, a unei proceduri stocate sau a momentului la
care o tranzactie poate incepe.
'time_to_pass' este perioada de timp de asteptare. Acest argument poate fi
specificat intr-un format de date de tip datetime acceptat, sau poate fi specificat
intr-o variabila locala.
TIME este momentul specificat pentru rularea unui batch, a unei proceduri stocate
sau a unei tranzactii.
'time_to_execute'
este momentul in care se finalizeaza instructiunea
WAITFOR.Acest argument poate fi specificat in format de data acceptat sau intr-o
variabila locala.
receive_statement este o instructiune valida RECEIVE.
TIMEOUT timeout specifica timpul, in milisecunde pentru asteptarea sosirii intr-o
coada a unui mesaj.
Pentru testarea procedurii se deschide o noua fereastra de query sau din aplicatia client, si
se scrie:
exec obtineredep
Pentru testarea procedurii se deschide o noua fereastra de querysau din aplicatia client, si
se scrie:
exec obtinerenumedep 1
Exercitii:
1. Creati o procedura stocata care sa aiba la iesire toate informatiile depre proiectele stocate
in baza de date
2. Creati o procedura stocata pentru a obtine informatiile despre un proiect cu numele
proiectului sa fie parametru de intrare.
3. Creati o procedura stocata care sa intoarca intr0un parametru, cel mai mic salariilor din
companie.
4. Creati o procedura stocata care sa intoarca media salariilor pe fiecare departament (un
parametru de intrare si unul de iesire).