Sunteți pe pagina 1din 13

Ministerul Educaiei al Republicii Moldova

Universitatea Tehnic a Moldovei


Departamentul Inginerie, Software i Automatic

Raport
Lucrare de laborator Nr. 8

Tema: Proceduri stocate i funcii definite de utilizator


Disciplina: Baze de Date i Cunotine

Efectuat de: st.gr.TI-131 f/r Bogdan Ion

Controlat de: Bulai Rodica


Chiinu 2017

Mersul lucrrii

Sarcina 1: S se creeze proceduri stocate n baza exerciiilor din capitolul 4. Parametrii


de intrare trebuie s corespund criteriilor din clauzele where ale exerciiilor respective.
-- EXERCISE 1 --
USE Calculatoare;

GO
IF OBJECT_ID('proc1', 'P') IS NOT NULL
DROP PROCEDURE proc1;
GO
CREATE PROCEDURE proc1
@Pret FLOAT
AS
SELECT Model,
Viteza,
Hd,Pret
FROM PC_uri
WHERE Pret < @Pret;

EXECUTE proc1 @Pret = 600;


EXECUTE proc1 @Pret = 700;
EXECUTE proc1 @Pret = 900;
GO

--Another One --
GO
IF OBJECT_ID('Sample2', 'P') IS NOT NULL
DROP PROCEDURE Sample2;
GO
Create Procedure Sample2
@Tip VarChar(10)
As
SELECT Producator
FROM Produse
WHERE Tip = @Tip;

Execute Sample2 @Tip='Imprimante';


GO

--Another One --
GO
IF OBJECT_ID('Sample3', 'P') IS NOT NULL
DROP PROCEDURE Sample3;
GO

Create Procedure Sample3


AS
SELECT Producator,
viteza
FROM Produse, PC_uri
WHERE Produse.Model = PC_uri.Model
AND Hd = (SELECT Min(Hd)
FROM PC_uri);
EXECUTE Sample3;
GO

--Another One --
IF OBJECT_ID('proc2', 'P') IS NOT NULL
DROP PROCEDURE proc2;
GO
CREATE PROCEDURE proc2
@Viteza DECIMAL (4, 0)
AS
SELECT DISTINCT Producator
FROM Produse, PC_uri
WHERE Produse.Model = PC_uri.Model
AND Viteza > @Viteza;

EXECUTE proc2 @Viteza = 450;


GO

--Another One --
GO
IF OBJECT_ID('proc3', 'P') IS NOT NULL
DROP PROCEDURE proc3;
GO
CREATE PROCEDURE proc3
@Pret FLOAT
AS
SELECT AVG(Viteza) AS 'Viteza Medie'
FROM Laptop_uri
WHERE Pret > @Pret;

EXECUTE proc3 @Pret = 1000;


GO

Sarcina 2: S se creeze o procedur stocat care ar elimina toate produsele unui


productor sau unul din tipurile de produse ale acestui productor. n calitate de
parametru de intrare, s se ia numele productorului i tipul productorului.

-- EXERCISE 2 --
GO
IF OBJECT_ID('delproc1', 'P') IS NOT NULL
DROP PROCEDURE delproc1;
GO

Create procedure delproc1


@NumeProducator char(1),
@TipProdus varchar(15)
as
Delete from Produse
where Producator =@NumeProducator and Tip=@TipProdus;

EXECUTE delproc1 @NumeProducator='D', @TipProdus='Imprimante';


GO

Sarcina 3: S se creeze o procedur stocat care ar insera n baza de date un model nou
de imprimant. n cazul n care datele inserate sunt incorecte sau incomplete, s se
afieze un mesaj de avertizare. n calitate de parametrii de intrare apar datele pentru
modelul respectiv.

GO
IF OBJECT_ID('proexer3', 'P') IS NOT NULL
DROP PROCEDURE proexer3;
GO

CREATE procedure proexer3


@Cod int = null,
@Producator char(1) = null,
@Model varchar(4) = null,
@Tip varchar(6) = null,
@Color char(2) = null,
@Pret float = null
AS
IF @Producator IS NULL BEGIN PRINT 'Nu este indicat producatorul' END
ELSE IF @Model IS NULL BEGIN PRINT 'Nu este indicat modelul' END
ELSE IF DATALENGTH(@Model)<4 BEGIN PRINT 'Modelul trebuie sa contina 4 caractere' END
ELSE IF DATALENGTH(@Model)>4 BEGIN PRINT 'Modelul trebuie sa contina 4 caractere' END
ELSE IF @Tip NOT IN('Lazer','Jet','Matrix') BEGIN PRINT 'Nu exista astfel de tip in baza de date'
END

