Resumo : neste tutorial, você aprenderá como chamar um procedimento armazenado a partir de um gatilho no MySQL.
MySQL permite que você chame um procedimento armazenado a partir de um gatilho usando a CALL
instrução. Ao fazer isso, você pode reutilizar o mesmo procedimento armazenado em vários gatilhos.
No entanto, o gatilho não pode chamar um procedimento armazenado que tenha parâmetros OUT
ou INOUT
ou um procedimento armazenado que use SQL dinâmico.
Vamos dar uma olhada no exemplo a seguir.
Configurando uma tabela de exemplo
Primeiro, crie uma nova tabela chamada accounts
:
DROP TABLE IF EXISTS accounts;
CREATE TABLE accounts (
accountId INT AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
amount DECIMAL(10 , 2 ) NOT NULL ,
PRIMARY KEY (accountId),
CHECK(amount >= 0)
);
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Segundo, insira duas linhas na accounts
tabela:
INSERT INTO accounts(name, amount)
VALUES
('John Doe', 1000),
('Jane Bush', 500);
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Terceiro, consulte os dados da accounts
tabela.
SELECT * FROM accounts;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Crie um procedimento armazenado que retire de uma conta
Este extrato cria um procedimento armazenado que retira uma quantia em dinheiro de uma conta:
DELIMITER $$
CREATE PROCEDURE Withdraw(
fromAccountId INT,
withdrawAmount DEC(10,2)
)
BEGIN
IF withdrawAmount <= 0 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'The withdrawal amount must be greater than zero';
END IF;
UPDATE accounts
SET amount = amount - withdrawAmount
WHERE accountId = fromAccountId;
END$$
DELIMITER ;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Neste procedimento armazenado, se o valor da retirada for menor ou igual a zero, ocorrerá um erro. Caso contrário, atualiza o valor da conta.
Crie um procedimento armazenado que verifique a retirada
A instrução a seguir cria um procedimento armazenado que verifica a retirada de uma conta:
DELIMITER $$
CREATE PROCEDURE CheckWithdrawal(
fromAccountId INT,
withdrawAmount DEC(10,2)
)
BEGIN
DECLARE balance DEC(10,2);
DECLARE withdrawableAmount DEC(10,2);
DECLARE message VARCHAR(255);
-- get current balance of the account
SELECT amount
INTO balance
FROM accounts
WHERE accountId = fromAccountId;
-- Set minimum balance
SET withdrawableAmount = balance - 25;
IF withdrawAmount > withdrawableAmount THEN
SET message = CONCAT('Insufficient amount, the maximum withdrawable is ', withdrawableAmount);
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = message;
END IF;
END$$
DELIMITER ;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Neste procedimento armazenado:
- Primeiro, obtenha o saldo atual da conta.
- Em segundo lugar, defina o valor sacável. O saldo mínimo da conta deve ser 25.
- Terceiro, gere um erro se o valor retirado for maior que o valor sacável.
Crie um gatilho que chame um procedimento armazenado
A instrução a seguir cria um BEFORE UPDATE
gatilho que chama o procedimento armazenado CheckWithdrawal
:
DELIMITER $$
CREATE TRIGGER before_accounts_update
BEFORE UPDATE
ON accounts FOR EACH ROW
BEGIN
CALL CheckWithdrawal (
OLD.accountId,
OLD.amount - NEW.amount
);
END$$
DELIMITER ;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Testando as transações
Primeiro, retire 400 do ID da conta 1:
CALL withdraw(1, 400);
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Funcionou.
Segundo, consulte os dados da accounts
tabela:
SELECT * FROM accounts
WHERE accountId = 1;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
O saldo atual da conta id 1 é 600.
Terceiro, retire 600 do ID da conta 1:
CALL withdraw(1, 600);
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
O procedimento armazenado Withdraw
executa uma UPDATE
instrução que invoca automaticamente o gatilho before_accounts_update
.
O before_account_update
gatilho então chama o procedimento armazenado CheckWithdrawal
para verificar a retirada. Emite um erro porque o valor do saque faz com que o saldo mínimo seja zero, que é menor que 25.
Error Code: 1644. Insufficient amount, the maximum withdrawable is 575.00
Linguagem de código: JavaScript ( javascript )
Quarto, retire 575 do ID da conta 1:
CALL withdraw(1, 575);
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Por fim, verifique o saque consultando os dados da tabela de contas:
SELECT *
FROM accounts
WHERE accountId = 1;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Neste tutorial, você aprendeu como chamar um procedimento armazenado a partir de um gatilho no MySQL.