SQL Server – Porque NÃO utilizar SET ANSI_WARNINGS OFF

Avalie esse post

Olá pessoal,
Boa noite! Tudo bem ?

Neste post vou comentar sobre um recurso utilizado por muitos desenvolvedores para “resolver” rapidamente alguns problemas comuns no desenvolvimento de queries Transact-SQL. Esse recurso é o SET ANSI_WARNINGS OFF.

Para que serve o comando SET ANSI_WARNINGS OFF?

A opção de controle de sessão ANSI_WARNINGS altera o comportamento do motor do SQL Server para algumas condições, que são:

  • Truncamento de strings (Tentar armazenar um texto de 10 caracteres num VARCHAR(9))
  • Divisão por ZERO
  • Valores NULL em funções de agregação (MAX, SUM, COUNT, etc)

O valor padrão é o ON, que irá apresentar o comportamento padrão ISO para esse tipo de situação, fazendo com que mensagens de erro sejam geradas nas duas primeiras situações e um alerta seja gerado na última situação.

Se você utilizar o comando SET ANSI_WARNINGS OFF, o engine do SQL Server vai reproduzir um comportamento fora do padrão e tentar executar o comando SELECT 10/0, ao invés de uma mensagem de erro, vai retornar NULL e exibir apenas um alerta, permitindo que suas rotinas retornem informações erradas e dados incorretos.

Por este motivo, alguns desenvolvedores SQL, querendo evitar que a aplicação retorne erro nessas situações acabam optando pelo modo mais fácil de “resolver” erros como os listados acima ao invés de realmente atuar no problema e resolvê-lo efetivamente. Isso geralmente ocorre nas empresas devido a diversos motivos, os quais destaco:

  • Falta de conhecimento técnico para identificar e corrigir o erro
  • Falta de vontade de efetivamente resolver o problema
  • Prazos muito apertados para entrega do software funcionando e sem erros

Msg 8134 Divide by zero error encountered

Erro comum no dia a dia dos desenvolvedores SQL, a clássica mensagem de divisão por zero é um indício que algum valor nos seus cálculos está errado. Esse é um erro aritmético básico e que causa uma exceção grave no SQL Server, fazendo com que o comando seja interrompido e a transação sofra um rollback automático. Esse é o comportamento padrão da engine do SQL Server, seguindo o padrão ISO.

O controle desse comportamento é feito em conjunto com o comando ARITHABORT. Quando o ANSI_WARNIGS está ativado, o ARITHABORT é ativado automaticamente, fazendo com que a engine funcione em seu modo padrão (ISO).

Quando o ANSI_WARNINGS está desativado, o ARITHABORT pode ser alterado para mudar o comportamento padrão do Engine. Se ARITHABORT está desativado, ao encontrar um erro de divisão por zero, o SQL Server irá ignorar o erro e continuar a execução normalmente, apenas exibindo um alerta na aba Messages.

Exemplo:

Como vimos no exemplo acima, o ANSI_WARNINGS OFF permite que contas de divisão por zero sejam executadas silenciosamente, gerando dados incorretos e sem que a equipe de desenvolvimento fique sabendo, uma vez que não será gerada nenhuma exceção na aplicação.

Retorno com SET ANSI_WARNINGS ON (Padrão):

Retorno com SET ANSI_WARNINGS OFF:

Msg 8152 String or binary data would be truncated

Essa mensagem de erro é muito comum entre os desenvolvedores SQL e com certeza vocês já devem ter visto enquanto criam suas queries, fazem integrações entre sistemas, etc. Essa mensagem ocorre quando você tenta armazenar uma quantidade de caracteres maior que o permitido em uma coluna.

O comportamento padrão do motor do SQL Server, seguindo o padrão ANSI, faz com que seja gerado uma exceção na execução do seu código Transact-SQL caso você
tenha um texto de 10 caracteres e tente inserir esse texto em uma coluna que permite só até 9 caracteres.

Quando você utiliza o comando SET ANSI_WARNINGS OFF, você faz com que o motor do SQL Server não gere mais esse erro na execução, fazendo com que o seu texto de 10 caracteres seja truncado e armazenado na coluna de 9 caracteres. Os caracteres excedentes serão silenciosamente descartados, ignorando e mascarando um problema na gravação dos dados do seu sistema, sem que ninguém fique sabendo.

Exemplo:

Retorno com SET ANSI_WARNINGS ON (Padrão):

Retorno com SET ANSI_WARNINGS OFF:

Null value is eliminated by an aggregate or other SET operation

Mensagem de alerta que ocorre quando é aplicada uma função de agregação (MAX, SUM, COUNT, AVG, etc) em um conjunto de dados e ao menos 1 registro possui um valor nulo (NULL).

Exemplo:

Retorno com SET ANSI_WARNINGS ON (Padrão):

Retorno com SET ANSI_WARNINGS OFF

Reparem que neste caso, se a opção ANSI_WARNINGS estiver desativada, você pode estar ignorando a existência de valores nulos no seu conjunto de resultados, o que podem indicar um possível problemas, uma vez que em determinadas situações, isso pode representar algum erro na sua query e que você está mascarando.

Caso você queira saber como remover o warning “Null value is eliminated by an aggregate or other SET operation” da forma correta, saiba mais acessando o post SQL Server – Warning: Null value is eliminated by an aggregate or other SET operation.

INSERT failed because the following SET options have incorrect settings: ‘ANSI_WARNINGS’

Mais um grave efeito colateral do uso do ANSI_WARNINGS OFF é o impacto que esse comando influi sobre views indexadas e índices criados em colunas calculadas, que muitas vezes são desenhados para ganho de performance, mas que a simples criação de um índice com o intuito de melhorar, acaba criando uma grande dor de cabeça para o DBA, uma vez que todas as rotinas que inserem dados em tabelas que possuem colunas calculados irão falhar após a criação do índice na coluna calculada.

Diferente dos erros anteriores, que podem causar dados incorretos e inconsistentes, esse exemplo impede que as rotinas funcionem de um modo geral, inclusive já acontecendo comigo, que criei um índice para otimizar uma query lenta na produção e começou a disparar alertas de erros em um dos módulos do sistema de onde trabalho.

Exemplo:

Retorno com SET ANSI_WARNINGS ON (Padrão):

Retorno com SET ANSI_WARNINGS OFF:

Msg 1934, Level 16, State 1, Line 12
CREATE INDEX failed because the following SET options have incorrect settings: ‘ANSI_WARNINGS’. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations.

É isso aí, pessoal!
Espero que tenham gostado do post e até a próxima.

SQL, sql server, sql server 2008, sql server 2008 R2, Oracle, Oracle Database, Oracle 11g, Oracle 10g, Oracle 12c, MySQL, Firebird, Consultoria, Consultor, Programador, Programação. Desenvolvedor, Analista de Sistemas, DBA, Criação de website, Criação de Sistema Web, Vitória, Vila Velha, Guarapari, Espírito Santo, ES, Consultoria SQL em VItória, Treinamento, Curso, Prestação de serviço, prestar serviço, freelancer, freela, banco de dados, consultoria em banco de dados, consultor de banco de dados

Deixe uma resposta