O MySQL nos fornece a capacidade de criar procedimentos armazenados . Os procedimentos armazenados são uma parte poderosa do MySQL (e de outros sistemas de gerenciamento de banco de dados, como o SQL Server) e permitem que você faça mais do que as visualizações.
Um procedimento armazenado é uma coleção de instruções SQL que são armazenadas no banco de dados. Um procedimento armazenado pode conter lógica de negócios, que é um dos principais aspectos que distinguem procedimentos armazenados de exibições. Um procedimento armazenado pode aceitar parâmetros e você pode definir variáveis, escrever
IF
instruções, etc dentro de um procedimento armazenado. Como funcionam os procedimentos armazenados?
Em primeiro lugar, você cria o procedimento armazenado. Então, uma vez criado, você pode executá-lo (ou mais precisamente, você "chama").
Para executar um procedimento armazenado, você o "chama". Ao chamá-lo, você também fornece quaisquer parâmetros que possam ser necessários. O procedimento armazenado será executado, usando seus parâmetros de qualquer maneira que o código especificar.
Por exemplo, você pode escrever um procedimento armazenado que aceite um
FruitId
parâmetro. O procedimento armazenado poderia então pegar esse parâmetro e usá-lo para verificar o inventário dessa fruta específica. Portanto, você poderia chamar o procedimento armazenado, cada vez com um ID de fruta diferente e retornaria um valor que mostra quanto dessa fruta está em estoque. Criar um procedimento armazenado
Os procedimentos armazenados são criados usando o
CREATE PROCEDURE
demonstração. Sintaxe
Aqui está a sintaxe para criar um procedimento armazenado:
CREATE PROCEDURE sp_name(p_1 INT) BEGIN ...code goes here... END;
Substituir sp_name com qualquer nome que você gostaria de usar para o procedimento armazenado. Os parênteses são obrigatórios — eles incluem quaisquer parâmetros. Se nenhum parâmetro for necessário, os parênteses podem estar vazios.
O corpo principal do procedimento armazenado fica entre o
BEGIN
e END
palavras-chave. Essas palavras-chave são usadas para escrever instruções compostas. Uma instrução composta pode conter várias instruções e elas podem ser aninhadas, se necessário. Portanto, você pode aninhar BEGIN
e END
blocos. Na maioria dos casos, você também precisará cercar o
CREATE PROCEDURE
instrução com DELIMITER
comandos e altere END;
para END //
. Assim:DELIMITER // CREATE PROCEDURE sp_name(p_1 INT) BEGIN ...code goes here... END // DELIMITER ;
Vou explicar o porquê em breve, mas por enquanto, vamos ver um exemplo.
Exemplo
Aqui está um exemplo simples de criação de um procedimento armazenado. Executando o seguinte código em nosso FruitShop banco de dados criará um procedimento armazenado chamado spCheckFruitStock :
DELIMITER // CREATE PROCEDURE spCheckFruitStock(thisFruit SMALLINT) BEGIN SELECT Fruit.FruitName, Fruit.Inventory, Units.UnitName FROM Fruit INNER JOIN Units ON Fruit.UnitId = Units.UnitId WHERE Fruit.FruitId = thisFruit; END // DELIMITER ;
Agora podemos chamar esse procedimento armazenado assim:
CALL spCheckFruitStock(1);
Aqui, passamos um parâmetro de
1
que é o ID da
Apple
. Aqui está o resultado:
Podemos fazer o mesmo para qualquer fruta em nosso banco de dados, simplesmente alterando o parâmetro passado para o procedimento armazenado.
Sobre o DELIMITER
Comando
No exemplo acima, adicionamos alguns
DELIMITER
comandos e substituímos um ponto e vírgula por duas barras. O que está acontecendo aqui? Fizemos isso para dizer ao MySQL para usar um delimitador diferente enquanto cria nosso procedimento armazenado.
A razão para isso é que o MySQL já reconhece o ponto e vírgula como um delimitador para marcar o final de cada instrução SQL. Portanto, assim que o MySQL vir o primeiro ponto e vírgula, ele interpretará o delimitador como tal e nosso procedimento armazenado será interrompido.
O
DELIMITER
O comando nos permite dizer ao MySQL para usar um delimitador diferente. No exemplo acima definimos isso como duas barras (//
), mas isso poderia ter sido qualquer coisa (embora, evite usar uma barra invertida (\
) pois esse é o caractere de escape para MySQL). Ao alterar o delimitador, o MySQL não tentará interpretar nosso ponto e vírgula como o final da instrução — ele aguardará até ver as duas barras. Depois de criar o procedimento armazenado, podemos usar
DELIMITER ;
para redefinir o delimitador de volta ao ponto e vírgula. Descartando um procedimento armazenado
Você pode descartar um procedimento armazenado usando o
DROP PROCEDURE
demonstração. Assim:DROP PROCEDURE spCheckFruitStock;
Alterando um procedimento armazenado
Você pode alterar algumas aspectos de um procedimento armazenado usando o
ALTER PROCEDURE
demonstração. No entanto, para alterar o corpo do procedimento armazenado ou qualquer um de seus parâmetros, você precisa descartar o procedimento e criá-lo novamente. Assim:
DROP PROCEDURE IF EXISTS spCheckFruitStock; DELIMITER // CREATE PROCEDURE spCheckFruitStock(thisFruit SMALLINT) BEGIN SELECT Fruit.FruitId, Fruit.FruitName, Fruit.Inventory, Units.UnitName FROM Fruit INNER JOIN Units ON Fruit.UnitId = Units.UnitId WHERE Fruit.FruitId = thisFruit; END // DELIMITER ;
Aqui, adicionamos
Fruit.FruitId
para a lista de colunas a serem retornadas. Resultado:
Um procedimento armazenado mais avançado
O exemplo acima foi simples para demonstrar a sintaxe de criação e chamada de procedimentos armazenados. Vejamos um procedimento armazenado um pouco mais complexo:
DROP PROCEDURE IF EXISTS spCheckFruitStockLevel; DELIMITER // CREATE PROCEDURE spCheckFruitStockLevel( IN pFruitId SMALLINT(5), OUT pStockLevel VARCHAR(6)) BEGIN DECLARE stockNumber SMALLINT; SELECT Fruit.Inventory into stockNumber FROM Fruit INNER JOIN Units ON Fruit.UnitId = Units.UnitId WHERE Fruit.FruitId = pFruitId; IF stockNumber > 10 THEN SET pStockLevel = 'High'; ELSEIF (stockNumber <= 10 AND stockNumber >= 5) THEN SET pStockLevel = 'Medium'; ELSEIF (stockNumber < 5) THEN SET pStockLevel = 'Low - Please Replace Now!'; END IF; END // DELIMITER ;
O exemplo acima aceita dois modos diferentes de parâmetros (
IN
e OUT
). IN
é o padrão, então é por isso que o exemplo anterior não incluiu o modo. Aqui, também definimos uma variável. Usamos
DECLARE stockNumber SMALLINT
para declarar uma variável chamada stockNumber
com um tipo de SMALLINT
(pequeno inteiro). Usamos um
SELECT
para procurar o inventário para o ID de fruta fornecido e atribuí-lo ao nosso stockNumber
variável. Finalmente, usamos um SQL
IF
instrução para determinar o nível de estoque, colocando esse valor no pStockLevel
parâmetro (que obviamente é o OUT
parâmetro — este é o valor que veremos quando chamarmos o procedimento armazenado). Chamando um procedimento armazenado com um OUT
ou INOUT
Parâmetro
Em nosso último exemplo, especificamos dois parâmetros, um
IN
parâmetro e um OUT
parâmetro. Quando chamamos esse procedimento armazenado, ainda precisamos incluir o
OUT
parâmetro. No entanto, como não saberemos seu valor (afinal, é por isso que o chamamos — para descobrir seu valor!), precisaremos usar uma variável. Então podemos usar um SELECT
declaração para descobrir o seu valor. Assim:
CALL spCheckFruitStockLevel(1, @stockLevel); select @stockLevel;
Resultado:
Modos de parâmetro
Acabamos de usar dois modos de parâmetro (
IN
e OUT
). No MySQL, existem três modos de parâmetro que podem ser usados com procedimentos armazenados. - EM
- Ao usar esse modo de parâmetro, você (ou seu aplicativo) deve passar o valor do parâmetro ao chamar o procedimento armazenado. Esses parâmetros são protegidos. Portanto, seu valor original é retido após a execução do procedimento armazenado. Se o procedimento armazenado alterar o valor, ele o fará apenas em uma cópia do parâmetro.
Este modo é o modo padrão. Se você não fornecer o modo de parâmetro, ele seráIN
.
- SAÍDA
- O valor de um
OUT
O parâmetro pode ser alterado no procedimento armazenado e seu valor é retornado ao aplicativo de chamada. - INOUT
- Este modo é uma combinação do
IN
eOUT
modos. Você pode passar o valor inicial, o procedimento armazenado pode alterá-lo e retornará o novo valor ao aplicativo de chamada.