SQLShack

Gatilhos SQL são outro poderoso objecto de base de dados que temos à nossa disposição. Em artigos anteriores, cobrimos funções definidas pelo utilizador, procedimentos definidos pelo utilizador, e visualizações SQL. Hoje vamos falar sobre gatilhos SQL e como utilizá-los para alcançar o comportamento desejado.

O Modelo

Antes de passarmos ao tópico deste artigo, vamos dar uma rápida olhada ao modelo que estamos a utilizar neste artigo mas também ao longo de toda esta série.

AcionadoresSQL - o modelo de dados que utilizaremos no artigo'll use in the article

Neste artigo, centrar-nos-emos nos accionadores DML (linguagem de manipulação de dados) e mostraremos como funcionam quando fazemos alterações numa única tabela.

O que são accionadores SQL?

No SQL Server, os gatilhos são objectos da base de dados, na verdade, um tipo especial de procedimento armazenado, que “reage” a certas acções que fazemos na base de dados. A ideia principal por detrás dos gatilhos é que eles executam sempre uma acção no caso de algum evento acontecer. Se estamos a falar de gatilhos de DML, estas alterações serão alterações nos nossos dados. Vamos examinar algumas situações interessantes:

  • No caso de efectuar uma inserção na tabela de chamadas, pretende actualizar que o cliente relacionado tem mais 1 chamada (nesse caso, devemos ter atributo inteiro na tabela de clientes)
  • Quando completar uma chamada (actualizar chamada.valor do atributo end_time) pretende aumentar o contador de chamadas efectuadas por esse funcionário durante esse dia (mais uma vez, devemos ter esse atributo na tabela de funcionários)
  • Quando tenta apagar um funcionário, pretende verificar se este tem chamadas relacionadas. Se assim for, evitará que apague e levantará uma excepção personalizada

A partir de exemplos, pode reparar que os gatilhos DML são acções relacionadas com os comandos SQL definidos nestes gatilhos. Uma vez que são semelhantes aos procedimentos armazenados, é possível testar valores usando a instrução IF, etc. Isto proporciona muita flexibilidade.

A boa razão para usar os gatilhos SQL DML é o caso quando se pretende assegurar que um determinado controlo deve ser efectuado antes ou depois da instrução definida na tabela definida. Este pode ser o caso quando o seu código está em todo o lado, por exemplo, a base de dados é utilizada por diferentes aplicações, o código é escrito directamente nas aplicações e não está bem documentado.

Tipos de gatilhos SQL

No SQL Server, temos 3 grupos de gatilhos:

  • gatilhos DML (linguagem de manipulação de dados) – Já os mencionámos, e eles reagem aos comandos DML. Estes são – INSERT, UPDATE, e DELETE
  • DDL (linguagem de definição de dados) triggers – Como esperado, triggers deste tipo devem reagir a comandos DDL como – CREATE, ALTER, e DROP
  • Logon triggers – O nome diz tudo. Este tipo reage a eventos LOGON

Neste artigo, vamos focar-nos nos gatilhos DML, porque são mais comummente utilizados. Cobriremos os dois tipos de gatilhos restantes nos próximos artigos desta série.

Gatilhos DML – Sintaxe

A sintaxe SQL simplificada para definir o gatilho é a seguinte.

CREATE TRIGGER trigger_name
ON table_name
{FOR | DEPOIS | INSTEAD OF} { } { }
AS
{sql_statements}

1
2
3
4
5

A maior parte da sintaxe deve ser auto-explicativa. A ideia principal é definir:

  • Um conjunto de {sql_statements} que deve ser executado quando o gatilho é disparado (definido pelos restantes parâmetros)
  • Temos de definir quando o gatilho é disparado. É o que faz a parte {FOR | DEPOIS | INSTEAD OF}. Se o nosso disparo for definido como PARA | DEPOIS | INSTEAD OF trigger do que as instruções SQL no disparo devem ser executadas depois de todas as acções que dispararam este disparo serem lançadas com sucesso. O INSTEAD OF trigger deverá executar controlos e substituir a acção original pela acção no trigger, enquanto que o FOR | AFTER (significam o mesmo) trigger deverá executar comandos adicionais após a declaração original ter completado
  • A parte { } denota qual o comando que efectivamente dispara este trigger. Devemos especificar pelo menos uma opção, mas podemos usar várias se precisarmos dela

