Sunteți pe pagina 1din 8

Proiect PBD – Tema nr 5

Se considera o aplicatie pentru evidenta clientilor care achizitioneaza produse de la o


firma distribuitoare.
Pentru orice Client trebuie sa se salveze intr-o baza de date Oracle urmatoarele
informatii:
- nume
- prenume
- CNP
- adresa
- telefon
- disponibil in cont (suma de bani achitata de client in avans) - informatii despre
achizitiile efectuate:
o Produs
o Data achizitiei
o Pret
o Suma incasata

Stiind ca `Numele` nu depaseste 15 caractere, `Prenumele` nu depaseste 20 caractere,


`CNP` are exact 13 caractere, telefonul contine doar cifre si este exact de 9 caractere, disponibil
in cont este pozitiv si cu 2 zecimale, si ca un client poate avea oricate achizitii, se cere:

1. Să se realizeze proiectarea bazei de date aferente (structura de tabele, structura de coloane a


fiecărei tabele, constrângeri).
2. Sa se scrie comenzile SQL pentru tabelele proiectate la punctul anterior.
3. Să se scrie comenzile SQL pentru popularea bazei de date cu urmatoarele produse:

nume prenume CNP adresa telefon Disponibil produs data pret Suma
incasata
Ion Adi 123456 Timis 123456789 0 Indesit 10/01/2007 66 66
Achim Gheorghe 123457 Resita 234567890 0 Siemens 01/02/2003 100 100
Dima Alex 123458 Arad 326774434 0 Bosch 07/12/2005 120 20
Duma Mihai 123459 Deva 576325767 0 LG 11/12/2005 55 37
Ion Adi 123456 Timis 123456789 0 Sony 14/05/2006 7.99 1.99

4. Să se scrie o procedura care sa permita vanzarea unui produs (La vanzarea unui produs, se va
verifica disponibilul clientului, si acesta va fi adaugat sumei incasate. In cazul in care suma
incasata depaseste valoarea ramasa de achitat, diferenta va fi trecuta in disponibilul clientului)
- procedura va fi apelata cu parametrii: CNP, nume produs, data, pret, suma incasata.
5. Sa se genereze un raport care sa cuprinda numele,prenumele, cnp, si produsele achizitionate si
achitate integral de catre clienti.
6. Sa se genereze un raport detaliat care sa cuprinda numele,prenumele, CNP, si toate produsele
achizitionate, pretul, si restul de plata, ordonat dupa nume, prenume, data achitiei, crescator,
respectiv rest de plata descrescator.
7. Sa se scrie un trigger care la adaugarea unui produs, sa calculeze automat disponibilul si suma
incasata, in conditiile enuntate la punctul 4.
8. Sa se scrie o functie care sa primeasca ca parametri CNP si produs si care sa returneze restul
de plata.
9. Sa se afiseze doar clientii care au minim 4 produse achitate integral, sau au achitionat produse
a caror valoare totala depaseste 1000, in maxim 2 ani consecutivi precizand: nume, prenume,
CNP si respectiv suma totala incasata., si care nu au produse achitate partial (Clienti majori).
10. Sa se afiseze clientul care are cele mai multe produse achiztionate dar neplatite integral,
precizand numele, prenumele, CNP, numar de produse si rata lui de achitare (cat la suta a
platit din pretul bunurilor achizitionate).

1. Proiectarea bazei de date aferente:

Client

Camp Tip Constrangeri Comentarii


Nume caracter(15) necesar(not null), numele de familie
lungimea< 15
caractere
Prenume caracter(20) necesar(not null), prenumele
lungimea< 20
caractere
CNP caracter(13) cheie primara, codul numeric
lungimea=13 caractere personal
Adresa caracter(20) adresa clientului
Telefon int(9) lungimea=9 caractere numarul de telefon al
clientului
Disponibil_in_cont double pozitiv, cu 2 zecimale Suma disponibila in
cont

Produs

Camp Tip Constrangeri Comentarii

Id int necesar(not null), Identificatorul unic al


cheie primara unui produs
Marca caracter(20) necesar(not null), Marca(numele)
lungimea< 20 produsului
caractere
Pret double Pozitiv si cu 2 pretul produsului
zecimale

Achizitie

Camp Tip Constrangeri Comentarii


Id int necesar(not null), cheie Identificatorul unic al
primara unei achizitii
Cnp_client caracter(13) necesar(not null),
foreign key catre tabela
Client
Id_produs int necesar, not null,
foreign key catre tabela
Produs
Data_achizitiei data data cand a fost
efectuata achizitia
Suma_incasata double pozitiva suma incasata
corespunzatoare
achizitiei
Pret double Pozitiv si cu 2 pretul produsului
zecimale

2. Comenzile SQL pentru popularea bazei de date

