Você está na página 1de 24

Stored Procedures

Luciano F. de Medeiros
Definição
• Uma stored procedure é um segmento de um
comando declarativo gravado dentro do
catálogo do banco de dados.
• Uma stored procedure pode ser chamada por
gatilhos (“triggers”) , por outras stored
procedures ou por aplicações em Java, C#,
PHP, etc.
• Uma stored procedure pode inclusive chamar
ela mesma.
Vantagens
• SP auxiliam a aumentar a performance das aplicações;
uma vez criadas, elas são compiladas e armazenadas
no BD (MySQL compila sob demanda, depois de
compiladas, as SP são colocadas no cache)
• SP reduzem o tráfego entre as aplicações e o servidor
de BD
• SP são reutilizáveis e transparentes para qualquer
aplicação
• SP são seguras. O DBA pode garantir as permissões
para as aplicações a partir das SPs, sem precisar dar
qualquer permissão às tabelas diretamente.
Desvantagens
• O uso de SP pode aumentar o uso de memória
• É difícil depurar SP (MySQL não provê
ferramentas para fazer debug de SP)
• Desenvolver e manter SP requer habilidades
que nem todo desenvolvedor pode ter
Sintaxe Geral
// Criação da SP
CREATE PROCEDURE <nome> (IN/OUT/INOUT <parâmetro>
<tipo_do_parâmetro>, ...)
BEGIN
...
<comandos SQL>
...
END;

// Execução da SP
CALL <nome>;
Sintaxe Geral
// Apagando a SP
DROP PROCEDURE <nome>

// Apagando se existir a SP criada


DROP PROCEDURE IF EXISTS <nome>;
Exemplo de uma SP simples
• Listar todos os
clientes da tabela
CLIENTE (banco de
dados SAKILA)

CREATE PROCEDURE
GetClientes()
BEGIN
SELECT * FROM cliente;
END;
Executando a SP

CALL GetClientes();
Parâmetros para SP
• Sintaxe:

MODE <nome> <tipo> ( <tamanho> )

• MODE pode ser IN, OUT ou INOUT


• <nome> é o nome da variável
• <tipo> é o tipo da variável
• <tamanho> é o tamanho da variável
Exemplos (IN)
• Liste os clientes ativos:
DROP PROCEDURE IF EXISTS GetClientes;
CREATE PROCEDURE GetClientes(IN param_ativo INT)
BEGIN
SELECT * FROM cliente WHERE ativo = param_ativo;
END;

• Executando:

CALL GetClientes(1); SET @ativo = 1;


