BD II (SI 587) Funções Definidas pelo Usuário Prof. Josenildo Silva jcsilva@ifma.edu.br
Funções definidas pelo usuário Funções precisam obrigatoriamente retornar um valor Somente aceitam parâmetros do tipo IN Podem ser utilizadas em cláusulas SQL (WHERE, ORDER BY, GROUP BY, etc)
Utilização Geralmente usadas para calcular alguma expressão ou fazer manipulação de valores simples Regras de negócio complexas são colocadas em procedures Não reinvente a roda Oracle, MySQL, PostegreSQL possuem um grande número de funções pré-definidas
Restrições Não podem conter instruções DDL (CREATE, ALTER, DROP) Não podem finalizar transações Aceitam e retornam somente tipos de dados SQL
Restrições Em geral, funções são chamadas a cada linha do resultado SQL Potencialmente onera a execução Talvez deva-se realizar este processamento na aplicação
Sintaxe (Padrão) CREATE FUNCTION <nome> (<params>) RETURNS <tipo de retorno> <declaracoes de variaveis locais> <corpo da funcao> ;
Funções no MySQL
Funções no MySQL Uma função é determinística se ela sempre retorna o mesmo resultado para os mesmos parâmetros de entrada, Não deterministica caso contrário. Esta informação é útil para o otimizador.
Exemplo de função no MySQL mysql> CREATE FUNCTION hello (s CHAR(20)) mysql> RETURNS CHAR(50) DETERMINISTIC -> RETURN CONCAT('Hello, ',s,'!'); Query OK, 0 rows affected (0.00 sec) mysql> SELECT hello('world'); +----------------+ hello('world') +----------------+ Hello, world! +----------------+
Exemplo MySQL: média de notas DELIMITER CREATE FUNCTION media (nome VARCHAR(10)) RETURNS FLOAT DETERMINISTIC BEGIN DECLARE n1,n2,n3,n4 INT; DECLARE med FLOAT; SELECT nota1,nota2,nota3,nota4 INTO n1, n2, n3, n4 FROM notas WHERE aluno = nome; SET med = (n1 + n2 + n3 + n4) / 4; RETURN med; END DELIMITER ; Para chamar esta função SELECT aluno, media(aluno) FROM notas; Fonte: http://ajuda.locaweb.com.br/pt-br/como_criar_functions_no_mysql_5.0
Exemplo MySQL: Função com cursores DELIMITER $$ CREATE FUNCTION fn_valortotalemestoque() RETURNS decimal(9,2) BEGIN DECLARE quantidade int(11) default 0; DECLARE valor decimal(9,2) default 0.0; DECLARE total_valor decimal(9,2) default 0.0; DECLARE done INT DEFAULT FALSE; # cursor para buscar os registros a serem processados # com quantidade > 0 DECLARE busca_estoque CURSOR FOR SELECT qtde, valor_unitario FROM estoque where qtde > 0; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
Exemplo MySQL: função com cursores SET total_valor = 0; # abre o cursor OPEN busca_estoque; # inicia o loop estoque: LOOP ## recebe o valor do percentual de cada vendedor FETCH busca_estoque INTO quantidade, valor; IF done THEN LEAVE estoque; END IF; SET total_valor = total_valor + (quantidade * valor); END LOOP estoque; # fecha o cursor CLOSE busca_estoque; RETURN total_valor; END $$ Para chamar esta função DELIMITER ; SELECT fn_valortotalemestoque();
Funções no Oracle
Funções no Oracle CREATE [OR REPLACE] FUNCTION <name> [ (par1 type1, par2 type2,...) ] RETURN <datatype> IS AS BEGIN... EXCEPTION... END <name>;
Funções no Oracle (parametro IN) CREATE OR REPLACE FUNCTION f_salary( p_id IN EMPLOYEES.EMPLOYEE_ID%TYPE) RETURN NUMBER IS v_sal EMPLOYEES.SALARY%TYPE; BEGIN SELECT SALARY INTO v_sal FROM EMPLOYEES WHERE EMPLOYEE_ID = p_id; RETURN v_sal*1.1; END f_salary;
Funções no Oracle -- Execucao 1: SELECT EMPLOYEE_ID,SALARY,f_salary(EMPLOYEE_ID) FROM EMPLOYEES; -- Execucao 2: DECLARE BEGIN END; sal NUMBER; sal := f_salary(176); DBMS_OUTPUT.PUT_LINE(' Salario com aumento de 10%: ' TO_CHAR(sal) );
Funções exemplo de restrição CREATE OR REPLACE FUNCTION F_DELETE( p_id IN EMPLOYEES.EMPLOYEE_ID%TYPE) RETURN NUMBER IS BEGIN DELETE EMPLOYEES WHERE EMPLOYEE_ID = p_id; COMMIT; RETURN TO_NUMBER(SQL%ROWCOUNT); END F_DELETE; -- Tentativa de execução SELECT LAST_NAME,F_DELETE(EMPLOYEE_ID) FROM EMPLOYEES
Leitura Adicional Seção 9.6 do SILBERSCHATZ: Funções e Procedimentos Tutorial sobre Procedimentos no MySQL por Wagner Bianchi. http://imasters.com.br/artigo/7556/mysql/ stored_procedures_no_mysql/ http://www.mysqltutorial.org/introductionto-sql-stored-procedures.aspx
Links interessantes http://dev.mysql.com/doc/refman/5.1/en/stored-routines.html http://www.mysqltutorial.org http://www.databasejournal.com/features/mysql/article.php/352 5581/MySQL-Stored-Procedures-Part-1.htm http://www.oficinadanet.com.br/artigo/2088/criando_stored_pro cedures_no_mysql http://www.brainbell.com/tutorials/mysql/using_stored_proced ures.htm