Sunteți pe pagina 1din 21

Academia de Studii Economice din Bucuresti

Proiect SGBD

--- Gestiunea unei Banci ---

Negreanu Radu Stefan


Grupa 1052

Profesor: Diaconita Vlad

Bucuresti
2018
Această baza de date are ca scop gestionarea resurselor unei bănci. Se stochează
informații despre bancă și se permite accesarea și ștergerea lor, dar și adăugarea de noi
înregistrări și generarea de rapoarte.
Baza de date conține 8 tabele:

 CLIENTI : id_client, nume, prenume, cnp, telefon,email,data_nasterii,sex,adresa.


Tabela stochează informații despre clienții băncii și se leagă de tabelele credite si
depozite prin id_client.
 CREDITE : id_credit, tip, id_client, data_semnare, suma de plata, dobanda ,
tip_asigurare, id_filiala.
Tabela stochează informații despre creditele acordate de bancă și este legată de tabela
CLIENTI în sensul că un client poate avea mai multe credite. De asemenea se leagă și
de tabela FILIALE, pentru că orice CREDIT acordat aparține unei filiale( a fost eliberat
dintr-o anumită filială).
 DEPOZITE: id_depozit, tip, id_client, data_semnare, dobânda, id_filiala.
Tabela stochează informații despre depozitele făcute la bancă și este legată de tabela
CLIENTI în sensul că un client poate avea mai multe depozite. De asemenea se leagă
și de tabela FILIALE, pentru că orice depozit făcut aparține unei filiale.
 LOCAȚII : id_locatie, adresa,cod_postal,oras,zona
Tabela stochează informații despre locațiile filialelor.
 FILIALE: id_filiala, numar_angajati,nume_filiala,id_locatie.
Tabela stochează informații despre filiale. Este o legatura de 1-1 între filiale și locații
deoarece orice filiala are o singură locație.
O filiala poate avea mai multe departamente și angajați.
 DEPARTAMENTE: id_departament,denumire_departament, id_locatie
Tabela stochează informații despre departamente. Orice departament aparține unei
filiale.
 FUNCȚII : id_funcție, denumire, id_angajat
Tabela stochează informații despre funcțiile angajaților. Pot fi mai mulți angajați pe
aceeași funcție.
 ANGAJAȚI: id_angajat,nume,prenume,cnp, telefon, data_angajare,salariul,
id_departament, id_functie,id_filiala,email, id_manager.
Tabela stochează informații despre angajații băncii. Este legată de funcții și de filiale.
I. Crearea tabelelor, prezentarea schemei conceptuale si inserarea datelor in
tabel

create table CLIENTI


(id_client NUMBER(2) CONSTRAINT pk_id PRIMARY KEY,
nume VARCHAR2(30) NOT NULL,
prenume VARCHAR2(30) NOT NULL,
cnp VARCHAR2(13) CONSTRAINT ck_cnp CHECK (cnp like '1___________' or cnp like
'2___________'),
telefon VARCHAR(12),
email VARCHAR2(20),
data_nasterii DATE,
sex VARCHAR2(2) CONSTRAINT ck_sex CHECK(sex like 'm' or sex like 'f'),
adresa VARCHAR2(50)
);

create table FILIALE(


id_filiala NUMBER(2)CONSTRAINT pk_id_filiala PRIMARY KEY,
adresa VARCHAR2(50),
numar_angajati NUMBER(4) CONSTRAINT ck_numar_angajati
CHECK(numar_angajati>0)
);

create table CREDITE


(id_credit NUMBER(2)CONSTRAINT pk_id_credit PRIMARY KEY ,
tip VARCHAR2(20) NOT NULL,
data_semnare DATE,
rata NUMBER(3),
dobanda NUMBER(3),
tip_asigurare VARCHAR2(20),
id_filiala NUMBER(2),
id_client NUMBER(2),
CONSTRAINT id_client_fk FOREIGN KEY (id_client) REFERENCES clienti(id_client),
CONSTRAINT id_filiala_fk FOREIGN KEY (id_filiala) REFERENCES filiale(id_filiala)
);

create table DEPOZITE(


id_depozite NUMBER(2) CONSTRAINT pk_id_depozit PRIMARY KEY,
tip VARCHAR2(20) NOT NULL,
data_semnare DATE,
dobanda NUMBER(3),
id_filiala NUMBER(2),
CONSTRAINT id_filiala_fk2 FOREIGN KEY (id_filiala) REFERENCES
filiale(id_filiala));

