- java-How to parse sql columns with JDBC or jSqlParser ?
- 2. Environments
- 3. The code
- 3.1 The database table environment
- 3.2 Parse column names with JDBC
- 3.2 Parse with jSqlParser library
- 3.2.1 Add the dependency
- 3.2.2 The Utility Method
- 3.2.3 Now we test it
- 4. Conclusion
- Saved searches
- Use saved searches to filter your results more quickly
- License
- Licenses found
- JSQLParser/JSqlParser
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- Parsing SQL CREATE query using JSQLParser
- JSQLParser maven dependency
- Parsing SQL Create query in Java
- Expected output
java-How to parse sql columns with JDBC or jSqlParser ?
This post would demo how to parse sql column names with JDBC or jSqlParser.
2. Environments
3. The code
3.1 The database table environment
Assume that we have a table named tbl_city, which has two column names like this:
CREATE TABLE tbl_city ( id INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT, name VARCHAR(255) );
3.2 Parse column names with JDBC
The most easiest way is to execute the sql and get the columns from the ResultSetMetaData.
public static void main(String[] args) System.out.println("Mysql JDBC Parse Column Names Testing ~"); try Class.forName("com.mysql.jdbc.Driver"); > catch (ClassNotFoundException e) System.err.println("Unable to find the mysql JDBC Driver!"); e.printStackTrace(); return; > // default database: mysql // JDK 1.7+, auto close connection with try-with-resources, you do not need to use try-finally to close the resource. try (Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456")) //would close the Connection automatically String sql = "select * from tbl_city"; // the sql to parse java.sql.Statement statement = connection.prepareStatement(sql); try (ResultSet rs = statement.executeQuery(sql)) //would close the ResultSet automatically ResultSetMetaData rsMeta = rs.getMetaData(); int columnCount = rsMeta.getColumnCount(); for (int i = 1; i columnCount; i++) String columnName = rsMeta.getColumnName(i); System.out.format("%s\n", columnName); > > > catch (SQLException e) System.err.println("Something went wrong!"); e.printStackTrace(); return; > >
Execute the code and we get this result:
3.2 Parse with jSqlParser library
But what if we don’t want to execute the sql , or we can’t execute the sql, how to parse sql column names without execute it? You can try the jSqlParser library.
3.2.1 Add the dependency
com.github.jsqlparser jsqlparser 1.1
3.2.2 The Utility Method
public static ListString> getColumns(String sql) throws JSQLParserException CCJSqlParserManager parserRealSql = new CCJSqlParserManager(); Statement stmt = parserRealSql.parse(new StringReader(sql)); // create a jSqlParser Statement from the sql ListString> list=new ArrayListString>(); // contains the columns result if (stmt instanceof Select) // only parse select sql Select selectStatement = (Select) stmt; //convert to Select Statement PlainSelect ps = (PlainSelect)selectStatement.getSelectBody(); ListSelectItem> selectitems = ps.getSelectItems(); selectitems.stream().forEach(selectItem -> list.add(selectItem.toString()));//add the selected items to result > return list; >
3.2.3 Now we test it
public static void main(String[] args) throws JSQLParserException String sql = "select a,b from tbl_city"; getColumns(sql).stream().forEach(c-> System.out.println(c)); // get a b System.out.println("----"); String sql2 = "select a from (select b from table1 left join table2 on table2.c=table1.d)"; // get a getColumns(sql2).stream().forEach(c-> System.out.println(c)); System.out.println("----"); String sql3 = "select * from tbl_city"; getColumns(sql).stream().forEach(c-> System.out.println(c)); // get * >
As you can see, the jSqlParser can parse the sql columns without executing it, but if you do not specify the column names in your sql, for example, select * from test, it can not get the right column names. So ,use it with caution.
4. Conclusion
You can parse the sql columns with JDBC, if you choose this way, you must execute the sql on the database, then you would get the real column names. If you can’t or don’t want to execute the sql ,you can try the jSqlParser library. But use it with caution.
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
JSqlParser parses an SQL statement and translate it into a hierarchy of Java classes. The generated hierarchy can be navigated using the Visitor Pattern
License
Apache-2.0, LGPL-2.1 licenses found
Licenses found
JSQLParser/JSqlParser
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
Please visit the WebSite. JSqlParser is a RDBMS agnostic SQL statement parser. It translates SQL statements into a traversable hierarchy of Java classes (see Samples):
SELECT 1 FROM dual WHERE a = b
SQL Text └─Statements: statement.select.PlainSelect ├─selectItems: statement.select.SelectItem │ └─LongValue: 1 ├─Table: dual └─where: expression.operators.relational.EqualsTo ├─Column: a └─Column: b
String sqlStr = "select 1 from dual where a=b"; PlainSelect select = (PlainSelect) CCJSqlParserUtil.parse(sqlStr); SelectItem selectItem = select.getSelectItems().get(0); Assertions.assertEquals( new LongValue(1) , selectItem.getExpression()); Table table = (Table) select.getFromItem(); Assertions.assertEquals("dual", table.getName()); EqualsTo equalsTo = (EqualsTo) select.getWhere(); Column a = (Column) equalsTo.getLeftExpression(); Column b = (Column) equalsTo.getRightExpression(); Assertions.assertEquals("a", a.getColumnName()); Assertions.assertEquals("b", b.getColumnName()); >
JSqlParser aims to support the SQL standard as well as all major RDBMS. Any missing syntax or features can be added on demand.
RDBMS | Statements |
---|---|
Oracle MS SQL Server and Sybase PostgreSQL MySQL and MariaDB DB2 H2 and HSQLDB and Derby SQLite | SELECT INSERT , UPDATE , UPSERT , MERGE DELETE , TRUNCATE TABLE CREATE . , ALTER . , DROP . WITH . |
JSqlParser can also be used to create SQL Statements from Java Code with a fluent API (see Samples).
Alternatives to JSqlParser?
General SQL Parser looks pretty good, with extended SQL syntax (like PL/SQL and T-SQL) and java + .NET APIs. The tool is commercial (license available online), with a free download option.
Parsing SQL CREATE query using JSQLParser
There are multiple use-cases for parsing a Create Statement. Suppose if you want to validate the table schema between the source and target system and make sure you are using the same table and column names, you can very well parse the Create statements of both the systems and generate a report or send an alert email with the observations. For Parsing SQLs in java using the JSQLParser library, we can use the below maven dependency in the project.
JSQLParser maven dependency
You need to create a new maven project and add the following dependency in your pom.xml file to access this parsing library
com.github.jsqlparser jsqlparser 1.4
The following JSQLParser example program will help you to understand how we can parse the CREATE SQL statement.
Parsing SQL Create query in Java
import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.operators.conditional.AndExpression; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.create.table.ColDataType; import net.sf.jsqlparser.statement.create.table.ColumnDefinition; import net.sf.jsqlparser.statement.create.table.CreateTable; import net.sf.jsqlparser.statement.insert.Insert; import net.sf.jsqlparser.statement.select.*; import net.sf.jsqlparser.util.SelectUtils; import java.util.ArrayList; import java.util.List; public class CreateSqlParser < public static void main(String[] args) < System.out.println("Program to parse CREATE sql statement"); System.out.println("-------------------------------------"); String createSQL = "CREATE Table User.TableName (" + "id INTEGER NOT NULL," + "name varchar(100) NOT NULL," + "CRE_TS TIMESTAMP(0) NOT NULL," + "UPD_TS TIMESTAMP(0) NOT NULL" + ")" ; try < Statement createTable = CCJSqlParserUtil.parse(createSQL); System.out.println("Table Name from query: " + ((CreateTable) createTable).getTable().getName()); System.out.println("Database Name from query: " + ((CreateTable) createTable).getTable().getSchemaName()); String sqlTableName = ((CreateTable) createTable).getTable().getName(); System.out.println("Columns in the given insert query"); System.out.println("---------------------------------"); for(ColumnDefinition col: ((CreateTable) createTable).getColumnDefinitions()) < System.out.println(col.getColumnName() + " - " + col.getColDataType().toString()); >//Modifying the tablename and DB ((CreateTable) createTable).getTable().setName("NewTable"); ((CreateTable) createTable).getTable().setSchemaName("NewDatabase"); //Adding a new column to the create statement ColumnDefinition newCol = new ColumnDefinition(); newCol.setColumnName("processDate"); ColDataType colDataType = new ColDataType(); colDataType.setDataType("DATE"); newCol.setColDataType(colDataType); List colSpecStrings = new ArrayList<>(); colSpecStrings.add("FORMAT 'YYYY-MM-DD' NOT NULL DEFAULT DATE '1970-01-01'"); newCol.setColumnSpecStrings(colSpecStrings); ((CreateTable) createTable).getColumnDefinitions().add(newCol); String newSql = createTable.toString(); System.out.println("\nNew Create statement:"); System.out.println("-----------------------"); System.out.println(newSql); System.out.println("New Columns"); System.out.println("-----------"); for(ColumnDefinition col: ((CreateTable) createTable).getColumnDefinitions()) < System.out.println(col.getColumnName() + " - " + col.getColDataType().toString()); >> catch (JSQLParserException e) < e.printStackTrace(); >> >
Expected output
The output of the above JSQLParser example program is given below. You can see that we are able to extract the database name, table name, list of columns and the data types of each of the columns as well.
Program to parse CREATE sql statement ------------------------------------- Table Name from query: TableName Database Name from query: User Columns in the given insert query --------------------------------- id - INTEGER name - varchar (100) CRE_TS - TIMESTAMP (0) UPD_TS - TIMESTAMP (0) New Create statement: ----------------------- CREATE TABLE NewDatabase.NewTable (id INTEGER NOT NULL, name varchar (100) NOT NULL, CRE_TS TIMESTAMP (0) NOT NULL, UPD_TS TIMESTAMP (0) NOT NULL, processDate DATE FORMAT 'YYYY-MM-DD' NOT NULL DEFAULT DATE '1970-01-01') New Columns ----------- id - INTEGER name - varchar (100) CRE_TS - TIMESTAMP (0) UPD_TS - TIMESTAMP (0) processDate - DATE