Algoritmo para formatar código SQL

11

Preciso de uma ferramenta (para uso interno) que formate o código SQL (SQL Server / MySQL).
Existem várias ferramentas de terceiros e sites on-line que fazem isso, mas não exatamente como eu preciso.

Então, eu quero escrever minha própria ferramenta que atenda às minhas necessidades.

Primeira pergunta: existe algum padrão ou convenção sobre como o código SQL deve ser formatado? (as ferramentas que tentei formatá-lo de maneira diferente)

A segunda pergunta, como devo abordar essa tarefa? A princípio, deveria converter a consulta sql em alguma estrutura de dados como uma Árvore?

jullins
fonte

Respostas:

2

... existe algum padrão ou convenção sobre como o código SQL deve ser formatado?

Padrão, não. Você pode colocar uma instrução SQL inteira em uma linha no que diz respeito a um analisador SQL.

Convenção, com certeza existem muitos. Depende se você está tentando maximizar a capacidade de mudança ou minimizar o espaço. Eu escrevi formatadores SQL para os dois casos.

Eu apenas usei combinações de caracteres específicas para me dizer onde quebrar a instrução SQL.

Aqui está um exemplo de um formatador Java DB2 SQL que escrevi. Outro programa Java gerou o código Java. O SQL veio diretamente das SYSIBMtabelas.

protected void prepareIndex00Select(String codeFacl)
        throws SQLException {
    StringBuffer sb = new StringBuffer();
    sb.append("SELECT CODE_FACL, SEQ_FACL, FILLER_TOF ");
    sb.append("    , CODE_TOF, NAME_FACL, NAME_LENGTH ");
    sb.append("    , CODE_FMB, ID_NCIC_ORI, NBR_PRINTER_PREFIX ");
    sb.append("    , ID_PERSONNEL_OFC, COMPLEX_CODE ");
    sb.append("    , PHS_CODE, DESIG_FACL_GRP, IND_DESIG_AUTH ");
    sb.append("    , CODE_FACL_I_T, INTKEY_FACL, IND_CDM_SENTENCING ");
    sb.append("    , MAL_FEM_IND, DEL_AFTER, IND_INMATES ");
    sb.append("    , VALUE_SO_CPU_STD, VALUE_SO_CPU_DAY ");
    sb.append("    , CODE_CAT, VALUE_DCN, XIDBKEY ");
    sb.append("    , FACL_FK_REGN ");
    sb.append("  FROM ");
    sb.append(creator);
    sb.append(".FACL ");
    sb.append("  WHERE CODE_FACL = ? ");
    if (additionalSQL != null) sb.append(additionalSQL);

    psIndex00 = connection.prepareStatement(sb.toString());
    psIndex00.setString(1, codeFacl);

}   // End prepareIndex00Select method
Gilbert Le Blanc
fonte
O seu produto (o formatador) está disponível on-line ou para download?
jullins
@jullins: Não. Eu escrevi apenas para provar que poderia escrever um aplicativo Java que escreve classes Java, além de criar o SQL a partir da coluna do banco de dados e das tabelas de índice (SYSIBM). Infelizmente, ninguém com quem trabalho achou útil. Suponho que poderia colocar o código em algum lugar, se você quiser.
Gilbert Le Blanc
Eu apreciaria, eu só quero ver a parte da formatação.
jullins
@jullins: Estou no trabalho agora, então não consigo acessar repositórios públicos. Vou colocar o código em algum lugar neste fim de semana e informar como acessá-lo.
Gilbert Le Blanc
e o código? Você pode colocá-lo em algum lugar?
Jillins 21/10
2

Um pouco tarde, só tropeçou nisso, desculpe.

O T-SQL Formatter da Poor Man é um formatador T-SQL de código aberto (biblioteca, plugin ssms, formatador de arquivo de linha de comando, etc.) - a implementação é razoavelmente modular e não deve ser muito difícil implementar um tokenizador e formatador MySQL para coincidir com os do T-SQL (não o fiz principalmente porque não tenho experiência ou uso o MySQL no momento, por isso não é um bom uso do meu tempo).

A biblioteca é implementada em C # (2.0) com uma licença AGPL - isso significa que você não pode redistribuí-la comercialmente ou expor como um serviço público sem publicar nenhuma modificação, mas, para o usuário interno, não deve apresentar problemas, seja ele personalizado ou não.

Como o @Gilbert Le Blank já respondeu, definitivamente não há um padrão na formatação SQL - mesmo os formadores comerciais existentes no mercado, com as diferentes opções que oferecem, não convergem para os mesmos padrões ou necessariamente suportam os mesmos formatos de saída.

No que diz respeito a escrever sua própria ferramenta do zero, eu desaconselharia se você precisar lidar com uma variedade de casos: pelo menos para T-SQL, manipulando lotes de múltiplas instruções SQL com cláusulas CTE WITH, instruções MERGE, subconsultas e tabelas derivadas, etc, acaba por ser bastante difícil :)

Caso haja alguma ajuda: http://www.architectshack.com/PoorMansTSqlFormatter.ashx

Tao
fonte