create table LOCATII


(
id_locatie NUMBER(2) not null CONSTRAINT pk_id_locatie PRIMARY KEY,
adresa VARCHAR2(40),
cod_postal VARCHAR2(12),
oras VARCHAR2(30),
zona VARCHAR2(25)
);

create table DEPARTAMENTE


(
id_departament NUMBER(4) not null CONSTRAINT pk_id_departament PRIMARY
KEY,
denumire_departament VARCHAR2(30),
id_locatie NUMBER(4),
CONSTRAINT fk_id_locatie FOREIGN KEY (id_locatie) references locatii(id_locatie)
);

create table ANGAJATI


(
id_angajat NUMBER(2) not null CONSTRAINT pl_id_angajat PRIMARY KEY,
prenume VARCHAR2(20),
nume VARCHAR2(25),
email VARCHAR2(25),
telefon VARCHAR2(20),
data_angajare DATE,
salariul NUMBER(8,2),
id_manager number(3),
id_departament NUMBER(4),
CONSTRAINT fk_id_departament FOREIGN KEY (id_departament) references
departamente(id_departament)
)

create table FUNCTII(


id_functie NUMBER(2)CONSTRAINT pk_id_functie PRIMARY KEY,
denumire varchar(100),
id_angajat number(3),
CONSTRAINT fk_id_ang FOREIGN KEY(id_angajat) REFERENCES
angajati(id_angajat)
);
II. Comenzi SQL directe asupra tabelelor.

Adaugare coloana nume_filiala la tabela filiale.

alter table filiale add nume_filiala varchar2(30);


alter table filiale drop column adresa;

Stergerea coloanei id_locatie din filiale si adaugarea ei din nou cu restrictia unique si not null
pentru a forma relatia de 1-1

alter table filiale add id_locatie number(2) unique;


alter table filiale drop column id_locatie;
alter table filiale add id_locatie number(2) unique not null;

Modfica restrictia CNP-ului astfel incat el sa inceapa cu 1 sau cu 2 folosind drop

alter table clienti


drop constraint ck_cnp;
alter table clienti
add constraint ck_cnp check (cnp like '1%' or cnp like '2%');

Adaugare restrictie pe salariu, astfel incat sa nu fie negative

alter table angajati


add constraint ck_salariul check(salariul>=0);
III. Structuri alternative si repetitive.

1. Sa se modifice rata bancara a creditului cu id-ul 1. Atunci cand rata este mai mare de
300 se va scadea din aceasta o constanta =10. Altfel se va aduna o constanta egala cu
10.

declare
c_cota number:=10;
v_rata credite.rata%type;

begin

select rata into v_rata from credite where id_credit=1;


if v_rata>=300 then
v_rata:=v_rata-c_cota;
else
v_rata:=v_rata+c_cota;
end if;
dbms_output.put_line('Rata noua: '||v_rata );
end;
2. Sa se afiseze numele si prenumele primilor 5 clienti. Pastrati numerul 5 intr-o
constanta.

DECLARE
c_i number:=5;
v_i number:=0;
v_nume clienti.nume%type;
v_prenume clienti.prenume%type;

begin
while v_i<c_i loop
v_i:=v_i+1;
select nume,prenume into v_nume,v_prenume
from clienti
where id_client=v_i;
dbms_output.put_line('Clientul '|| v_nume||' ' || v_prenume);
end loop;
end;
3. Sa se afiseze numele si primilor 2 angajati care au salariul mai mare de 2500.

declare
v_nume angajati.nume%type;
v_prenume angajati.prenume%type;
begin
for i in 1..2 loop
select nume, prenume into v_nume,v_prenume from angajati where salariul>2500 and
id_angajat=i;
dbms_output.put_line(v_nume || ' '|| v_prenume);
end loop;
end;
4. Sa se afiseze primii 5 clienti

declare
c_i constant number :=5;
v_i number:=0;
v_nume clienti.nume%type;
v_prenume clienti.prenume%type;
begin
while v_i<c_i loop
v_i:=v_i+1;
select nume,prenume into v_nume,v_prenume
from clienti
where id_client=v_i;
dbms_output.put_line('Clientul '|| v_nume||' ' || v_prenume);
end loop;
end;
IV. Tratarea exceptiilor