Com isto em mente, podemos facilmente escrever os gatilhos que o farão:

  • Verificar (antes de inserir) se todos os parâmetros da instrução INSERT estão OK, adicionar alguns se necessário, e executar o insert
  • Após inserir, executar tarefas adicionais, como actualizar um valor noutra tabela
  • Antes de apagar, verificar se existem registos relacionados
  • Actualizar certos valores (e.g. ficheiro de registo) após a eliminação

Se quiser largar um gatilho, irá utilizar:

1
DROP TRIGGER trigger_name;

SQL INSERT Trigger – Exemplo

Primeiro, vamos criar um gatilho SQL simples que deverá efectuar uma verificação antes da declaração INSERT.

>

DROP TRIGGER IF EXISTS t_country_insert;
GO
CRIAR TRIGGER t_país_inserir no país INSTEAD OF INSERT
COMO COMEÇA
DECLARE @country_name CHAR(128);
DECLARE @country_name_eng CHAR(128);
DECLARE @country_code CHAR(8);
SELECT @country_name = nome_do_país, @country_name_eng = nome_do_país, @country_code = código_do_país DE INSERTED;
IF @country_name IS NULL SET @country_name = @country_name_eng;
IF @country_name_eng IS NULL SET @country_name_eng = @country_name_name;
INSERIR EM PAÍS (nome_país, nome_país_em_eng, código_país) VALORES (@nome_país, @nome_país_em_eng, @código_país);
FIM;

1
2
3
4
5
6
7
8
9
10
11
12

Podemos ver o nosso gatilho no Explorador de Objectos, quando expandimos os dados para a tabela relacionada (país).

object explore triggers

object explore triggers

Quero enfatizar algumas coisas aqui:

  • A instrução INSERT dispara esta consulta e é efectivamente substituída (INSTEAD OF INSERT) pela instrução neste gatilho
  • Definimos um número de variáveis locais para armazenar valores do registo de inserção original (INSERTED). Este registo é específico para triggers e permite aceder a este único registo e aos seus valores
  • Note: O registo INSERTED pode ser utilizado nos triggers de inserção e actualização SQL.
  • Com instruções IF, testamos valores e valores SET se não foram definidos antes
  • No final da consulta, executamos a instrução INSERT (a que substitui a original que disparou este disparo)

Vamos agora executar um comando INSERT INTO e ver o que acontece na base de dados. Vamos executar as seguintes afirmações:

SELECT * FROM country;
INSERT INTO país (country_name_eng, country_code) VALORES (‘Reino Unido’, ‘UK’);
SELECT * FROM país;

1
2
3

O resultado está na figura abaixo.

o resultado da declaração de inserção

Pode-se facilmente notar que a linha com id = 10, tinha sido inserida. Não especificámos o nome_país, mas o gatilho fez o seu’ trabalho e preencheu esse valor com country_name_eng.

  • Note: Se o gatilho estiver definido numa determinada tabela, para uma determinada acção, deverá sempre ser executado quando essa acção for executada.

SQL DELETE Trigger – Exemplo

Agora vamos criar um gatilho que deve disparar sobre a declaração DELETE na tabela de países.

1
2
3
4
5
6
7
8
9
10
11
12
13

/div>/td>

TRIGGERADOR DE Gotas SE EXISTE t_país_delete;
GO
CREATE TRIGGER t_country_delete ON country INSTEAD OF DELETE
AS BEGINES
DECLARE @id INT;
DECLARE @count INT;
SELECT @id = id DE APAGADO;
SELECT @count = COUNT(*) DE cidade ONDE país_id = @id;
SE @count = 0
DELETE DE país ONDE id = @id;
ELSE
THROW 51000, ‘can not delete – country is referenced in other tables’, 1;
END;

Para este gatilho, vale a pena salientar o seguinte:

  • Uma vez mais, executamos a acção antes (em vez de) executar realmente (INSTEAD OF DELETE)
  • Usamos o registo DELETED. Este registo pode ser utilizado nos triggers relacionados com a instrução DELETE
  • Nota: O registo DELETED pode ser utilizado nos triggers SQL delete e update.
    • Utilizámos a instrução IF para determinar se a linha deve ou não ser apagada. Se assim fosse, executámos a declaração DELETE, e se não deveria, somos atirados e excepção

A execução da declaração abaixo passou sem erro porque o país com id = 6 não tinha registos relacionados.

1
DELETE FROM country WHERE id = 6;

Se executarmos esta declaração, veremos uma mensagem de erro personalizada, como mostra a figura abaixo.

