Como parte de uma MERGE
consulta que desejo executar, gostaria de afirmar em tempo de execução que uma determinada condição é válida. Quando um MERGE
-match é encontrado, gostaria de atualizar uma determinada coluna e executar a seguinte lógica:
- Se a coluna de destino for
NULL
, escreva o valor de origem - Se o destino for
NOT NULL
, afirme que o destino e a origem são idênticos
Espero que os dois valores sejam sempre idênticos no caso 2, mas posso ter cometido um erro (tenho um bug). Quando isso acontecer, gostaria de travar a instrução e deixar meu aplicativo relatar o erro. Esta é uma condição de erro muito rara, não algo que possa acontecer como parte do processamento normal.
Então, eu estava pensando que poderia abusar de uma exceção de divisão por zero para acionar uma falha:
MERGE
...
WHEN MATCHED BY TARGET THEN UPDATE SET
TargetCol = CASE
WHEN TargetCol IS NULL THEN SourceCol
WHEN TargetCol = SourceCol THEN SourceCol
ELSE 0/0 END --crash!
Isso funcionará de forma confiável? Existe uma razão para isso não ser feito?
A resposta para isso depende da força da garantia que você precisa. Houve erros no passado em
CASE
relação à ordem de avaliação, por exemplo , dobrar constantemente uma expressão geradora de erro . Não há bugs atuais no SQL Server 2014 que eu saiba que afetariam sua consulta, mas isso não significa que eles não possam ocorrer no futuro.Isso é um risco com qualquer código, claro, mas minha avaliação é que o risco é maior ao combinar essa técnica com
MERGE
. Merge tem uma implementação complexa e houve muitos bugs relacionados no passado, como você sabe.Pessoalmente, eu procuraria evitar uma divisão por zero como parte da solução. Uma opção melhor pode ser tentar escrever um valor que viole uma
CHECK
restrição explícita (ou alguma outra) na tabela de destino. Isso resultaria em um operador Assert explícito no plano de execução, posicionado após o operador Merge. Pode não ser desejável adicionar tal restrição (ou mesmo possível se a coluna tiver permissão para conter todos os valores em seu domínio de tipo), mas é uma coisa a considerar.Outra sugestão geral: evite atualizar a coluna de destino quando os valores forem correspondentes. Isso é logicamente um no-op, mas isso nem sempre se traduz fisicamente.