1. Sa se afiseze primii 3 salariati cu salariul mai mare de 2500.

declare
v_nume angajati.nume%type;
v_prenume angajati.prenume%type;
begin
for i in 1..3 loop
select nume, prenume into v_nume,v_prenume from angajati where salariul>2500 and
id_angajat=i;
dbms_output.put_line(v_nume || ' '|| v_prenume);
end loop;

exception

when no_data_found then


dbms_output.put_line('Nu am gasit date pentru toate valorile.');

end;
2. Sa se afiseze un mesaj pentru exceptia too_many_rows

declare
v_sal angajati.salariul%type;

begin

select salariul into v_sal from angajati;

exception
when too_many_rows then
dbms_output.put_line('Prea multe randuri');

end;
3. Sa se creeze exceptia exc_filiale care se executa atunci cand incercam sa inseram
valori in tabela filiale fara sa se mentioneze adresa.

declare
exc_filiale exception;
pragma exception_init (exc_filiale,-20000);
begin
insert into filiale(id_filiala,numar_angajati) values(9,2);
raise exc_filiale;
exception
when exc_filiale
then
dbms_output.put_line('Nu ati mentionat adresa');

end;
4. Sa se creeze o exceptie ce se executa atunci cand se incearca stergerea din angajati.

declare
cod number;
del_exception exception;
PRAGMA EXCEPTION_INIT(del_exception, -2292);

begin
delete from angajati;

EXCEPTION
WHEN del_exception THEN
dbms_output.put_line('Nu puteti sterge angajati fara permisiune.');

cod:=SQLCODE;

dbms_output.put_line('Cod eroare: ' || cod);


end;
V. Gestionarea cursorilor: impliciti si expliciti, cu si fara parametrii.

1. Sa se afiseze numele si salariul angajatilor folosind un cursor.

declare
cursor n is select nume,salariul from angajati;
v_nume angajati.nume%type;
v_salariul angajati.salariul%type;

begin
open n;
loop
fetch n into v_nume, v_salariul;
exit when n%notfound;
dbms_output.put_line('Salariatul ' || v_nume || ' castiga ' || v_salariul);
end loop;
close n;
end;
2. Sa se afiseze lista cu numele si salariile angajatilor din departamentul 1.

DECLARE
cursor ang_cursor is select id_angajat, nume, salariul from angajati where id_departament=1;
ang_id angajati.id_angajat%type;
ang_nume angajati.nume%type;
ang_sal angajati.salariul%type;
BEGIN
dbms_output.put_line('Lista cu salariariile angajatilor din departamentul 1');
open ang_cursor;
loop
fetch ang_cursor into ang_id, ang_nume, ang_sal;
exit when ang_cursor%notfound;
dbms_output.put_line('Salariatul '||ang_nume||' are salariul: '||ang_sal);
end loop;
close ang_cursor;
end;
3. Sa se afiseze numele tuturor angajatilor.

declare
v_id angajati.id_angajat%type;
v_nume angajati.nume%type;
cursor c1 is select id_angajat, nume from angajati;

BEGIN
open c1;
for i in 1..5 LOOP
fetch c1 into v_id, v_nume;
dbms_output.put_line(v_nume);
end loop;
close c1;
end;
4. Sa se foloseasca un cursor cu parametri pentru a afisa toti angajatii ce au salariul mai
mare decat o valoare data.

declare
cursor c_ang (p_val number) IS
select nume, prenume, salariul
from angajati
where salariul>p_val
order by salariul desc;

v_ang c_ang %rowtype;


v_val NUMBER(5);
BEGIN
v_val:=10;
if not c_ang %ISOPEN then
open c_ang (v_val);
end if;

loop
fetch c_ang into v_ang;
exit when c_ang %notfound;
DBMS_OUTPUT.PUT_LINE(v_ang.nume || ' ' || v_ang.salariul);
end loop;
close c_ang;
end;
VI. Functii, procedure, includerea lor in pachete.

1. Faceti doua proceduri ce modifica dobanda creditelor si depozitelor cu un procent dat.

