Usuário com melhor resposta
Trigger Before insert

Pergunta
-
O que tem de errado com minha trigger?
Quero que assim que for inserido um registro na tabela tbAlertas uma trigger seja acionada e o campo data assuma a data atual.
CREATE TRIGGER trbiAlertas
ON tbAlertas
Before insert
AS
BEGIN
new.DATCADALERT = getDate()
END
GO
Respostas
-
Como a trigger é do tipo INSTED OF (BEFORE) ela é executada antes de se inserir o dado, que pode ser modificado.
Se você procurar "INSTEAD OF INSERT Triggers" no Books Online
INSTEAD OF INSERT triggers can be defined on a view or table to replace the standard action of the INSERT statement. Usually, the INSTEAD OF INSERT trigger is defined on a view to insert data into one or more base tables.
Tente o script que te passe e veja que funcionará
Todas as Respostas
-
CREATE TRIGGER trbiAlertas
ON tbAlertas
Before insert
AS
BEGIN
INSERT INTO TABELA (CAMPO1, CAMPO2, CAMPO3, CAMPO4)
SELECT CAMPO1, CAMPO2, CAMPO3, GETDATE() FROM INSERTED
END
GO- Sugerido como Resposta Bruno Belchior sexta-feira, 10 de maio de 2013 17:07
-
Acho que preciso rever os meus conhecimentos de SQL Server: TEM CERTEZA que existe Trigger do tipo BEFORE nas novas versões do SQL Server?
Eu conheço e tem documentado apenas AFTER (default) e INSTEAD OF (que simula um Before).Sobre o problema inicial, se a necessidade for apenas inserir uma data atual em uma coluna, sugiro que utilize um DEFAULT ( getdate() ) nessa coluna, é bem mais simples e não terá o custo de uma trigger para fazer isso.
-
Ola Alex, acho que existe sim o Before no SQL Server, sobre a trigger, queria não só para o campo Data, como para outros campos também.
Minha dúvida é: Como antes de inserir um registro no banco eu pegue um campo do registro que está sendo inserido, fasso um calculo com esse campo e ao invés de inserir o valor informado pelo usuário a trigger insira o valor calculado por ela. -
Segue exemplo,
Assim como a data é só vc alterar os campos da INSERTED
Essa tabela especial é criada especialmente para TRIGGERS e contem os dados que vc inseriria na tabela e que vc pode trabalhar os dados antes de inserir
OBS: A tabela inserted tem o mesmo formato da tabela na qual vc criou a trigger
CREATE TRIGGER trbiAlertas
ON tbAlertas
INSTEAD OF
AS
BEGIN
INSERT INTO tbAlertas (CAMPO1, CAMPO2, CAMPO3, CAMPO4)
SELECT CAMPO1, CAMPO2, (CAMPO3+123456), GETDATE() FROM INSERTED
END
GO
ESPERO TER AJUDADO
-
Sergio, me desculpe, mas acho que não estou entendendo.
Nesse seu código ele irá criar um loop infinito não?
Sempre antes de inserir um novo registro no banco a trigger irá ser acionada, e dentro destra trigger contém outro insert para a mesma tabela, criando assim um loop.
Acho que não me expressei direito, ou eu que não estou entendendo mesmo rsrs.
A situação é a seguinte.
Insert into tbExemplo (campo1, campo2, campo3) values ('Valor1','Valor2',Valor3')
Neste momento é chamada a trigger, antes que seja inserido o registro no banco.
Meu objetivo é alterar o valor do campo2 para 'ValorAlterado'.
+ ou - algo parecido com a trigger abaixo
CREATE TRIGGER trbiAlertas
ON tbAlertas
INSTEAD OF
AS
BEGIN
New.campo2 = 'ValorAlterado.
END
GO
O fato é que não entendi o motivo do select e do insert dentro de sua trigger, ja que meu objetivo é só alterar um campo da tabela em que o registro foi inserido
O erro está dando porque não está encontrando o comando New. -
Como a trigger é do tipo INSTED OF (BEFORE) ela é executada antes de se inserir o dado, que pode ser modificado.
Se você procurar "INSTEAD OF INSERT Triggers" no Books Online
INSTEAD OF INSERT triggers can be defined on a view or table to replace the standard action of the INSERT statement. Usually, the INSTEAD OF INSERT trigger is defined on a view to insert data into one or more base tables.
Tente o script que te passe e veja que funcionará -
Olá Riderman,
Apesar de vc ter marcado a resposta como "respondida", ainda falta alguns esclarecimentos de conceitos caso vc ainda não saiba:
a) O primeiro comentário que fiz, foi para mostrar que o script passado estava errado. Não existe o parametro BEFORE para triggers.
b) Sobre a dica do DEFAULT(), se a data é passada no comando INSERT o DEFAULT realmente não funcionará no seu caso.
c) O SQL Server NÃO POSSUI trigger do tipo BEFORE, as triggers do tipo INSTEAD OF (traduzindo: AO INVÉS) fazem a execução do comando enviado (INSERT, UPDATE ou DELETE) mas não efetivam a execução do comando, ou seja se você não repetir o comando ou fazer outra operação dentro da trigger, nada será gravado no banco de dados.
-
-
Riderman,
Ignorar não é a palavra mais correta, pois o comando será executado e com isso criará a tabela INSERTED mas no final esse comando não será efetivado (commit) na tabela em questão.
Para que os dados sejam efetivados na tabela ou tabelas, você codifica a trigger para fazer o que você precisa. Podendo trocar dados, como foi o último exemplo que o Sergio enviou: troncando o valor de uma coluna pela função GETDATE.
INSTEAD OF triggers é normalmente usado, mais de 90% do uso, com VIEWS. Como está descrito no Books Online.
O último exemplo que foi passado resolve o seu caso.
-
CREATE TRIGGER trbiAlertas
ON tbAlertas
INSTEAD OF Insert
AS
BEGINDECLARE @DATCADALERT date
DECLARE OneChange CURSOR LOCAL READ_ONLY FORWARD_ONLY STATIC
FOR SELECT [DATCADALERT] FROM inserted
OPEN OneChange
FETCH NEXT FROM OneChange INTO @DATCADALERT
WHILE (@@FETCH_STATUS=0)
BEGINIF(@DATCADALER IS NULL)
SELECT @DATCADALER = getdate();END IFFETCH NEXT FROM OneChange INTO @DATCADALERTENDEND
TA UMA OLHADA NISSO AI CARA TESTA E VE SE ROLA -
Cara, eu acho que entendi o que você queria fazer pois estava com um problema parecido. vou postar o codigo que usei para resolve-lo.
CREATE TRIGGER tr_up_NmTabela on NmTable
AFTER UPDATE AS
BEGIN-- repare que sempre apos a ateração da minha tabela...
-- se o status do registro que acabou de ser incluido for 5 eu vou retornar a data atual, se não eu retorno null.
UPDATE NmTabela SET NmTabela.DtFinalizacao = (SELECT CASE WHEN (inserted.IdStatus = 5)
THEN GETDATE()
ELSE NULL
END)
FROM DemandaINNER JOIN inserted ON inserted.Id = NmTabela.Id
-- ATENÇÃO: eu tive que fazer um inner join com a tabela INSERTED que tem os dados da minha ultima alteração para eu poder comparar se o idstatus -- era o numero 5END
-
-
-
Paulo,
Isso não é POG. A norma ISO-IEC 9075 dá liberdade para cada fornecedor implementar ou não certas funcionalidades. A avaliação da Microsoft é que a trigger de INSTEAD OF é suficiente para o SQL Server neste momento.
Se no futuro eles implementarão? Não sei.
Se será legal? Eu considero que sim, mas sinceramente, eu já trabalho com SQL server e Oracle há algum tempo e nunca precisei de uma trigger de BEFORE.
IMHO é que trigger de BEFORE serve mais pra consertar POG de desenvolvedor do que tem uma utilidade imprescindível no SQL Server.
Roberto Fonseca MCT / MCITP - Database Administrator 2008 MCITP - Database Developer 2008 MCITP - Business Intelligence 2008