ELSE BEGIN
INSERT INTO Produse(Producator,Model,Tip) Values(@Producator, @Model,@Tip)
INSERT INTO Imprimante(Cod,Model,Color,Tip,Pret) Values(@Cod,@Model,@Color,@Tip,@Pret);
END;

EXECUTE proexer3 @Cod=90, @Producator='A', @Model='3456', @Tip='Lazer', @Color= 'da',


@Pret=200;
GO

Sarcina 4: S se creeze o procedur stocat care , n calitate de parametru de intrare, s


aib numrul de tipuri de produse fabricate de un productor. n urma executrii
procedurii, trebuie s se afieze un mesaj informativ, care s includ valoarea
parametrului inserat i un tabel cu coloanele Producator, Produs, Nr_De_Modele pentru
fiecare tip de produs.

-- EXERCISE 4 --
GO
IF OBJECT_ID('NrProd4', 'P') IS NOT NULL
DROP PROCEDURE NrProd4;
GO

CREATE PROCEDURE NrProd4


@nrTipuri INT=0
AS
BEGIN
PRINT 'Valoarea parametrului este ' + CAST (@nrTipuri AS VARCHAR(4));
SELECT Producator, Tip As Produs, Count(Model) AS nrModele
FROM Produse
GROUP BY Producator,Tip
HAVING COUNT(Model) = @nrTipuri
ORDER BY Producator ASC, Tip ASC;
END;

EXECUTE NrProd4 @nrTipuri=2;


GO
Sarcina 5: S se creeze o procedur stocat care ar calcula preul ce trebuie sa-l achite
cumprtorul n timpul promoiilor speciale la magazinul de calculatoare. Procedura va
trebui s calculeze preul nou pentru toate produsele unui productor anumit, n cazul
cnd se anun promoia. Un cumprtor poate procura deodat un singur model de
produse, dar mai multe uniti de acest model. Reducerea poate fi cteva tipuri n funcie
de tipul produsului, preul iniial i numrul de uniti de marf procurat.
n calitate de parametrii de intrare, se vor lua:
Modelul produsului procurat de cumprtor;
Numrul de uniti de marf procurat;
Procentul de reducere la pre n funcie de numrul de uniti de marf
procurat;
Procentul de reducere la pre in dependent de tipul de marf procurat;
Procentul de reducere la pre n dependent de preul produsului fr
reducere.

Astfel trebuie s se afieze Modelul, Tipul produsului, Productorul, Preul


fr reducere, Preul cu reducere i Suma total spre achitri. Suma totala spre
achitare trebuie s tina cont de reducerile calculate. Implicit asupra produselor
procurate nu trebuie s influeneze nici o reducere.
-- EXERCISE 5 --
GO
IF OBJECT_ID ('DISCOUNT' ,'P') IS NOT NULL DROP PROCEDURE DISCOUNT;
GO

CREATE PROCEDURE DISCOUNT


@Model VARCHAR(4) = NULL,
@Units INT = NULL,
@DiscountUnits FLOAT = NULL,
@DiscountType VARCHAR(10) = NULL,
@DiscountPrice FLOAT = NULL
AS
BEGIN
DECLARE
@FinalPrice FLOAT = NULL,
@Type VARCHAR(10) = NULL,
@Price FLOAT = NULL,
@Discount FLOAT = 0

/* CALCULATE DISCOUNT BASED ON TYPE MODEL */


SET @Type = (SELECT Tip FROM Produse WHERE Model = @Model)
IF (@DiscountType = @Type and @Type='Imprimante')
BEGIN
SET @Discount = 1;
SET @Price = (SELECT Pret FROM Imprimante WHERE Model = @Model);
END
ELSE IF (@DiscountType = @Type and @Type='Laptop_uri')
BEGIN
SET @Discount = 1;
SET @Price = (SELECT Pret FROM Laptop_uri WHERE Model = @Model);
END
ELSE IF (@DiscountType = @Type and @Type='PC')
BEGIN
SET @Discount = 1;
SET @Price = (SELECT Pret FROM PC_uri WHERE Model = @Model);
END

/* ADDING DISCOUNT BASED ON PRICE DISCOUNT */


