Sei sulla pagina 1di 16

Criando TRIGGER em SQL

Apesar de TRIGGERS SQL serem muito teis, no aconselhvel a utili zao deste ti po
de i nstruo, pelo fato de prejudi car a performance. Mesmo assim i rei demonstrar como
criar TRIGGERS.
TRIGGER um ti po de PROCEDURE que executada automati camente aps uma ao
especifica que ocorre em uma tabela ou view (por isso prejudi ca a performance).
Segue abaixo a si ntaxe para criao:
CREATE TRIGGER
nome_da_tri gger
ON { TABLE | VIEW }
{
{ { FOR | AFTER | INSTEAD OF } { [ INSERT ] [ , ] [ UPDATE ] } }
}
nome_da_tri gger: Nome que deseja rotular a TRIGGER;
TABLE | VIEW: Pode-se criar uma TRIGGER a parti r de uma Table ou de uma View;
AFTER: Indi ca que a TRIGGER apenas ser aci onada aps todas as aes terem
finali zadas com sucesso. AFTER padro caso a i nstruo FOR for a nica palavra-chave
especificada na criao da TRIGGER;
INSTEAD OF: Indi ca que a TRIGGER ser executada em vez de ser executada a ao.
possvel uti lizar a i nstruo INSTEAD OF com INSERT, UPDATE e/ou DELETE;
Exemplo:
CREATE TRIGGER
tg_Cli ente_Excluir
ON
Cli ente
INSTEAD OF DELETE
AS
DELETE FROM Cli ente WHERE Cli enteID IN (SELECT Cli enteID FROM deleted)
DELETE FROM Cli enteTelefone WHERE Cli enteID IN (SELECT Cli enteID FROM deleted)
O exemplo acima ir remover todos os telefone(s) do(s) cli ente(s) da tabela
Cli enteTelefone antes de remover todos os cli entes (Cli ente) e esta TRIGGER est
sendo apli cada a tabela Cli ente. Repare que est sendo uti li zado a instruo INSTEAD
OF que em vez exclui r (DELETE) o registro pela ao i r exclui r ao fi nal da TRIGGER.
CREATE TRIGGER
tg_Cli ente_Cadastrar
ON
Cli ente
AFTER INSERT
AS
INSERT INTO
Cli enteLog
SELECT
Cli enteID,
GETDATE(),
INSERT
FROM
Cli ente
O exemplo acima ir i nseri r no log da tabela Cli ente (Cli enteLog ) todos os IDs depois
de ocorrer a execuo do INSERT na tabela Cli ente.
Caso precise alterar a TRIGGER, basta substi tuir a palavra CREATE por ALTER e
adicionar a nova consulta.
Existem diversos parmetros que pode ser passados para uma TRIGGER, mas no vou me
aprofundar muito.
Unir duas tabelas em SQL
O operador UNION permite a combi nao de mais de dois resultados de uma
instruo SQL em um nico resultado de consulta. Os resultados combi nados no
operador UNION devem ter a mesma estrutura, ou seja, a mesma quanti dade e ti pos de
campos devem coi ncidi r em todas as consultas.
Segue abaixo a si ntaxe da uti li zao do operador UNION:
INSTRUCAO_SELECT
UNION [ALL]
INSTRUCAO_SELECT
Para demonstrar como se uti li za o operador UNION, segue abaixo uma instruo de
criao de uma tabela de cli entes referente pessoas fsi cas (Cli enteFisico) e outra
contendo as i nformaes de cli entes referente pessoas jur di cas, com campos
diferentes claro (se no, no haveria a necessidade de criao de uma segunda tabela
de diferenciao).
CREATE TABLE dbo.Cli enteFisico
(
ID bigi nt NOT NULL,
Nome varchar(64) NOT NULL,
RG varchar(16) NOT NULL,
Nascimento datetime NOT NULL
) ON [PRIMARY]
CREATE TABLE dbo.Cli enteJuri dico
(
ID bigi nt NOT NULL,
NomeFantasia varchar(64) NOT NULL,
CNPJ bigi nt NOT NULL,
IE varchar(16) NOT NULL
) ON [PRIMARY]
Aps a criao das tabelas aci ma se pode uni r ambas em um nico resultado de consulta.
SELECT
ID,
Nome
FROM
Cli enteFisi co
UNION
SELECT
ID,
NomeFantasia
FROM
Cli enteJuri dico
A consulta acima ir retornar todos os clientes fsicos e jurdi cos exi stentes nas
respectivas tabelas (Cli enteFisico e Cli enteJuridico)
SELECT
ID,
Nome,
RG
FROM
Cli enteFisi co
UNION
SELECT
ID,
NomeFantasia,
CNPJ
FROM
Cli enteJuri dico
Esta consulta no i r funcionar, ocorrer um erro, porque os tipos no correspondem. O
campo RG do ti po VARCHAR que contm at 16 caracteres enquanto o campo CNPJ do
tipo CHAR que contm 14 caracteres. Este problema fci l de ser resolvi do, basta
converter o resultado de um dos campos para que os dois tenham o mesmo ti po.
SELECT
ID,
Nome,
RG
FROM
Cli enteFisi co
UNION
SELECT
ID,
NomeFantasia,
CONVERT(VARCHAR(16), CNPJ) AS CNPJ
FROM
Cli enteJuri dico
Acima demonstrada a converso feita no campo CNPJ atri bui ndo um alias (codi nome)
ao campo, caso no seja feito, ir mostrar o campo sem nome no ttulo do resultado.
Existe um operador que pode ser uti li zado com o UNION, o ALL. A consulta com o
operador ALL i ndi ca que NO ser eli mi nada nenhuma duplici dade que ocorrer entre as
tabelas, ou seja, mostrar tudo que existir nas tabelas que esto sendo unidas com
resultado. Se omiti r o ALL, como padro, o SQL remove li nhas dos resultados que
dupli caram.
SELECT
ID,
Nome
FROM
Cli enteFisi co
UNION ALL
SELECT
ID,
NomeFantasia
FROM
Cli enteJuri dico
claro que no i r servir para muita coisa o operador ALL na consulta aci ma, porque
no existe nenhum cli ente fsi co que possua o mesmo nome de um cli ente jur dico (pelo
menos que eu conhea).







