Sintaxe:

CREATE [DEFINER = {user | CURRENT_USER}] FUNCTION func_name ([func_parameter[,...]]) RETURNS type [characteristic ...] RETURN func_body

func_parameter: param_name type

type: Any valid MySQL data type

characteristic: LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER } | COMMENT 'string'

func_body: Valid SQL procedure statement

Descrição:

Use a instrução CREATE FUNCTION para criar uma nova função. Você deve possuir o privilégio CREATE ROUTINE para usar CREATE FUNCTION.

Uma função aceita varios argumentos e retorna um valor do corpo da função. O corpo da função pode ser qualquer expressão SQL válida, como você poderia usar por exemplo, em qualquer expressão select. Se você tem os privilégios apropriados, você pode chamar a função exatamente como você o faria com qualquer função incorporada. Veja Security abaixo para obter detalhes sobre privilégios.

Você também pode usar uma variante da instrução CREATE FUNCTION para instalar uma função definida pelo usuário (UDF), definida por um plugin. Veja CREATE FUNCTION (UDF) para obter detalhes.

Você pode usar uma instrução SELECT para o corpo da função, colocando ela entre parênteses, exatamente como você o faria ao usar um subselect para qualquer outra expressão. A instrução SELECT deve retornar um único valor. Se mais de uma coluna é retornada quando a função é chamada, ocorrerá o erro 1241. Se mais de uma linha é retornada quando a função é chamada, ocorrerá um erro 1242. Use uma cláusula LIMIT para garantir que somente irá ser retornada uma linha.

Você também pode substituir a cláusula RETURN com a instrução composta BEGIN...END#. A instrução composta deve conter uma instrução RETURN. Quando a função for chamada, a instrução RETURN imediatamente retornará seu resultado e quaisquer instrução após RETURN será ignorada efetivamente.

Por padrão, uma função está associada com o banco de dados padrão. Para associar uma função explicitamente com um banco de dados determinado, especifique o nome plenamente qualificado como db_name.func_name ao você criá-la. Se o nome da função é igual ao nome de uma função incorporada, você deve usar o nome plenamente qualificado ao chamá-la.

A lista de parâmetros colocada entre parênteses deve estar sempre presente. Se não tiver parâmetros , uma lista vazia de parâmetros de () deveria ser usada. Os nomes de parâmetro não são sensíveis a letras maiúsculas e minúsculas.

Cada parâmetro pode ser declarado usando qualquer tipo de dado válido, exceto que o atributo COLLATE não possa ser usado.

A cláusula RETURNS especifica o tipo de retorno da função. Se a cláusula RETURN retorna o valor de um tipo diferente. o valor é forçado para o tipo adequado. Por exemplo, se uma função especifica o valor ENUM ou o valor SET na cláusula RETURNS, mas a cláusula RETURN retorna um inteiro, o valor retornado pela função é o string para o membro ENUM correspondente do conjunto de membros SET.

O MySQL armazena a configuração da variável de sistema sql_mode que está em vigor no momento em que a rotina é criada, e sempre executa a rotina com esta configuração em vigor, independentemente do modo SQL do servidor em vigor quando a rotina é invocada.

MySQL stores the sql_mode system variable setting that is in effect at the time a routine is created, and always executes the routine with this setting in force, regardless of the server SQL mode in effect when the routine is invoked.

Segurança

Você deve possuir o privilégio EXECUTE em uma função para poder chamá-la. O MariaDB automaticamente concede os privilégios EXECUTE e ALTER ROUTINE à conta que chamou CREATE FUNCTION, mesmo que a cláusula DEFINER tenha sido usada.

Cada função tem uma conta associada como o definidor. Por padrão, o definidor é a conta que criou a função. Use a cláusula DEFINER para especificar uma conta diferente com o definidor. Você deve possuir o privilégio SUPER para usar a cláusula DEFINER. Veja Account Names para mais informação sobre especifiação de contas.

A cláusula SQL SECURITY especifica que privilégios são usados quando uma função é chamada. Se SQL SECURITY for INVOKER, o corpo da função será avaliado usando os privilégios do usuário que chama a função. Se SQL SECURITY for DEFINER, o corpo da função é sempre avaliado usando os privilégios da conta definidora. DEFINER é o padrão.

Isto lhe permite criar funções que concedem acesso limitado à certos dados. Por exemplo, digamos que você tem uma tabela que armazena informação dos empregados, e que você tem concedido privilégios SELECT somente à certas colunas para a conta de usuário roger.

CREATE TABLE employees (name TINYTEXT, dept TINYTEXT, salary INT);
GRANT SELECT (name, dept) ON employees TO roger;

Para permitir o usuário obter o salário máximo para um departamento, defina uma função e conceda o privilégio EXECUTE:

CREATE FUNCTION max_salary (dept TINYTEXT) RETURNS INT RETURN
  (SELECT MAX(salary) FROM employees WHERE employees.dept = dept);
GRANT EXECUTE ON FUNCTION max_salary TO roger;

Já que SQL SECURITY é DEFINER, sempre que o usuário roger chamar esta função, o subselect irá se executar com seus privilégios. Enquanto você tiver privilégios para selecionar o salário de cada empregado, quem tenha chamado a função poderá obter o salário máximo de cada departamento sem ser capaz de ver os salários individuais.

Exemplos

No seguinte exemplo, a função recebe um parâmetro, executa uma operação usando uma função SQL e retorna o resultado.

MariaDB [test]> CREATE FUNCTION hello (s CHAR(20))
    -> RETURNS CHAR(50) DETERMINISTIC
    -> RETURN CONCAT('Hello, ',s,'!');
Query OK, 0 rows affected (0.00 sec)

MariaDB [test]> SELECT hello('world');
+----------------+
| hello('world') |
+----------------+
| Hello, world!  |
+----------------+
1 row in set (0.00 sec)

MariaDB [test]>

Você pode usar uma instrução composta em uma função para manipular dados com instruções como INSERT e UPDATE. O exemplo a seguir cria uma função contador que usa uma tabela temporária para armazenar o valor atual. Dado que a instrução composta contém instruções encerradas com ponto e vírgula, primeiramente você tem que alterar o delimitador da instrução com a instrução DELIMITER para permitir que o ponto e vírgula seja usado no corpo da função

CREATE TEMPORARY TABLE counter (c INT);
INSERT INTO counter VALUES (0);
DELIMITER //
CREATE FUNCTION counter () RETURNS INT
  BEGIN
    UPDATE counter SET c = c + 1;
    RETURN (SELECT c FROM counter LIMIT 1);
  END //
DELIMITER ;

Comments

Comments loading...