package com.hengyu.ticket.common; import java.util.HashSet; import java.util.LinkedList; import java.util.Set; import java.util.StringTokenizer; public class SQLFormat { private static final Set<String> BEGIN_CLAUSES = new HashSet<String>(); private static final Set<String> END_CLAUSES = new HashSet<String>(); private static final Set<String> LOGICAL = new HashSet<String>(); private static final Set<String> QUANTIFIERS = new HashSet<String>(); private static final Set<String> DML = new HashSet<String>(); private static final Set<String> MISC = new HashSet<String>(); public static final String WHITESPACE = " \n\r\f\t"; static { BEGIN_CLAUSES.add( "left" ); BEGIN_CLAUSES.add( "right" ); BEGIN_CLAUSES.add( "inner" ); BEGIN_CLAUSES.add( "outer" ); BEGIN_CLAUSES.add( "group" ); BEGIN_CLAUSES.add( "order" ); END_CLAUSES.add( "where" ); END_CLAUSES.add( "set" ); END_CLAUSES.add( "having" ); END_CLAUSES.add( "join" ); END_CLAUSES.add( "from" ); END_CLAUSES.add( "by" ); END_CLAUSES.add( "join" ); END_CLAUSES.add( "into" ); END_CLAUSES.add( "union" ); END_CLAUSES.add( "top" ); END_CLAUSES.add( "limit" ); LOGICAL.add( "and" ); LOGICAL.add( "or" ); LOGICAL.add( "when" ); LOGICAL.add( "else" ); LOGICAL.add( "end" ); QUANTIFIERS.add( "in" ); QUANTIFIERS.add( "all" ); QUANTIFIERS.add( "exists" ); QUANTIFIERS.add( "some" ); QUANTIFIERS.add( "any" ); DML.add( "insert" ); DML.add( "update" ); DML.add( "delete" ); MISC.add( "select" ); MISC.add( "on" ); } static final String indentString = " "; static final String initial = "\n "; public String format(String source) { return new FormatProcess( source ).perform(); } private static class FormatProcess { boolean beginLine = true; boolean afterBeginBeforeEnd = false; boolean afterByOrSetOrFromOrSelect = false; boolean afterOn = false; boolean afterBetween = false; boolean afterInsert = false; int inFunction = 0; int parensSinceSelect = 0; private LinkedList<Integer> parenCounts = new LinkedList<Integer>(); private LinkedList<Boolean> afterByOrFromOrSelects = new LinkedList<Boolean>(); int indent = 1; StringBuilder result = new StringBuilder(); StringTokenizer tokens; String lastToken; String token; String lcToken; public FormatProcess(String sql) { tokens = new StringTokenizer( sql, "()+*/-=<>'`\"[]," + WHITESPACE, true ); } public String perform() { result.append( initial ); while ( tokens.hasMoreTokens() ) { token = tokens.nextToken(); lcToken = token.toLowerCase(); if ( "'".equals( token ) ) { String t; do { t = tokens.nextToken(); token += t; } while ( !"'".equals( t ) && tokens.hasMoreTokens() ); // cannot handle single quotes } else if ( "\"".equals( token ) ) { String t; do { t = tokens.nextToken(); token += t; } while ( !"\"".equals( t ) ); } if ( afterByOrSetOrFromOrSelect && ",".equals( token ) ) { commaAfterByOrFromOrSelect(); } else if ( afterOn && ",".equals( token ) ) { commaAfterOn(); } else if ( "(".equals( token ) ) { openParen(); } else if ( ")".equals( token ) ) { closeParen(); } else if ( BEGIN_CLAUSES.contains( lcToken ) ) { beginNewClause(); } else if ( END_CLAUSES.contains( lcToken ) ) { endNewClause(); } else if ( "select".equals( lcToken ) ) { select(); } else if ( DML.contains( lcToken ) ) { updateOrInsertOrDelete(); } else if ( "values".equals( lcToken ) ) { values(); } else if ( "on".equals( lcToken ) ) { on(); } else if ( afterBetween && lcToken.equals( "and" ) ) { misc(); afterBetween = false; } else if ( LOGICAL.contains( lcToken ) ) { logical(); } else if ( isWhitespace( token ) ) { white(); } else { misc(); } if ( !isWhitespace( token ) ) { lastToken = lcToken; } } return result.toString(); } private void commaAfterOn() { out(); indent--; newline(); afterOn = false; afterByOrSetOrFromOrSelect = true; } private void commaAfterByOrFromOrSelect() { out(); newline(); } private void logical() { if ( "end".equals( lcToken ) ) { indent--; } newline(); out(); beginLine = false; } private void on() { indent++; afterOn = true; newline(); out(); beginLine = false; } private void misc() { out(); if ( "between".equals( lcToken ) ) { afterBetween = true; } if ( afterInsert ) { newline(); afterInsert = false; } else { beginLine = false; if ( "case".equals( lcToken ) ) { indent++; } } } private void white() { if ( !beginLine ) { result.append( " " ); } } private void updateOrInsertOrDelete() { out(); indent++; beginLine = false; if ( "update".equals( lcToken ) ) { newline(); } if ( "insert".equals( lcToken ) ) { afterInsert = true; } } private void select() { out(); indent++; newline(); parenCounts.addLast( Integer.valueOf( parensSinceSelect ) ); afterByOrFromOrSelects.addLast( Boolean.valueOf( afterByOrSetOrFromOrSelect ) ); parensSinceSelect = 0; afterByOrSetOrFromOrSelect = true; } private void out() { result.append( token ); } private void endNewClause() { if ( !afterBeginBeforeEnd ) { indent--; if ( afterOn ) { indent--; afterOn = false; } newline(); } out(); if ( !"union".equals( lcToken ) ) { indent++; } newline(); afterBeginBeforeEnd = false; afterByOrSetOrFromOrSelect = "by".equals( lcToken ) || "set".equals( lcToken ) || "from".equals( lcToken ); } private void beginNewClause() { if ( !afterBeginBeforeEnd ) { if ( afterOn ) { indent--; afterOn = false; } indent--; newline(); } out(); beginLine = false; afterBeginBeforeEnd = true; } private void values() { indent--; newline(); out(); indent++; newline(); } private void closeParen() { parensSinceSelect--; if ( parensSinceSelect < 0 ) { indent--; parensSinceSelect = parenCounts.removeLast().intValue(); afterByOrSetOrFromOrSelect = afterByOrFromOrSelects.removeLast().booleanValue(); } if ( inFunction > 0 ) { inFunction--; out(); } else { if ( !afterByOrSetOrFromOrSelect ) { indent--; newline(); } out(); } beginLine = false; } private void openParen() { if ( isFunctionName( lastToken ) || inFunction > 0 ) { inFunction++; } beginLine = false; if ( inFunction > 0 ) { out(); } else { out(); if ( !afterByOrSetOrFromOrSelect ) { indent++; newline(); beginLine = true; } } parensSinceSelect++; } private static boolean isFunctionName(String tok) { final char begin = tok.charAt( 0 ); final boolean isIdentifier = Character.isJavaIdentifierStart( begin ) || '"' == begin; return isIdentifier && !LOGICAL.contains( tok ) && !END_CLAUSES.contains( tok ) && !QUANTIFIERS.contains( tok ) && !DML.contains( tok ) && !MISC.contains( tok ); } private static boolean isWhitespace(String token) { return WHITESPACE.indexOf( token ) >= 0; } private void newline() { result.append( "\n" ); for ( int i = 0; i < indent; i++ ) { result.append( indentString ); } beginLine = true; } } }
相关推荐
而其内嵌的SQL格式化工具则能够帮助开发者统一SQL语句的风格,使代码更易于阅读和理解,从而降低出错率和团队协作难度。 "SqlFor"标签可能是指这个工具是专门为Java开发者设计的SQL格式化解决方案。在Java编程环境...
然而,SSMS本身并不内置SQL代码的格式化功能,这就是为什么需要额外的SQL格式化工具,如SQL Pretty Printer。 SQL Pretty Printer是一款专业的SQL代码美化和格式化软件,它专门设计用于将杂乱无章的SQL脚本转换为...
一款非常好用的SQL格式化工具 SQLserver必备的工具。
超好用的sql格式化工具,支持单个sql格式/sql文件批量格式/监控剪切板并自动将sql复制的sql语句格式化工具, 支持mssql/oracle/mysql/msaccess/generic... 一句话,不好用回帖骂我吧
SQL格式化工具2.8.7汉化+破解 SQL Pretty Printer是一款简单易用、功能强大的SQL格式化工具 SQL Pretty Printer自2005推出以来,一直深受广大用户的好评,是数据库管理人员和程序开发人员的得力助手。 截至2009年...
为了提升代码的可读性和可维护性,通常会使用SQL格式化工具对查询进行美化。本文将详细讲解一个基于C#实现的SQL格式化功能,它源于Hibernate项目,并且已经去除了无用的功能,不依赖任何第三方DLL。 首先,让我们...
SQL Prompt是一款由Red Gate Software开发的强大SQL代码编辑和格式化工具,主要针对SQL Server环境。在标题中提到的"SQL Prompt 6.1 5.3"是指该工具的两个不同版本,6.1是较新的一个,而5.3是其前任版本。SQL Prompt...
SQL格式化工具是一种专门用于美化和标准化SQL代码的软件,它可以帮助程序员和数据库管理员将混乱不堪的SQL脚本整理成整齐、易读的格式。在处理大量或复杂的SQL语句时,这种工具显得尤为重要,因为它可以提高代码的...
- **兼容性**:Windows平台上有许多专门为该操作系统优化的SQL格式化工具,它们通常与Windows集成良好,支持拖放操作,与Windows Explorer无缝协作。 - **集成开发环境(IDE)**:许多SQL IDEs(如SQL Server ...
在处理复杂的查询时,自动生成的SQL可能会变得难以阅读和理解,这就需要SQL格式化工具来帮助优化代码。 描述中提到这个功能去除了“没用的功能”,这意味着该Java代码可能是一个精简版的SQL格式化器,专注于最基本...
sql格式化工具使你的sql语句更加清晰
为了解决这个问题,开发者通常会使用SQL格式化工具来美化和标准化代码。在给定的“sql格式化JS脚本”中,我们看到一个名为`SqlFormat.js`的文件,它提供了在前端环境中对SQL语句进行格式化的功能。 这个JavaScript...