Criando procedures SQL
Uma manei ra mui to ti l de fazer uma consulta em uma tabela a uti lizao
de PROCEDURES SQL. A criao e uti li zao desta i nstruo so simples, veja abaixo a
sintaxe:
CREATE PROC[EDURE] nome_procedure
[
@parametro tipo_parametro[=valor_padrao]
]
AS
instrucao_SQL [...n]
Irei criar uma PROCEDURE que consulta todos os produtos da tabela Produto ordenando
pelo o valor do produto (Valor) em ordem decrescente.
CREATE PROCEDURE sp_produto_informar
AS
SELECT
Nome,
Descricao,
Valor
FROM
Produto
ORDER BY
Valor
DESC
A i nstruo ORDER BY ordena um determi nado campo, porm prejudica fortemente a
performance do servi dor, portanto evite usar esta i nstruo (que muitas vezes
indispensvel).
Agora adi cionarei um parmetro consulta que ser comparada no campo Nome e o
resultado tambm ser ordenado pelo Valor de forma decrescente.
CREATE PROCEDURE sp_produto_informar
@Nome VARCHAR(64)
AS
SELECT
Nome,
Descricao,
Valor
FROM
Produto
WHERE
Nome LIKE % + @Nome + %
ORDER BY
Valor
DESC
Para executar esta PROCEDURE basta abri r MS SQL Server e executar o segui nte cdigo:
EXECUTE sp_produto_informar Refri
ou
EXEC sp_produto_informar Refri
Esta consulta retornar todos os produtos cujo o nome comece com Refri e orden -los
novamente pelo valor decrescente. Lembrando que SQL no case-sensitive.
A parti r desta si ntaxe podem-se passar quantos parmetros for necessrio para fazer
uma consulta mais precisa e se obter o resultado exato que se deseja. Mui tos
programadores uti li zam a identifi cao daquele registro na tabela, que deve ser nica,
uma chave pri mria.
Uma PROCEDURE pode tambm fazer qualquer outra operao na base, como por
exemplo: inserir, alterar e deletar algum regi stro. A i nstruo abaixo permite i nseri r
algum registro na tabela atravs de uma PROCEDURE, passando os parmetros
necessrios.
CREATE PROCEDURE sp_produto_inserir
@Nome VARCHAR(64),
@Descricao TEXT,
@Valor MONEY
AS
INSERT INTO
Produto(Nome, Descricao, Valor)
VALUES(
@Nome,
@Descricao,
@Valor
)
Os campos da tabela podem ser omi tidos, contanto que os valores estejam na ordem dos
campos.
Abaixo segue um exemplo de uma PROCEDURE que faz a alterao de alguns campos
(Nome, Descricao e Valor):
CREATE PROCEDURE sp_produto_alterar
@ID BIGINT,
@Nome VARCHAR(64),
@Descricao TEXT,
@Valor MONEY
AS
UPDATE
Produto
SET
Nome = @Nome,
Descri cao = @Descri cao,
Valor = @Valor
WHERE
ID = @ID
Como havia dito, a vari vel @I D deve conter o chave pri mria para que a alterao seja
nica e efi ci ente.