IF (@Price >= 100 AND @Price < 250)
BEGIN
SET @Discount = @Discount + @DiscountPrice;
END
ELSE IF(@Price >= 250 AND @Price < 500)
BEGIN
SET @Discount = @Discount + @DiscountPrice * 2;
END
ELSE IF(@Price >= 500)
BEGIN
SET @Discount = @Discount + @DiscountPrice * 3;
END;

/* ADDING DISCOUNT BASED ON UNITS */


IF (@Units >= 3 AND @Units < 6)
BEGIN
SET @Discount = @Discount + @DiscountUnits;
END
ELSE IF (@Units >= 6 AND @Units < 15)
BEGIN
SET @Discount = @Discount + @DiscountUnits * 2;
END
ELSE IF (@Units >= 15 AND @Units < 30)
BEGIN
SET @Discount = @Discount + @DiscountUnits * 3;
END

SET @FinalPrice = @Price - (@Price * @Discount / 100);

IF (@Type = 'Imprimante')
BEGIN
SELECT Imprimante.Model, Produse.Tip, Producator, Pret,
@FinalPrice AS Pret_cu_reducere, @FinalPrice * @Units AS
Suma_totala
FROM Produse, Imprimante
WHERE Produse.Model = @Model
AND Imprimante.Model = @Model
END
ELSE IF (@Type = 'PC')
BEGIN
SELECT PC_uri.Model, Produse.Tip, Producator, Pret,
@FinalPrice AS Pret_cu_reducere, @FinalPrice * @Units AS
Suma_totala
FROM Produse, PC_uri
WHERE Produse.Model = @Model
AND PC_uri.Model = @Model
END
ELSE IF (@Type = 'Laptop_uri')
BEGIN
SELECT Laptop_uri.Model, Produse.Tip, Producator, Pret,
@FinalPrice AS Pret_cu_reducere, @FinalPrice * @Units AS
Suma_totala
FROM Produse, Laptop_uri
WHERE Produse.Model = @Model
AND Laptop_uri.Model = @Model
END
END;
GO

EXECUTE DISCOUNT '1321', 5, 3, 'Laptop_uri', 5;

Sarcina 6: S se creeze funcii definite de utilizator n baza exerciiilor din capitolul 4.


Parametrii de intrare trebuie s corespund criteriilor din clauzele WHERE ale
exerciiilor respective.
-- Exercise 6 --
IF OBJECT_ID('sample1', 'FN') IS NOT NULL
DROP FUNCTION sample1;

GO
CREATE FUNCTION sample1
(@Pret FLOAT)
RETURNS TABLE
AS
RETURN
(SELECT Model,
Viteza,
Hd,
Pret
FROM PC_uri
WHERE Pret <= @Pret)
GO

select * from sample1(500)

Sarcina 7: S se scrie funcia care ar calcula diferena aritmetic dintre valoarea curent
a nregistrrii n cmpul Pre al tabelului pc_uri i valoare cmpului precedent.
Ordonarea nregistrrilor n tabel s fie fcut dup cmpul Cod.
n calitate de exemplu al utilizrii acestei funcii poate servi cmpul diferena din
screenshot-ul de mai jos. Iniial cmpul diferena=0.

-- Exercise 7 --
IF OBJECT_ID('GetDiffence', 'FN') IS NOT NULL
DROP FUNCTION GetDiffence;

GO
CREATE FUNCTION GetDiffence
(@difference FLOAT)
RETURNS
@Modify TABLE (
Cod INT ,
Pret FLOAT,
Diferenta FLOAT)
AS
BEGIN
INSERT @Modify
SELECT Cod,
Pret,
@difference - Pret AS Diferenta
FROM PC_uri
ORDER BY Cod;
RETURN;
END
GO

Select * from GetDiffence(350)

Sarcina 8: Folosind tabelul laptop_uri, s se creeze o funcie definit de utilizator, care


ar citi numele cmpului i ar ataa sufixul respectiv la valoarea necesar. De exemplu, n
cazul n care cmpul este Pre, se adaug sufixul $, iar dac cmpul este Viteza, se
ataeaz sufixul GHz etc.
Formatul funciei este urmtor: nume_funcie (nume_cmp).

-- Exercise 8 --
IF OBJECT_ID('Insert_Symbol', 'FN') IS NOT NULL
DROP FUNCTION Insert_Symbol;
GO

CREATE FUNCTION Insert_Symbol