CREATE OR REPLACE
PROCEDURE modifica_dobanda_credit
(p_id_credit IN credite.id_credit%type, procent IN number)
IS
v_dobanda credite.dobanda%type;
BEGIN
select dobanda into v_dobanda from credite where id_credit=p_id_credit;
dbms_output.put_line('Creditul are dobanda: '||v_dobanda);
update credite
set dobanda=procent
where id_credit=p_id_credit;
select dobanda into v_dobanda from credite where id_credit=p_id_credit;
dbms_output.put_line('Noua dobanda '||v_dobanda);
END;

///////

CREATE OR REPLACE
PROCEDURE modifica_dobanda_depozit
(p_id_depozit IN depozite.id_depozite%type, procent IN number)
IS
v_dobanda depozite.dobanda%type;
BEGIN
select dobanda into v_dobanda from depozite where id_depozite=p_id_depozit;
dbms_output.put_line('Depozitul are dobanda: ' || v_dobanda);
update depozite
set dobanda=procent
where id_depozite=p_id_depozit;
select dobanda into v_dobanda from depozite where id_depozite=p_id_depozit;
dbms_output.put_line('Noua dobanda '||v_dobanda);
END;

2. Sa se realizeze 3 functii care calculeaza suma de plata in cazul unui credit, vechimea
unui depozit si verificarea salariului daca este mai mic sau mai mare decat 1300.

CREATE OR REPLACE FUNCTION calculeaza_suma_de_plata


(p_id_credit IN credite.id_credit%type)
RETURN number
IS
v_rata credite.rata%type;
v_dobanda credite.dobanda%type;
suma number;
BEGIN
SELECT rata into v_rata from credite where id_credit=p_id_credit;
SELECT dobanda into v_dobanda from credite where id_credit=p_id_credit;
suma := v_rata * (v_dobanda/100);
return suma;
EXCEPTION
WHEN no_data_found THEN
return NULL;
end;

///////

create or replace function calculeaza_vechime_depozit


(p_id_depozit in depozite.id_depozite%type)
return number
is
v_zile number:=0;
v_data date;
begin
select data_semnare into v_data from depozite where id_depozite=p_id_depozit;
v_zile := sysdate-v_data;
end;

///////

CREATE OR REPLACE FUNCTION verifica_salariul_1300


(p_id_angajat IN angajati.id_angajat%type)
RETURN Boolean
IS
v_salariul angajati.salariul%type;
BEGIN
SELECT salariul into v_salariul from angajati where id_angajat=p_id_angajat;
IF v_salariul > 1300 then
return true;
ELSE
return false;
end if;
EXCEPTION
WHEN no_data_found THEN
return NULL;
end;

3. Sa se realizeze un pachet banca care sa contina toate functiile si procedurile de mai sus

create or replace package banca


is
procedure modifica_dobanda_credit(p_id_credit IN credite.id_credit%type, procent
IN number);
PROCEDURE modifica_dobanda_depozit
(p_id_depozit IN depozite.id_depozite%type, procent IN number);
FUNCTION calculeaza_suma_de_plata
(p_id_credit IN credite.id_credit%type)
return number;
function calculeaza_vechime_depozit
(p_id_depozit in depozite.id_depozite%type)
return number;
FUNCTION verifica_salariul_1300
(p_id_angajat IN angajati.id_angajat%type)
return number;
exc exception;
end;

VII. Declansatori

1. Sa se realizeze un declansator pe credite la inserari si actualizari.


create or replace TRIGGER credite_trig
BEFORE INSERT or UPDATE or DELETE on credite
DECLARE
v_mesaj varchar(500);
BEGIN
case
when INSERTING then v_mesaj :='A avut loc o inserare';
when UPDATING then v_mesaj:='A avut loc o updatare.';
ELSE v_mesaj :='A avut loc o stergere';
END case;
dbms_output.put_line(v_mesaj);
END;

2. Sa se realizeze un declansator pe dobanzi la inserari, daca noua dobanda e mai mare


decat cea maxima.

create or replace TRIGGER restrict_dobanda


BEFORE INSERT or UPDATE on credite
FOR EACH ROW
DECLARE
v_dob_max number;
BEGIN
select max(dobanda) into v_dob_max from credite;
IF :new.dobanda>v_dob_max then
RAISE_APPLICATION_ERROR (-20202, 'Nu se poate depasi dobanda
maxima pentru creditul dat.');
end if;
END;