sábado, 20 de dezembro de 2014

Tão destrutivo, como injeção SQL

Precisa muita atenção em digitação de números, especificamente NÃO BATER PONTO E VÍRGULA (;).

Eu uso MySQL 5.0.27 com HeidiSQL 9.1.0.4867.

Com HeidiSQL pode inserir novo registro ou alterar registro existente com maneira intuitiva como trabalhando com uma planilha.

O desastre aconteceu quando queria alterar um valor de um campo para '-1,42' (notação da lingua portuguesa) onde devia digitar '-1.42' utilizando ponto em lugar de vírgula.

O procedimento correto em HeidiSQL é
  1. selecionar o campo da tabela
  2. apertar a tecla F2 para colocar o campo em modo de edição
  3. digitar '-1.42'
  4. apertar Enter para sair do modo de edição
  5. apertar Ctrl + Enter para efetuar alteração do registro

O problema aconteceu assim.
No passo 3 foi digitado, sem querer e perceber, '-1;42'
No passo 5 o programa mostrou uma mensagem de erro e a alteração não foi executada.
Se tivesse só alteração não efetuada, não teria nenhum arrepio que senti após o momento do erro.

Todos os valores desta coluna foi modificado em -1 (um negativo), sim TODOS sem nenhuma exceção.
A COLUNA INTEIRA COM MAIS DE MIL REGISTROS SOFREU ARRASTÃO QUE ARRASOU HORAS DE TRABALHO DEIXANDO LIXO DE DADOS.
Tentei entender o que aconteceu, procurei informações na janela inferior onde HeidiSQL mostra as operações executadas como um log.
E descobri uma parte que explica o acontecimento.

UPDATE `vendas` SET `vr_pedra`=-1;42 WHERE `trato_id`=1401 AND `caixa_id`=0;
/* SQL Error (1064) in statement #2: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '42 WHERE `trato_id`=1401 AND `caixa_id`=0' at line 1 */

Se tivesse digitado corretamente acontecia:
UPDATE `vendas` SET `vr_pedra`=-1.42 WHERE `trato_id`=1401 AND `caixa_id`=0;
Esta tabela 'vendas' tem duas colunas de chave primária, 'trato_id' e 'caixa_id' que identifica registro único.

Ponto e vírgula significa fim de uma sentença de SQL.

Com uma troca de ';' em lugar de '.' o programa HeidiSQL executou:
UPDATE `vendas` SET `vr_pedra`=-1;
e não conseguiu entender:
42 WHERE `trato_id`=1401 AND `caixa_id`=0;

"UPDATE `vendas` SET `vr_pedra`=-1" sem frase de WHERE foi aplicado para todos os registros da tabela 'venda'.
Os valores de todos os registros da coluna 'vr_pedra' foi modificado em -1.

A única solução foi contar com arquivo de backup, e repetir as transações após a última cópia de segurança.