CREATE TABLE `client` (


`Nume` VARCHAR(15) NOT NULL,
`Prenume` VARCHAR(20) NOT NULL,
`CNP` CHAR(13) NOT NULL,
`Telefon` INT(9) ZEROFILL NULL,
`Adresa` VARCHAR(20) NULL,
`Disponibil_in_cont` DOUBLE NULL,
PRIMARY KEY (`CNP`));

CREATE TABLE `produs` (


`Id` INT NOT NULL,
`Marca` VARCHAR(20) NOT NULL,
`Pret` DOUBLE UNSIGNED NULL,
PRIMARY KEY (`id`));

CREATE TABLE `achizitie` (


`Id` INT NOT NULL AUTO_INCREMENT,
`Cnp_client` CHAR(13) NOT NULL,
`Id_produs` INT NOT NULL,
`Data_achizitiei` DATE NULL,
`Pret` DOUBLE UNSIGNED NULL,
`Suma_incasata` DOUBLE UNSIGNED NULL,
PRIMARY KEY (`Id`),
CONSTRAINT `Cnp_client`
FOREIGN KEY (`Cnp_client`)
REFERENCES `client` (`CNP`),
CONSTRAINT `Id_produs`
FOREIGN KEY (`Id_produs`)
REFERENCES `produs` (`id`);

3. Insertiile in cele 3 tabele sunt dupa cum urmeaza:

Table - Client
INSERT INTO
`client`(`Nume`,`Prenume`,`CNP`,`Telefon`,`Adresa`,`Disponibil_in_cont`) VALUES (`Ion`,
`Adi`, `123456`,123456789, `Timis`, 0);
INSERT INTO
`client`(`Nume`,`Prenume`,`CNP`,`Telefon`,`Adresa`,`Disponibil_in_cont`)
VALUES (`Achim`, `Gheorghe`, `123457`,234567890, `Resita`, 0);
INSERT INTO
`client`(`Nume`,`Prenume`,`CNP`,`Telefon`,`Adresa`,`Disponibil_in_cont`)
VALUES (`Dima`, `Alex`, `123458`,326774434, `Arad`, 0);
INSERT INTO
`client`(`Nume`,`Prenume`,`CNP`,`Telefon`,`Adresa`,`Disponibil_in_cont`)

VALUES (`Duma`, `Mihai`, `123459`, 576325767, `Deva`, 0);


INSERT INTO
`client`(`Nume`,`Prenume`,`CNP`,`Telefon`,`Adresa`,`Disponibil_in_cont`)

VALUES (`Ion`, `Adi`, 123456, 123456789, `Timis`, 0);

Table - Produs
INSERT INTO `produs` (`Id`,`Marca`,`Pret`) VALUES (1,`Indesit`,66);
INSERT INTO `produs` (`Id`,`Marca`,`Pret`) VALUES (2,`Simens`,100);
INSERT INTO `produs` (`Id`,`Marca`,`Pret`) VALUES (3,`Bosch`,120);
INSERT INTO `produs` (`Id`,`Marca`,`Pret`) VALUES (4,`LG`,55);
INSERT INTO `produs` (`Id`,`Marca`,`Pret`) VALUES (3,`Sony`,7.99);
Table- Achizitie
INSERT INTO
`achizitie`(`Id`,`cnp_Client`,`Id_produs`,`Data_achizitiei`,`Suma_incasata`,`Pret`)
VALUES (1,`123456`,1,`2007-01-10`,66,66);
INSERT INTO
`achizitie`(`Id`,`Cnp_client`,`Id_produs`,`Data_achizitiei`,`Suma_incasata`,`Pret`)
VALUES (2,`123457`,2,`2003-02-01`,100,100);
INSERT INTO
`achizitie`(`Id`,`Cnp_client`,`Id_produs`,`Data_achizitiei`,`Suma_incasata`,`Pret`)
VALUES (3,`123458`,3,`2005-12-07`,20,120);
INSERT INTO
`achizitie`(`Id`,`Cnp_client`,`Id_produs`,`Data_achizitiei`,`Suma_incasata`,`Pret`)
VALUES (4,`123459`,4,`2005-12-11`,37,55);
INSERT INTO
`achizitie`(`Id`,`Cnp_client`,`Id_produs`,`Data_achizitiei`,`Suma_incasata`,`Pret`)
VALUES (5,`123456`,5,`2006-05-14`,1.99,7.99);
4. Procedura stocata pentru achizitia unui produs

USE `proiect_pbd`;
DROP procedure IF EXISTS `permite_vanzare`;
DELIMITER $$
USE `proiect_pbd`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `permite_vanzare`(IN cod_numeric
CHAR(13),
IN nume_produs varchar(20),
IN data_ach date,
IN pret double,
IN suma_incasata double)
BEGIN
DECLARE disponibil double default 0;
DECLARE total_plata double default 0;
DECLARE suma_ramasa double default 0;
DECLARE id_produs int;
SELECT disponibil_in_cont INTO disponibil FROM client WHERE cnp = cod_numeric;
SET total_plata = disponibil + suma_incasata;
SET suma_ramasa = total_plata - pret;
IF suma_ramasa > 0 THEN
SELECT id INTO id_produs FROM produs WHERE marca = nume_produs;
INSERT INTO
`achizitie`(`cnp_client`,`id_produs`,`data_achizitiei`,`suma_incasata`)
VALUES (cod_numeric,id_produs,data_ach,total_plata);
UPDATE client SET disponibil_in_cont = suma_ramasa WHERE cnp = cod_numeric; END
IF;
END$$
DELIMITER ;

5. Raport produse achitate integral

SELECT nume, prenume, cnp, marca FROM achizitie, client, produs


WHERE achizitie.cnp_client = client.cnp AND achizitie.id_produs = produs.id AND produs.pret
<= achizitie.suma_incasata

6. Raport detaliat produse achizitionate ordonate

SELECT nume, prenume, cnp, marca, data_achizitiei,pret,suma_incasata


FROM achizitie, client, produs
WHERE achizitie.cnp_client = client.cnp AND achizitie.id_produs = produs.id
ORDER BY nume ASC, prenume ASC, data_achizitiei ASC, pret-suma_incasata DESC
7. Trigger- care la adaugarea unui produs, sa calculeze automat disponibilul si suma
incasata

DROP TRIGGER IF EXISTS `achizitie_BEFORE_INSERT`;


DELIMITER $$
USE `proiect_pbd`$$
CREATE DEFINER=`root`@`localhost` TRIGGER `achizitie_BEFORE_INSERT` BEFORE
INSERT ON `achizitie` FOR EACH ROW BEGIN
DECLARE disponibil double default 0;
DECLARE total_plata double default 0;
DECLARE suma_ramasa double default 0;
DECLARE pret_produs double default 0;
SELECT disponibil_in_cont INTO disponibil FROM `client` WHERE cnp = new.cnp_client;
SET total_plata = disponibil + new.suma_incasata;
SELECT pret INTO pret_produs FROM produs WHERE id = new.id_produs;
SET suma_ramasa = total_plata - pret_produs;
IF suma_ramasa > 0 THEN
UPDATE client SET disponibil_in_cont = suma_ramasa WHERE cnp = new.cnp_client;
END IF;
END$$
DELIMITER ;

8. Functie care returneaza restul de plata pe baza CNP si id produs.

USE `proiect_pbd`;
DROP function IF EXISTS `calcul_rest_plata`;
DELIMITER $$
USE `proiect_pbd`$$
CREATE DEFINER=`root`@`localhost` FUNCTION `calcul_rest_plata`(cod_numeric char(13),
id_p int) RETURNS double
BEGIN
DECLARE pret_produs double default 0;
DECLARE suma_inc double default 0;
SELECT pret INTO pret_produs from produs where id = id_p;
SELECT suma_incasata INTO suma_inc from achizitie where cnp_client = cod_numeric AND
id_produs = id_p;
RETURN suma_inc-pret_produs;
END$$
DELIMITER ;
9. Afisaza clientii care au minim 4 produse achitate integral, sau au achitionat produse a
caror valoare totala depaseste 1000 precizand: nume, prenume, CNP si respectiv suma
totala incasata., si care nu au produse achitate partial

SELECT nume, prenume, cnp, SUM(achizitie.suma_incasata),count(achizitie.cnp_client)


FROM achizitie, client, produs
WHERE achizitie.cnp_client = client.cnp AND achizitie.id_produs = produs.id
GROUP BY cnp
HAVING SUM(achizitie.suma_incasata + client.disponibil_in_cont) >= SUM(produs.pret)
AND (count(achizitie.cnp_client)>=4 OR SUM(achizitie.pret)>1000)

10. Se afiseaza clientul care are cele mai multe produse achiztionate dar neplatite integral,
precizand numele, prenumele, CNP, numar de produse si rata lui de achitare (cat la suta a
platit din pretul bunurilor achizitionate)

DROP TEMPORARY TABLE IF EXISTS _table1_;


CREATE TEMPORARY TABLE _table1_ AS
SELECT nume, prenume,cnp, count(achizitie.cnp_client) AS numar_achizitii,
sum(achizitie.pret) AS pret_total,
sum(achizitie.suma_incasata) as suma_totala_incasata
FROM achizitie, client
WHERE achizitie.cnp_client = client.cnp
GROUP BY cnp
HAVING SUM(achizitie.suma_incasata + client.disponibil_in_cont) < SUM(achizitie.pret);
SELECT max(numar_achizitii) INTO @max_number FROM _table1_;
SELECT nume,prenume,cnp,numar_achizitii,
CONCAT(CAST(FORMAT((suma_totala_incasata*100)/pret_total,2) AS char),"%") AS achitat
from _table1_ WHERE numar_achizitii = @max_number;

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