1
DELETE FROM country WHERE id = 1;

a mensagem de erro lançada pelo SQL trigger

a mensagem de erro lançada pelo gatilho SQL

Tal mensagem não é apenas descritiva, mas permite-nos tratar bem este erro e mostrar uma mensagem mais significativa para o utilizador final.

SQL UPDATE Trigger

Deixarei este para si, como prática. Portanto, tente anotar o gatilho UPDATE. O importante que deve saber é que no gatilho de actualização pode usar ambos – registos INSERTED (após actualização) e DELETED (antes da actualização). Em quase todos os casos, terá de usar ambos.

Quando utilizar gatilhos SQL?

Os gatilhos partilham muito em comum com os procedimentos armazenados. Ainda assim, em comparação com os procedimentos armazenados, eles são limitados no que se pode fazer. Portanto, prefiro ter um procedimento armazenado para inserir/actualizar/apagar e fazer aí todas as verificações e acções adicionais.

Ainda assim, essa nem sempre é a opção. Se herdou um sistema ou simplesmente não quer colocar toda a lógica nos procedimentos armazenados, então os desencadeadores podem ser uma solução para muitos problemas que possa ter.

Tabela de conteúdos

Aprender SQL: CRIAR BASE DE DADOS &CRIAR TABELA DE OPERAÇÕES

Aprender SQL: INSERIR NA TABELA

br>>p>Saprender SQL: Chave primária>br>>p>Saprender SQL: Chave Estrangeira>br>>p>Saprender SQL: Declaração SELECT

Saprender SQL: INNER JOIN vs LEFT JOIN

>br>

Saiba SQL: SQL Scripts

>br>>p>Saprender SQL: Tipos de relações>br>>p>Saiba SQL: Juntar várias tabelas

Saprender SQL: Funções agregadas

Saprender SQL: Como Escrever uma Consulta Complexa SELECT?

p>Saprender SQL: A base de dados INFORMAÇÃO_SCHEMA
p>Saiba SQL: Tipos de Dados SQL>br>>p>Saprender SQL: Teoria do Conjunto
p>Saprender SQL: Funções Definidas pelo Utilizador

Saprender SQL: Procedimentos Armazenados Definidos pelo Utilizador

br>>p>Saprender SQL: SQL Views>br>>p>Saprender SQL: Gatilhos SQL>br>>p>Saprender SQL: Prática de Consultas SQL

Saprender SQL: Exemplos de consultas SQL

>br>>p>Saiba SQL: Criar um relatório manualmente usando consultas SQL>br>>p>Saprender SQL: Funções de data e hora do SQL Serverbr>>p>Saprender SQL: Criar relatórios do SQL Server usando funções de data e horabr>>p>Saprender SQL: Tabelas Pivot do SQL Server
p>Saprender SQL: Exportação do SQL Server para Excel
p>Saprender SQL: Introdução aos loops do SQL Serverbr>>p>Saprender SQL: Cursores do Servidor SQLbr>>p>Saprender SQL: SQL Best Practices for Deleting and Updating databr>>p>Saprender SQL: Convenções de Nomeação>br>>p>Saprender SQL: Trabalhos relacionados com SQL>br>>p>Saprender SQL: Non-Equi Adere ao SQL Serverbr>>p>Saprender SQL: SQL Injection>br>

Saiba SQL: SQL dinâmico

    >>li>>Autorli> Posts recentes
Emil Drkusic
Emil é um profissional de bases de dados com mais de 10 anos de experiência em tudo relacionado com bases de dados. Durante os anos, trabalhou na indústria informática e financeira e agora trabalha como freelancer.
Os seus compromissos passados e presentes variam desde a concepção e codificação de bases de dados até ao ensino, consultoria, e escrita sobre bases de dados. Também para não esquecer, BI, criar algoritmos, xadrez, filatelia, 2 cães, 2 gatos, 1 mulher, 1 bebé…
Pode encontrá-lo no LinkedIn
Veja todos os posts de Emil Drkusic

Emil Drkusic
Postes mais recentes de Emil Drkusic (ver todos)
ul>

  • Aprender SQL: SQL dinâmico – 3 de Março de 2021
  • Aprender SQL: SQL Injection – 2 de Novembro de 2020
  • Aprender SQL: Non-Equi Adere ao SQL Server – 29 de Setembro de 2020
  • Deixe uma resposta

    O seu endereço de email não será publicado. Campos obrigatórios marcados com *