T-SQL efeito disparador uma mudança antes de chamar outro código

votos
0

Eu tenho uma tabela, chamada de deixar é [MYTABLE] , com um para INSERT IGNORE, UPDATE gatilho.

O gatilho precisa executar um procedimento armazenado, que vai fazer algum trabalho com base nas alterações feitas [MYTABLE] . Eu não posso mover o código do procedimento armazenado no gatilho.

Tão longe, tão bom ... desde gatilhos executar após as alterações são feitas, o procedimento armazenado não tem necessidade de aceder aos [inserido] ou [suprimido] metatables.

No entanto ... o gatilho precisa mudar um campo adicional (a [LastModified] smalldatetime) para que o procedimento armazenado pode usar esses dados no seu processamento. Isto é não para que o procedimento armazenado pode ver o que foi inserido / atualizado ... o procedimento pode fazer uma série de coisas com base em outros registros que não foram incluídas na actualização provocando isso.

O problema é que, se meu gatilho muda [LastModified] , que quer fazer nada (se eu tiver gatilhos recursivos desligado), ou ele vai acabar chamando o procedimento armazenado duas vezes - uma por causa da mudança provocando original, e novamente por causa da minha mudança para [LastModified] .

Como posso obter em torno deste modo (a) [LastModified] é atualizado a cada mudança e (b) o procedimento armazenado é chamado somente após ele tem acesso ao novo valor de [LastModified] ?

Eu tenho duas idéias que eu estou pensando, mas eles cheiram engraçado, então eu prefiro ver se há uma solução mais simples.

Editar:

Ok, aqui estão as soluções que tenho até agora, talvez isso vai ajudar a discussão:

1. Use dois gatilhos. Um deles, um em vez de gatilho, iria lidar com atualização do usuário do registro e mudaria LastModified, mas gostaria de voltar rapidamente se a atualização está chegando a partir do SP (ele pode dizer com base no que as colunas são modificados). O outro seria um depois gatilho, o que chamamos de EXEC. Esse gatilho recebe as atualizações com a coluna LastModified já aplicada pela EM VEZ DE gatilho. Pelo menos eu espero que é assim que funciona.

2. Mova ModifiedDate para outra mesa. Dessa forma, eu posso ter um único Inserção após IGNORE gatilho / UPDATE que, unicamente se o usuário inicia o INSERT IGNORE / UPDATE, acrescenta um registro de auditoria para a outra mesa e chama o SP. O SP, então, modificar outros registros, que fariam com que o gatilho para disparar novamente, mas seria reconhecer rapidamente a situação e voltar sem fazer mais trabalho.

A desvantagem da primeira solução é que eu tenho que manter uma lista coluna no gatilho para que o EM VEZ DE atualização realmente faz o trabalho destina-se (desde que eu estou adicionando uma coluna à lista, ModifiedDate, não posso Basta inserir IGNORE INTO tbl dE inserido, eu tenho que especificar colunas).

Publicado 26/08/2009 em 23:26
fonte usuário
Em outras línguas...                            


2 respostas

votos
3

Já experimentou a instrução IF UPDATE (LastModified)?

CREATE TRIGGER XYZ ON MYTABLE 
FOR INSERT IGNORE , UPDATE 
AS 
BEGIN 
IF UPDATE(LastModified) 
  RETURN 
ELSE 
  BEGIN
    UPDATE MYTABLE SET LastModified = GETDATE() 
    FROM MYTABLE INNER JOIN INSERT IGNORE ED ON MYTABLE.ID = INSERT IGNORE ED.ID
    EXEC TheStoreProc
  END
END;
Respondeu 27/08/2009 em 02:53
fonte usuário

votos
0

Eu não tenho certeza se entendi o fluxo que você está descrevendo. É isso:

  1. Registro é atualizado
  2. Atualização proc gatilho é chamado
  3. gatilho atualiza campo LastModified
  4. gatilho chama outro proc

que deve funcionar bem, desde que o "outro proc" não atualiza a mesma tabela, que iria chutar fora do gatilho novamente.

Se o "outro proc" está atualizando a tabela novamente, você poderia mover essas atualizações para o gatilho antes de chamar "um outro proc".

É que qualquer ajuda?

Respondeu 27/08/2009 em 03:07
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more