Preciso escrever um Insert, Update Trigger na tabela A, que excluirá todas as linhas da tabela B, cuja coluna (digamos Desc) possui valores como o valor inserido / atualizado na coluna da tabela A (digamos Col1). Como eu iria escrevê-lo para que eu possa lidar com os casos Update e Insert. Como eu determinaria se o gatilho é executado para uma atualização ou inserção.
fonte
fonte
Muitas dessas sugestões não são levadas em consideração se você executar uma instrução de exclusão que não exclui nada.
Digamos que você tente excluir onde um ID é igual a algum valor que não existe na tabela.
Seu gatilho ainda é chamado, mas não há nada nas tabelas Excluídas ou Inseridas.
Use isto para ser seguro:
Agradecimentos especiais a @KenDog e @Net_Prog por suas respostas.
Eu construí isso a partir de seus scripts.
fonte
Estou usando o seguinte, ele também detecta corretamente instruções de exclusão que não excluem nada:
fonte
Após muita pesquisa, não consegui encontrar um exemplo exato de um único gatilho do SQL Server que lida com todas as três condições das ações de gatilho INSERT, UPDATE e DELETE. Finalmente encontrei uma linha de texto que falava sobre o fato de que, quando um DELETE ou UPDATE ocorre, a tabela DELETED comum conterá um registro para essas duas ações. Com base nessas informações, criei uma pequena rotina de ação que determina por que o gatilho foi ativado. Às vezes, esse tipo de interface é necessário quando há uma configuração comum e uma ação específica a ocorrer em um acionador INSERT vs. UPDATE. Nesses casos, criar um gatilho separado para o UPDATE e o INSERT se tornaria um problema de manutenção. (ou seja, os dois gatilhos foram atualizados corretamente para a correção necessária do algoritmo de dados comuns?)
Para esse fim, gostaria de fornecer o seguinte snippet de código de evento com vários gatilhos para manipular INSERT, UPDATE, DELETE em um gatilho para um Microsoft SQL Server.
fonte
Creio aninhado ifs um pouco confuso e:
;)
fonte
fonte
Tente isso ..
fonte
Embora eu também goste da resposta postada por @Alex, ofereço essa variação à solução de @ Graham acima
isso usa exclusivamente a existência de registro nas tabelas INSERTED e UPDATED, em vez de usar COLUMNS_UPDATED no primeiro teste. Ele também fornece alívio paranóico ao programador, sabendo que o caso final foi considerado ...
você receberá NOOP com uma declaração como a seguinte:
fonte
END
é recuado incorretamente! (causando a questão, onde a primeiraBEGIN
está fechado)Esta pode ser uma maneira mais rápida:
fonte
Um possível problema com as duas soluções oferecidas é que, dependendo de como elas são gravadas, uma consulta de atualização pode atualizar zero registros e uma consulta de inserção pode inserir zero registros. Nesses casos, os conjuntos de registros inseridos e excluídos estarão vazios. Em muitos casos, se os conjuntos de registros Inserido e Excluído estiverem vazios, convém sair do gatilho sem fazer nada.
fonte
Eu encontrei um pequeno erro na solução Grahams caso contrário legal:
Deve ser IF COLUMNS_UPDATED () < > 0 - inserir ou atualizar em
vez de> 0 provavelmente porque o bit superior é interpretado como bit de sinal inteiro ASSINADO ... (?). Então, no total:
fonte
Isso faz o truque para mim:
Como nem todas as colunas podem ser atualizadas ao mesmo tempo, você pode verificar se uma coluna específica está sendo atualizada por algo assim:
fonte
fonte
Gosto de soluções que são "elegantes em ciência da computação". Minha solução aqui atinge as pseudotables [inseridas] e [excluídas] uma vez para obter seus status e coloca o resultado em uma variável mapeada em bits. Em seguida, cada combinação possível de INSERT, UPDATE e DELETE pode ser prontamente testada em todo o gatilho com avaliações binárias eficientes (exceto para a improvável combinação INSERT ou DELETE).
Supõe-se que não importa qual era a instrução DML se nenhuma linha foi modificada (o que deve satisfazer a grande maioria dos casos). Portanto, embora não seja tão completa quanto a solução de Roman Pekar, é mais eficiente.
Com essa abordagem, temos a possibilidade de um gatilho "FOR INSERT, UPDATE, DELETE" por tabela, fornecendo A) controle completo sobre a ordem das ações eb) implementação de código por ação aplicável a várias ações. (Obviamente, todo modelo de implementação tem seus prós e contras; você precisará avaliar seus sistemas individualmente quanto ao que realmente funciona melhor.)
Observe que as instruções "existe (selecione * de« inserido / excluído »)" são muito eficientes, pois não há acesso ao disco ( https://social.msdn.microsoft.com/Forums/en-US/01744422-23fe-42f6 -9ab0-a255cdf2904a ).
fonte
Solução rápida MySQL
A propósito: estou usando o MySQL PDO.
(1) Em uma tabela de incremento automático, obtenha o valor mais alto (nome da minha coluna = id) da coluna incrementada uma vez que cada script seja executado primeiro:
(2) Execute a consulta MySQL como faria normalmente e converta o resultado para inteiro, por exemplo:
(3) Após a consulta "INSERT INTO ... ON DUPLICATE KEY UPDATE", obtenha o último ID inserido da sua maneira preferida, por exemplo:
(4) Compare e reaja: se o lastInsertId for maior que o mais alto da tabela, provavelmente é um INSERT, certo? E vice versa.
Eu sei que é rápido e talvez sujo. E é um post antigo. Mas, ei, eu estava procurando uma solução há muito tempo, e talvez alguém ache o meu caminho um pouco útil de qualquer maneira. Muito bem sucedida!
fonte
apenas maneira simples
fonte
No primeiro cenário, eu supunha que sua tabela tivesse a coluna IDENTITY
No segundo cenário, não é necessário usar a coluna IDENTITTY
fonte
SE sua atualização
se a sua inserção
fonte
Eu usei essas
exists (select * from inserted/deleted)
consultas por um longo tempo, mas ainda não é suficiente para operações CRUD vazias (quando não há registrosinserted
edeleted
tabelas). Então, depois de pesquisar um pouco sobre este tópico, encontrei uma solução mais precisa:Também é possível usar
columns_updated() & power(2, column_id - 1) > 0
para ver se a coluna está atualizada, mas não é seguro para tabelas com grande número de colunas. Usei uma maneira um pouco complexa de calcular (consulte o artigo útil abaixo).Além disso, essa abordagem ainda classifica incorretamente algumas atualizações como inserções (se todas as colunas da tabela forem afetadas pela atualização) e provavelmente classificará as inserções em que apenas os valores padrão são inseridos como exclusões, mas essas são as operações raras (em locação no meu sistema eles são). Além disso, não sei como melhorar essa solução no momento.
fonte
fonte
Eu faço isso:
1 -> inserir
2 -> excluir
3 -> atualização
fonte
fonte