(@name_column NVARCHAR (15))
RETURNS
@Table_Symbol TABLE (
Cod INT ,
Model VARCHAR (4) ,
Viteza NVARCHAR (15),
Ram NVARCHAR (15),
Hd NVARCHAR (15),
Pret NVARCHAR (15),
Ecran NVARCHAR (15) )
AS
BEGIN
IF @name_column = 'Viteza'
BEGIN
INSERT @Table_Symbol
SELECT Cod, Model, CONCAT(Viteza, 'MHz'), Ram, Hd , Pret,Ecran
FROM Laptop_uri
END
ELSE
IF @name_column = 'Ram'
BEGIN
INSERT @Table_Symbol
SELECT Cod, Model, Viteza, CONCAT(Ram,'GB'), Hd , Pret,Ecran
FROM Laptop_uri
END
ELSE
IF @name_column = 'Hd'
BEGIN
INSERT @Table_Symbol
SELECT Cod, Model, Viteza, Ram, CONCAT(Hd,' GB '), Pret,Ecran
FROM Laptop_uri
END
ELSE
IF @name_column = 'Pret'
BEGIN
INSERT @Table_Symbol
SELECT Cod, Model, Viteza, Ram, Hd, CONCAT(Pret,'$'), Ecran
FROM Laptop_uri
END
ELSE
IF @name_column = 'Ecran'
BEGIN
INSERT @Table_Symbol
SELECT Cod, Model, Viteza, Ram, Hd, Pret, CONCAT ( Ecran, '"')
FROM Laptop_uri
END
RETURN;
END
GO

Select * from Insert_Symbol('Ecran')

Sarcina 9: Se dorete realizarea unei funcii definite de utilizator din baza de date
calculatoare, care ar putea transforma cmpul Pre din dolari (starea curent) n euro sau
lei. Se utilizeaz tabelul imprimante. Formatul funciei este urmtorul:
Nume_funcie(valoare_pret, curs_BNM, valuta).

-- Exercise 9 --
IF OBJECT_ID('Exchange', 'FN') IS NOT NULL
DROP FUNCTION dbo.Exchange;

GO
CREATE FUNCTION Exchange
(@Curs_BNM FLOAT, @Valuta CHAR (3))
RETURNS
@Result TABLE (
Cod INT ,
Model VARCHAR (4),
Color CHAR (2) ,
Tip VARCHAR (6),
PretMDL MONEY )
AS
BEGIN
IF @Valuta = 'MDL'
BEGIN
INSERT @Result
SELECT Cod,
Model,
Color,
Tip,
Pret * @Curs_BNM as PretMDL
FROM Imprimante
END
ELSE
IF @Valuta = 'EUR'
BEGIN
INSERT @Result
SELECT Cod,
Model,
Color,
Tip,
Pret * @Curs_BNM as PretEUR
FROM Imprimante
END
RETURN;
END
GO
Select * from Exchange(19.906,'MDL');
GO

Sarcina 10: S se creeze o funcie definit de utilizator, care ar returna toate datele de un
anumit produs din stoc. Se definete urmtorul format al funciei:
Nume_funcie(pret_minimal, pret_maximal, tip_produs)
unde parametrii pot lua valori
tip_produs pc, laptop sau imprimanta
pre_maximal 0.00, valoarea implicit.
pre_minimal 10000.00, valoarea implicit.

IF OBJECT_ID('ShowDetails', 'FN') is not null


drop function dbo.ShowDetails;
GO
CREATE FUNCTION ShowDetails
(@max_price FLOAT, @min_price FLOAT, @product_type NVARCHAR (15))
RETURNS
@Result TABLE (
Cod INT null,
Model VARCHAR (4) null,
Viteza DECIMAL (3, 0) null,
Ram DECIMAL (3, 0) null,
Hd DECIMAL (2, 0) null,
Cd VARCHAR (3) null,
Pret FLOAT null,
Ecran INT null,
Color CHAR (2) null,
Tip VARCHAR (6) null
)
AS
BEGIN
IF @product_type = 'PC'
BEGIN
INSERT into @Result (Cod, Model, Viteza, Ram, Hd, Cd, Pret)
SELECT Cod AS CodPC,
Model AS ModelPC,
Viteza AS VitezaPC,
Ram AS RamPC,
Hd AS HdPC,
Cd,
Pret AS PretPC
FROM PC_uri
WHERE Pret >= @min_price
AND Pret <= @max_price;

--where Pret >= 850 and Pret <=1900


