Gostaria de fazer uma trigger no SQL Server como eu fazia no firebird.

20/07/2010


  Sem trabalhei com o firebird e gosto de manter em minhas tabelas a data e a hora da ultima alteração (insert ou update) para cada registro. Para isto criava uma coluna do tipo datetime para este fim e criava uma trigger da seguinte forma:
CREATE TRIGGER minha_tabela_biu FOR minha_tabelaACTIVE BEFORE INSERT OR UPDATE POSITION 0ASbegin  NEW.ULTIMA_ALTERACAO = CURRENT_DATE + CURRENT_TIME;end

No firebird, muito fácil: através da função NEW pego os dados antes de um INSERT ou UPDATE, coloco o valor que eu quero e assim consigo meu propósito.
Agora, estou migrando para o SQL SERVER 2008 e estou tendo muitas dificuldades. Alguém poderia me ajudar como eu faço a mesma coisa no banco de dados da microsoft?
Desde já agradeço.

Respostas

20/07/2010

Eriley Barbosa

CREATE TRIGGER minha_tabela_biu FOR minha_tabela ACTIVE BEFORE INSERT OR UPDATE POSITION 0 AS begin   NEW.ULTIMA_ALTERACAO = CURRENT_DATE + CURRENT_TIME; end   USE SuaBasedeDados IF EXISTS (SELECT name FROM sysobjects WHERE name = 'minha_tabela_biu' AND type = 'TR') DROP TRIGGER minha_tabela_biu GO CREATE TRIGGER minha_tabela_biu ON minha_tabela FOR INSERT, UPDATE ULTIMA_ALTERACAO = GETDATE() GOAtenciosamenteEriley 
Responder Citar

20/07/2010

Eriley Barbosa

USE SuaBasedeDados
IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'minha_tabela_biu' AND type = 'TR')
   DROP TRIGGER minha_tabela_biu
GO
CREATE TRIGGER minha_tabela_biu
ON minha_tabela
INSTEAD OF INSERT, UPDATE AS BEGIN   ULTIMA_ALTERACAO = GETDATE() END GO Tinha me esquecido de que você queria before insert, update e isto é feito no sqlserver pelo comando instead of.   Atenciosamente   Eriley
Responder Citar

20/07/2010

Bruno

Ele não tá reconhecendo a chamada direta à minha coluna
ULTIMA_ALTERACAO = GETDATE()
ULTIMA_ALTERAÇÃO: Sintaxe incorreta.
Responder Citar

20/07/2010

Eriley Barbosa

Parece que não reconheceu o seu campo, tente:   NomedaSuaTabela.ULTIMA_ALTERACAO = GETDATE()   Atenciosamente   Eriley
Responder Citar

20/07/2010

Emerson

o Firebird cria as tabelas temporárias "New"e "Old".

O SQL Server criar UPDATED, INSERTED, DELETED. essas tabelas podem conter mais de um registro. para que você possa manipular corretamente essas registros, crie um cursor para a tabela UPDATED e varra todos os registros.

Responder Citar

20/07/2010

Bruno

Parece que finalmente com a ajuda de vocês consegui entender.
O SQL SERVER não possui a função/cláusula BEFORE. Porem para realizar algo similar ele possui o INSTEAD OF que traduzindo quer dizer (ao invés de).
Neste caso, quando utilizamos o INSTEAD OF, o SQL SERVER executa os INSERTS, DELETES E UPDATES, porém não commita. Então devemos dizer a ele o que fazer. E para termos acesso aos dados inseridos/editados/deletados pelo usuário, utilizamos as tabelas citadas pelo Emerson. Achei um exemplo prático na net:
CREATE TRIGGER trbiAlertas
   ON tbAlertas
INSTEAD OF Insert
AS
BEGIN
DECLARE @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)
BEGIN
IF(@DATCADALER IS NULL)
SELECT @DATCADALER = getdate();
END IF
FETCH NEXT FROM OneChange INTO @DATCADALERT
END
END

Conclusão: Como avaliei que é muito código para pouca coisa, não compensa eu fazer dezenas de triggers para minha aplicação para uma coisa tão banal, ainda mais por se tratar de triggers. Vou preferir criar procedures de INSERT e UPDATE para meu banco de dados e chamá-las na minha aplicação. Assim, tenho a opção de setar meu campo data como Default = getdate() e passar parâmetro null nas minhas procedures de insert/delete.
Tudo bem que passei minha regra de negócio para a aplicação mais no meu caso não vai ser tão impactante.
Agradeço a atenção de todos.
Responder Citar