DAM - DAW - MP 0484 Bases de Dades - NF5
Pràctica 10 – Funcions
En aquesta pràctica, creareu funcions emmagatzemades; i les fareu servir des d’una comanda SQL o des d’un procediment emmagatzemat.
Per fer aquests exercicis cal tenir les següents taules creades (Compte que li deixem les PKs):
CREATE OR REPLACE TABLE EMPLEATS LIKE empresa.EMPLOYEES;
INSERT INTO EMPLEATS SELECT * FROM empresa.EMPLOYEES;
CREATE OR REPLACE TABLE DEPARTAMENTS AS SELECT * FROM empresa.DEPARTMENTS;
CREATE OR REPLACE TABLE FEINES LIKE empresa.JOBS;
INSERT INTO FEINES SELECT * FROM empresa.JOBS;
Canvieu el delimitador per a treballar millor (si ho feu des de la shell)
DELIMITER //
Es recomana, per possibles errades, treballar amb una transacció
START TRANSACTION //
SAVEPOINT P1 //
ROLLBACK TO P1 //
-
Creeu i utilitzeu la funció
Q_FEINAper retornar el títol de feina a partir del codi de feina.-
Creeu una funció anomenada
Q_FEINAper retornar el títol de feina (job_title). -
Utilitzeu la funció passant coma
job_idel valor'SA_REP'.
Possible solucio
DELIMITER // CREATE OR REPLACE FUNCTION Q_FEINA(p_job_id TYPE OF feines.job_id) RETURNS VARCHAR(35) READS SQL DATA BEGIN DECLARE v_job_title TYPE OF feines.job_title; SELECT job_title INTO v_job_title FROM feines WHERE job_id = p_job_id; RETURN v_job_title; END // DELIMITER ; SELECT Q_FEINA('SA_REP'); SELECT LAST_NAME, Q_FEINA(job_id) FROM EMPLEATS WHERE EMPLOYEE_ID < 200; -
-
Creeu una funció anomenada
SOU_ANUALper retornar el salari anual acceptant dos paràmetres: el salari i la comissió mensual.-
Creeu i invoqueu la funció
SOU_ANUAL, passant els valors del salari mensual i comissió. El salari anual ve definit per la fórmula següent:(salary*12) + (commission_pct* salary*12) -
Utilitzeu la funció en una sentència
SELECTsobre la taulaEMPLEATSper al departament80.+-----------+------------------------+ | LAST_NAME | SOU_ANUAL(employee_id) | +-----------+------------------------+ | Zlotkey | 151200.00 | | Abel | 171600.00 | | Taylor | 123840.00 | +-----------+------------------------+
Possible solució
DELIMITER // CREATE OR REPLACE FUNCTION SOU_ANUAL( p_employee_id TYPE OF empleats.employee_id) RETURNS DECIMAL(8,2) BEGIN DECLARE v_salary TYPE OF empleats.salary; DECLARE v_commission_pct TYPE OF empleats.commission_pct; DECLARE v_souFinal TYPE OF empleats.salary DEFAULT 0; SELECT salary, commission_pct INTO v_salary, v_commission_pct FROM empleats WHERE employee_id = p_employee_id; IF v_salary IS NOT NULL THEN IF v_commission_pct IS NOT NULL THEN SET v_souFinal = v_commission_pct * v_salary * 12; END IF; SET v_souFinal = v_souFinal + (v_salary * 12); END IF; RETURN v_souFinal; END // DELIMITER ; SELECT LAST_NAME, SOU_ANUAL(employee_id) FROM EMPLEATS WHERE DEPARTMENT_ID = 80; -
-
Creeu un procediment,
NOU_EMP, per afegir un nou empleat a la taulaEMPLEATS. El procediment ha de contenir una crida a la funcióVALID_DEPTIDper comprovar si l’identificador de departament especificat per al nou empleat existeix a la taulaDEPARTAMENTS.-
Creeu la funció
VALID_DEPTIDper validar un identificador de departament especificat. La funció ha de retornar un valorBOOLEÀ. -
Creeu el procediment
NOU_EMPper afegir un empleat a la taulaEMPLEATS. S'ha d'afegir una nova fila a la taulaEMPLEATSsi la funció retornaTRUE. Si la funció retornaFALSE, s’ha d'alertar l'usuari amb un missatge d’error adequat i no es farà l’alta de l’empleat. -
Definiu els valors per defecte per a la majoria de paràmetres. La comissió per defecte és
NULL, el salari per defecte és 1000, el número de departament predeterminat és 30, el treball per defecte ésSA_REPi el valor per defecte del manager_id és de 145. -
Proporcioneu també el cognom i el nom. El correu electrònic de l'empleat serà la inicial del nom + el cognom sense espais i tot en majúscula amb un màxim de 25 caràcters. La data de contractació serà el dia del sistema.
En MariaDB no podem definir valors per defecte en una funció o procediment, per tant, quan diem per defecte, serà, quan al procediment se li hagi passat un valor NULL al lloc on s’esperava un valor d’un camp específic.
-
Proveu el procediment
NOU_EMPafegint una nova empleada anomenada"Jane Harris"al departament15. Tots els altres paràmetres són els predeterminats. -
Proveu el procediment de
NOU_EMPafegint un nou empleat anomenat"Joe Harris"al departament80. Tots els altres paràmetres són els predeterminats.
Possible solució
DELIMITER // CREATE OR REPLACE FUNCTION VALID_DEPTID( p_department_id TYPE OF departaments.department_id) RETURNS BOOLEAN BEGIN DECLARE v_department_id TYPE OF departaments.department_id; SELECT department_id INTO v_department_id FROM departaments WHERE department_id = p_department_id; RETURN v_department_id IS NOT NULL; END; // CREATE OR REPLACE PROCEDURE NOU_EMP( p_first_name TYPE OF empleats.first_name, p_last_name TYPE OF empleats.last_name, p_phone_number TYPE OF empleats.phone_number, p_job_id TYPE OF empleats.job_id, p_salary TYPE OF empleats.salary, p_commission_pct TYPE OF empleats.commission_pct, p_manager_id TYPE OF empleats.manager_id, p_department_id TYPE OF empleats. department_id) BEGIN DECLARE v_employee_id TYPE OF empleats.employee_id ; DECLARE v_email TYPE OF empleats.email; DECLARE v_hire_date TYPE OF empleats.hire_date DEFAULT CURRENT_DATE(); IF p_first_name IS NULL THEN SET v_email = LEFT(UPPER(REPLACE(p_last_name, ' ' ,'')), 25); ELSE SET v_email = LEFT(UPPER(CONCAT(LEFT(p_first_name, 1), REPLACE(p_last_name, ' ' ,''))), 25); END IF; IF p_salary IS NULL THEN SET p_salary = 1000; END IF; -- IF p_commission_pct IS NULL THEN SET p_commission_pct = 0; END IF; IF p_department_id IS NULL THEN SET p_department_id = 30; END IF; IF p_job_id IS NULL THEN SET p_job_id = 'SA_REP'; END IF; IF p_manager_id IS NULL THEN SET p_manager_id = 145; END IF; SELECT IFNULL(MAX(EMPLOYEE_ID), 0) + 1 INTO v_employee_id FROM empleats; INSERT INTO EMPLEATS(employee_id, first_name, last_name, email, phone_number, hire_date, job_id, salary, commission_pct, manager_id, department_id) VALUES (v_employee_id, p_first_name, p_last_name, v_email, p_phone_number, CURRENT_DATE(), p_job_id, p_salary, p_commission_pct, p_manager_id, p_department_id); END // DELIMITER ; START TRANSACTION; CALL NOU_EMP('Jane', 'Harris', NULL, NULL, NULL, NULL, NULL, NULL); SELECT * FROM EMPLEATS; CALL NOU_EMP('Joe', 'Harris', NULL, NULL, NULL, NULL, NULL, NULL); ROLLBACK; -