CALL GetClientes(@ativo);
Exemplos (IN)
• Liste os clientes pelo primeiro nome:
DROP PROCEDURE IF EXISTS GetClientesFromNome;
CREATE PROCEDURE GetClientesFromNome(IN
param_nome VARCHAR(50))
BEGIN
SELECT * FROM cliente WHERE primeiro_nome =
param_nome;
END;
• Executando:
CALL GetClientesFromNome(‘LISA');

SET @nome= ‘LISA’;


CALL GetClientesFromNome(@nome);
Exemplos (IN)

• Liste os clientes pelo nome completo:

DROP PROCEDURE IF EXISTS


GetClientesFromNomeCompleto;
CREATE PROCEDURE
GetClientesFromNomeCompleto(IN param_nome1
VARCHAR(50), IN param_nome2 VARCHAR(50))
BEGIN
SELECT * FROM cliente WHERE primeiro_nome =
param_nome1 AND ultimo_nome= param_nome2;
END;
Dois parâmetros de entrada

• Executando:
CALL GetClientesFromNomeCompleto('LISA',
'ANDERSON');

SET @nome1= 'LISA';


SET @nome2= 'ANDERSON';

CALL GetClientesFromNomeCompleto(@nome1,
@nome2);
Exemplos (OUT)
• Faça a contagem dos clientes

DROP PROCEDURE IF EXISTS CountClientes;


CREATE PROCEDURE CountClientes(OUT total INT)
BEGIN
SELECT COUNT(*) AS total FROM cliente;
END;

• Executando:
CALL CountClientes(@total);
Exemplo misto (IN, OUT)
• Some o total locado por id de cliente
DROP PROCEDURE IF EXISTS GetValorPorCliente;
CREATE PROCEDURE GetValorPorCliente(IN id INT, OUT total INT)
BEGIN
SELECT cliente.cliente_id, SUM(filme.preco_da_locacao) AS total
FROM ((cliente JOIN aluguel ON cliente.cliente_id = aluguel.cliente_id)
JOIN inventario ON inventario.inventario_id = aluguel.inventario_id)
JOIN filme ON filme.filme_id = inventario.filme_id
WHERE cliente.cliente_id = id
GROUP BY cliente.cliente_id;
END;

CALL GetValorPorCliente(1,@total);
Exemplo com INOUT
• Contador de incremento variável

CREATE PROCEDURE set_counter(INOUT count


INT(4),IN inc INT(4))
BEGIN
SET count = count + inc;
END;
Executando com INOUT

SET @counter = 1;

CALL set_counter(@counter,1); /* --> 2 */

CALL set_counter(@counter,1); /* --> 3 */

CALL set_counter(@counter,5); /* --> 8 */

SELECT @counter;
SP com Retornos Múltiplos
• Faça um relatório de filmes por categoria
DROP PROCEDURE IF EXISTS GetFilmesPorCategoria;
CREATE PROCEDURE GetFilmesPorCategoria(OUT action INT, OUT drama INT, OUT comedy
INT)
BEGIN
SELECT COUNT(*) INTO action FROM filme
JOIN filme_categoria ON filme.filme_id=filme_categoria.filme_id
JOIN categoria ON categoria.categoria_id=filme_categoria.categoria_id
WHERE categoria.nome='Action';

SELECT COUNT(*) INTO drama FROM filme


JOIN filme_categoria ON filme.filme_id=filme_categoria.filme_id
JOIN categoria ON categoria.categoria_id=filme_categoria.categoria_id
WHERE categoria.nome='Drama';

SELECT COUNT(*) INTO comedy FROM filme


JOIN filme_categoria ON filme.filme_id=filme_categoria.filme_id
JOIN categoria ON categoria.categoria_id=filme_categoria.categoria_id
WHERE categoria.nome='Comedy';

END;
Executando

CALL GetFilmesPorCategoria(@action,@drama,@comedy);

SELECT @action,@drama,@comedy;
Declaração de Variáveis
• Uma variável é um objeto nomeado de dados
cujo valor pode mudar durante a execução da
SP
• Tipicamente utiliza-se variáveis em SP para
manter resultados imediatos
• Estas variáveis são locais à SP
Comando
• DECLARE <nome>
<tipo_de_dado>(<tamanho>) DEFAULT
<valor_default>;
• <nome> - Nome da variável
• <tipo_de_dado> - Tipo da variável
• <tamanho> - Tamanho da variável
• <valor_default> - Valor inicial
Exemplos
• DECLARE valor INT DEFAULT 0;
• DECLARE temp VARCHAR(25) DEFAULT ‘’;
• DECLARE soma DECIMAL(12,2) DEFAULT 0;
• DECLARE concluido BOOLEAN DEFAULT false;
Exemplo
• Quantidade de títulos alugados
DROP PROCEDURE IF EXISTS GetQuantLoc;
CREATE PROCEDURE GetQuantLoc(OUT valor INT)
BEGIN
DECLARE quant INT DEFAULT 0;
SELECT COUNT(*) INTO quant FROM aluguel;
SET valor = quant;
END;

CALL GetQuantLoc(@loc);
SELECT @loc;
Referências
• http://www.mysqltutorial.org/stored-
procedures-parameters.aspx

Você também pode gostar