DROP TYPE student; DROP TYPE angajat; CREATE OR REPLACE TYPE Persoana AS OBJECT ( nume varchar2(20), prenume varchar2(20), cnp char(13), map member function virsta return number, member function datan return date, member function validcnp return boolean, member function afisare return string ) NOT FINAL; / CREATE or replace TYPE BODY Persoana AS map member function virsta return number is -- functie locala function years_between(d1 date, d2 date) return number is n number; begin if (d1=d2) then return 0; end if; if (d1 is null or d2 is null) then return null; end if; n:=(d1-d2)/365.25; -- determina o valoare aproximativa return n; end; begin return years_between(sysdate,datan()); end; member function datan return date is an char(2); s char(1); begin /* Prima cifra a CNP-ului este: (sex barbatesc / sex femeiesc) 1 / 2 - nascuti între 1 ianuarie 1900 si 31 decembrie 1999 3 / 4 - nascuti între 1 ianuarie 1800 si 31 decembrie 1899 5 / 6 - nascuti între 1 ianuarie 2000 si 31 decembrie 2099 */ s:=substr(cnp,1,1); an:='20'; if s='1' or s='2' then an:='19'; end if; if s='3' or s='4' then an:='18'; end if; return to_date(an || substr(cnp,2,2) || substr(cnp,4,2) || substr(cnp,6,2),'yyyymmdd'); end; member function validcnp return boolean is /* Dupa: http://ro.wikipedia.org/wiki/Cod_numeric_personal Cifra de control (a 13-a) este calculata dupa cum urmeaza: - fiecare cifra din CNP (poz.1..12) este inmultita cu cifra de pe aceeasi pozitie din numarul 279146358279; - rezultatele sunt insumate, - rezultatul final este impartit cu rest la 11. - daca restul este 10, atunci cifra de control este 1, altfel cifra de control este egala cu restul impartirii. */ s number; i number; p char(12) := '279146358279'; begin s:=0; for i in 1..12 loop s:=s+to_number(substr(cnp,i,1))*to_number(substr(p,i,1)); end loop; s:=mod(s,11); if s=10 then s:=1; end if; if s=to_number(substr(cnp,13,1)) then return true; else return false; end if; end; member function afisare return string is s varchar(200); r char(6); begin s:='Nume: ' || nume; s:=s || '; ' || 'Prenume: '||prenume; if validcnp() then r:='Corect'; else r:='Eronat'; end if; s:=s || '; ' || 'CNP: '|| cnp || ' - ' || r; s:=s || '; ' || 'Varsta: '|| to_char(virsta(),'999.99'); s:=s || '; ' || 'Data nasterii: '||to_char(datan()); return s; end; end;