Às vezes, para refatoração, uso uma View para abstrair as alterações e uso INSTEAD OF
Triggers para imitar a funcionalidade anterior.
Eu encontrei o erro 414 (ou 415) no passado
UPDATE não é permitido porque a instrução atualiza a exibição "%.*ls" que participa de uma junção e tem um gatilho INSTEAD OF UPDATE.
Eu posso reescrever o UPDATE FROM
para uma MERGE
declaração e isso funciona. Mas por que?
Encontrei essas referências, mas nenhuma delas responde o porquê.
https://sqlserverfast.com/blog/hugo/2008/03/lets-deprecate-update-from/
Meu entendimento é que isso não é permitido porque
UPDATE...FROM
tem alguns comportamentos peculiares que são mantidos devido à compatibilidade com versões anteriores. Fazer com que eles funcionem da mesma forma quando a exibição tem gatilhos em vez de seria difícil, talvez impossível.MERGE
tem várias fraquezas, mas tem uma semântica de atualização bem definida e sã.O principal exemplo disso é
MERGE
evitar atualizações ambíguas — onde uma linha de destino é alterada logicamente mais de uma vez pela especificação SQL. Se nada no esquema garantir absolutamente que uma linha de destino não possa ser modificada mais de uma vez, umMERGE
plano apresentará operadores para verificar essa condição em tempo de execução e gerar um erro se for encontrado.Isso torna a implementação da tabela unida
MERGE
em um destino com gatilhos em vez de mais fácil/possível.A
UPDATE...FROM
sintaxe também tem comportamentos de ligação curiosos (novamente mantidos para evitar quebra de código antigo) quando a tabela de destino é referenciada mais de uma vez, às vezes por alias e às vezes não.Não está diretamente relacionado à sua pergunta, mas há um exemplo de caso extremo com CTEs descritos na documentação :
Tudo isso dito, só porque funciona
MERGE
não significa que não haja bugs à espreita. Para um exemplo semi-relacionado veja MERGE into a view com INSTEAD OF triggers .Pressionar com força as bordas das combinações de recursos complexos é uma ótima maneira de encontrar bugs de casos extremos.