END
ELSE
IF @product_type = 'Laptop-uri'
BEGIN
INSERT into @Result (Cod, Model, Viteza, Ram, Hd, Ecran, Pret)
SELECT Cod AS CodLaptop,
Model AS ModelLaptop,
Viteza AS VitezaLaptop,
Ram AS RamLaptop,
Hd AS HdLaptop,
Ecran,
Pret AS PretPC
FROM Laptop_uri
WHERE Pret >= @min_price
AND Pret <= @max_price;

END
ELSE
IF @product_type = 'Imprimante'
BEGIN
INSERT into @Result (Cod, Model, Color, Tip, Pret)
SELECT Cod AS CodPrinter,
Model AS ModelPrinter,
Color,
Tip,
Pret AS PretPC
FROM Imprimante
WHERE Pret >= @min_price
AND Pret <= @max_price;
END
RETURN;
END

Go

select * from ShowDetails(900, 200, 'PC')

Sarcina 11: Se cere realizarea unei funcii definite de utilizator, care ar calcula cel mai
ieftin sau cel mai scump produs al unui productor. Productorul este luat n calitate de
parametru. Formatul funciei este urmtorul:
Nume_funcie (nume productor, flag)
unde, dac flag=1, va afia preul minimal pentru utilizatorul dat, iar flag = 0 va afia
preul maximal.

-- Exercise 11 --
If OBJECT_ID('ShowMINMAX','TF') is not null drop function ShowMINMAX;
Go

CREATE FUNCTION ShowMINMAX


(@producer_name CHAR (2), @flag INT)
RETURNS
@Result TABLE (
Producator CHAR (2) ,
Nume_Produs VARCHAR (10),
Pret FLOAT )
AS
BEGIN
IF @flag = 1
BEGIN
INSERT @Result
SELECT TOP 1 tabel.Producator,
tabel.tip,
min(tabel.Pret_Min) AS Pret_Minimal
FROM (SELECT Producator,
Produse.Tip,
min(Pret) AS Pret_Min
FROM PC_uri
INNER JOIN
Produse
ON Produse.Model = PC_uri.Model
GROUP BY Producator, Produse.Tip
UNION ALL
SELECT Producator,
Produse.Tip,
min(Pret) AS Pret_Min
FROM Laptop_uri
INNER JOIN
Produse
ON Produse.Model = Laptop_uri.Model
GROUP BY Producator, Produse.Tip
UNION ALL
SELECT Producator,
Produse.Tip,
min(Pret) AS Pret_Min
FROM Imprimante
INNER JOIN
Produse
ON Produse.Model = Imprimante.Model
GROUP BY Producator, Produse.Tip) AS tabel
WHERE Producator = @producer_name
GROUP BY tabel.Producator, tip
ORDER BY Pret_Minimal;
END
ELSE
IF @flag = 0
BEGIN

INSERT @Result
SELECT TOP 1 tabel.Producator,
tabel.tip,
max(tabel.Pret_Max) AS Pret_Maximal
FROM (SELECT Producator,
Produse.Tip,
max(Pret) AS Pret_Max
FROM PC_uri
INNER JOIN
Produse
ON Produse.Model = PC_uri.Model
GROUP BY Producator, Produse.Tip
UNION ALL
SELECT Producator,
Produse.Tip,
max(Pret) AS Pret_Max
FROM Laptop_uri
INNER JOIN
Produse
ON Produse.Model = Laptop_uri.Model
GROUP BY Producator, Produse.Tip
UNION ALL
SELECT Producator,
Produse.Tip,
max(Pret) AS Pret_Max
FROM Imprimante
INNER JOIN
Produse
ON Produse.Model = Imprimante.Model
GROUP BY Producator, Produse.Tip) AS tabel
WHERE Producator = @producer_name
GROUP BY tabel.Producator, tip
ORDER BY Pret_Maximal;
END
RETURN;
END
GO

select * from ShowMINMAX('E', 0)

Concluzie:

n urma efecturii lucrrii de laborator am realizat o serie de proceduri i funcii


definite de utilizator, care ne ofer posibilitatea de a utiliza codul mult mai efectiv.
Totodat am identificat tipurile de funcii i posibilitile fiecreia in parte. Astfel
funciile inline ne ofer posibilitatea de a returna un tabel, dar au dezavantajul ca nu pot
fi scrise interogaii in blocurile begin ... end. De aceast funcionalitate dispun funciile
multi-instruciune unde putem specifica mai multe comenzi. Totodat procedurile i
funciile se difer prin funcionalitile ce le ofer unele sau altele, facilitnd utilizarea
acestora util in dependen de sarcina propus.