Como criar consultas SQL mais rpidas
Estou abordando este assunto aqui no blog, pelo fato de ser um assunto muito
importante atualmente para organizaes que possuem uma grande quanti dade de dados
e mui tos acessos si multaneamente.
Uma consulta mal projetada pode acarretar em lenti do ao servi dor ou at mesmo fazer
com que o servidor permanea fora do ar por um perodo, i mpossibi li tando o usurio de
uti li zar algum servio do sistema ou site, gerando preju zo a organizao.
Otimi zar uma consulta SQL nem sempre uma tarefa fci l e si mples, precisa um pouco
de conhecimento para desenvolver filtros que obtenham resultados que no custe ao
servi dor mui tos recursos de hardware. Mui tos dos exemplos que i rei demonstrar foram
resultados de pesquisas e testes executados no prprio Query Analyser do MS SQL
Server 2000.
Uma forma de prejudicar bastante o desempenho ao acessar a base de dados, a criao
de TRIGGERS. Esta i nstruo acionada sempre que uma determi nada tabela sofre
alguma alterao (INSERT, UPDATE, DELETE). Portanto, ao invs de criar uma
TRIGGER prefi ra criar uma PROCEDURE que ser acionada sempre que uma tarefa for
feita.
Ao criar um simples filtro em uma tabela, pode-se encontrar alguns pontos que
prejudi cam a performance da consulta. A consulta abaixo demonstra um dos exemplos:
SELECT
*
FROM
Cli ente
Ao fazer algum fi ltro em uma tabela, evite i nformar todos os campos de uma tabela em
uma consulta, a menos que isso for realmente necessrio. Muitas das vezes n o ser
uti li zado todos os campos. A consulta acima pode ser executada rapidamente se a tabela
da base de dados conti ver poucos registros, mas para adqui ri r uma melhor performance
da consulta recomendvel fi ltrar apenas os campos que sero uti li zados, o exemplo
abaixo demonstra um cenrio pareci do:
SELECT
Nome,
CPF,
RG,
Endereco
FROM
Cli ente
Outro ponto importante a utili zao da i nstruo COUNT, esta i nstruo i nforma a
quantidade de registros retornados em uma consulta.
SELECT
COUNT(*)
FROM
Cli ente
Porm no h a necessi dade de uti li zao desta consulta, porque ao execut -la, ser
contado um registro de cada vez. Para isto exi ste as tabelas sysobjects e sysindexes.
Com estas duas tabelas possvel obter muitas informaes de diversos todos objetos
existentes na base de dados.
SELECT
sysobjects.name AS [Nome da Tabela],
sysindexes.rowcnt AS [Qtde. de Registros]
FROM
sysobjects
INNER JOIN
sysindexes ON
sysindexes.i d = sysobjects.id
WHERE
sysobjects.name = Cli ente
AND
sysindexes.i ndid = 1
A consulta acima i nforma a quantidade de registros existentes na tabela Cli ente.
Reparem que foi uti li zado uma nova i nstruo, o INNER JOIN. Esta instruo serve para
fazer a juno de duas ou mais tabelas, lembrando que isto significa que DEVE possui r
algum registro na tabela secundria, ou seja na tabela que est recebendo o INNER
JOIN, sendo assim, necessrio fazer a comparao de campos em comum que as duas
possuem. Certifique-se que o nome da tabela escrito na clusula WHERE est correto,
caso contrrio no ser retornado nenhum regi stro. Esta consulta outro exemplo que
poder trazer problemas de performance, porque ao uti li z-la, a consulta toda pode
acessar qualquer uma das informaes (campos) existentes nas tabelas. Uma outra forma
de consultar a quanti dade de registros de uma tabela a segui nte:
SELECT
sysindexes.rowcnt AS [Qtde. de Registros]
FROM
sysindexes
WHERE
sysindexes.i ndid = 1
AND
EXISTS(
SELECT
sysobjects.i d
FROM
sysobjects
WHERE
sysobjects.i d=sysi ndexes.id
AND
sysobjects.name= Cli ente
)
Ao fazer um fi ltro como o aci ma, pode-se obter resultados mui to efi cazes em relao ao
desempenho. A i nstruoEXISTS uma i nstruo extremamente rpi da porque uti li za
pouco recurso de hardware. como se retornasse uma var ivel booleana.
Outra instruo que consome um maior processamento a i nstruo IN, que uti lizada
quando necessrio fazer o fi ltro de um vetor de dados. O exemplo abaixo i nforma os
todos clientes que possuir algum telefone.
SELECT
Nome
FROM
Cli ente
WHERE
ID IN(SELECT ClienteID FROM Telefone)
Outra manei ra de i nformar estes registro seri a uti li zar (novamente) a
instruo EXISTS ao i nvs da i nstruo IN.
SELECT
Cli ente.Nome
FROM
Cli ente
WHERE
EXISTS(
SELECT
Telefone.Cli enteID
FROM
Telefone
WHERE
Telefone.Cli enteID = Cliente.ID
)
So i nmeras as tarefas que se pode fazer para melhorar a performance de uma
consulta. Estas so apenas algumas operaes que devem ser feitas caso necessita de
resultados mais rpi dos em consultas SQL.

Potrebbero piacerti anche