Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como posso verificar as instruções (My)SQL para correção sintática


Depois de procurar uma ferramenta CLI para linting de sintaxe no Mysql para usar no Jenkins e não encontrar nada rapidamente (esta pergunta do Stackoverflow é um dos primeiros resultados - LOL) cheguei à seguinte solução (SO:Linux, mas deve ser viável com o Windows também):

Algo como o seguinte:
lint_result=`mysql mysql_test -B -f -e 'select asdf s where x;' 2>&1`; if [ `echo $lint_result | sed -r "s/ERROR ([0-9]*).*/\1/g"` -eq 1064 ]; then echo -e "Syntax error:\n${lint_result}"; fi
Syntax error:
ERROR 1064 (42000) at line 1: 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 'where x' at line 1

(Para verificar arquivos sql, você pode usar "
Se a sintaxe da consulta não puder ser analisada pelo mysql, ele alega:ERRO 1064 (42000) na linha 1:Você tem um erro em sua sintaxe SQL; verifique o manual que corresponde à versão do seu servidor MySQL para a sintaxe correta para usar perto de '' na linha 1

Somente se a sintaxe estiver correta ele tenta executar a consulta e percebe que a tabela não existe mas isso não é mais interessante:
ERROR 1146 (42S02) at line 1: Table 'mysql_test.s' doesn't exist

Portanto, o erro 1064 é a sintaxe inválida. Você só precisa criar um banco de dados de teste vazio porque, caso contrário, apenas erros com uma parte FROM errada apareceriam (aqui, por exemplo, o banco de dados é necessário para obter um resultado de verificação de sintaxe válido:'select asdf from s where x and if;).

Tanto quanto eu testei, funciona bem (Versão Mysql 5.5).

Aqui uma versão completa do script bash:
#!/bin/bash

source_dir=${1};
database="mysql_test";
mysql_args="-h127.0.0.1";

mysql $mysql_args -B -e "DROP DATABASE IF EXISTS $database; CREATE DATABASE $database;";
for file in `find $source_dir -name "*.sql"`; do
    lint_result=`mysql $mysql_args $database -f -b < $file 2>&1`;
    if [ "`echo $lint_result | sed -r \"s/ERROR ([0-9]*).*/\1/g\"`" = "1064" ]; then
        echo -e "Syntax error in file ${file}:\n${lint_result}" && exit 1;
    fi;
done