Board logo

标题: 用jsqlparser过滤数据集,使用sql 查询的语法 [打印本页]

作者: admin    时间: 2010-12-24 10:01     标题: 用jsqlparser过滤数据集,使用sql 查询的语法

如果你有一个行列形式的数据集,比如说,二维数组,你想用 sql 兼容的语法过滤数据,该怎么办? 我的答案是用 jsqlparser 结合 beanshell(bsh)来做到。

以下是简表中, 过滤一个csv数据集的示例,供大家参考。思路是采用jsqlparser的visitor编程模型,分析一行是否满足 where表达式。
复制内容到剪贴板
代码:
上面代码的输出
复制内容到剪贴板
代码:

作者: admin    时间: 2010-12-24 10:06

WhereExpressionVisitor.java 源码
复制内容到剪贴板
代码:

作者: cookie    时间: 2011-2-18 12:50     标题: 使用jsqlparser分析SQL語句

您好,請教admin大大

我想使用jsqlparser純粹分析我輸入Update的SQL語句

例如我輸入UPDATE table1 SET column1 = 1 column2 = 2 WHERE column3 = 3;

要如何使用jsqlparser的API來取得使用的UPDATE 指令(如UPDATE和INSERT)、table名、SET之後的參數、WHERE之後的參數呢?

像是如下使用:
xxx.statement => update
xxx.tablename => table1
xxx.set => {column1, 1, column2, 2}
xxx.where => {column3, 3}

不好意思,我是JAVA新手,還請多多觀照
作者: admin    时间: 2011-2-23 12:51

Statement stat = new CCJSqlParserManager().parse(new StringReader(
sql));

Update update = (Update) stat;
有了这个,就好办了,在jsqlparser的源代码里可以看到,update对象里,有很多东西,是你需要的

public class Update implements Statement {
private Table table;
private Expression where;
private List columns;
private List expressions;
作者: cookie    时间: 2011-3-2 17:09     标题: 非常感恩Admin大大

非常感恩Admin大大
抱歉這幾天回家鄉辦點事,現在才回覆您
我在使用Admin大大所教導的方式,出現了些錯誤訊息,不知是哪裡操作錯誤

非常感謝您

----------原始碼----------

import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.parser.CCJSqlParserManager;
import java.io.StringReader;
import net.sf.jsqlparser.statement.update.Update;
import java.util.List;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.expression.Expression;

public class JsqlparserTest
  {
    public static void main( String[] args)
      {
        String sql = new String("UPDATE table1 SET column1 = 1 column2 = 2 WHERE column3 = 3;");
        try
          {
            Statement stat = new CCJSqlParserManager().parse(new StringReader(sql));
            Update update = (Update) stat;
            
            //System.out.println("Get table name: " + (String)update.getTable().getName());
            //System.out.println("Get table schema name: " + (String)update.getTable().getSchemaName());
            //System.out.println((String)update.getWhere());
            //System.out.println((String)update.getColumns());
            //System.out.println((String)update.getExpressions());
          }
        catch(Exception e)
          {
            System.err.println("Error occured-");
            e.printStackTrace();
          }
      }
  }

----------錯誤訊息----------

Error occured-

net.sf.jsqlparser.JSQLParserException
        at net.sf.jsqlparser.parser.CCJSqlParserManager.parse(CCJSqlParserManager.java:40)
        at JsqlparserTest.main(JsqlparserTest.java:34)

Caused by: net.sf.jsqlparser.parser.ParseException: Encountered "<EOF>" at line 1, column 13.

Was expecting one of:
    "AS" ...
    "SET" ...
    <S_IDENTIFIER> ...
    <S_QUOTED_IDENTIFIER> ...

        at net.sf.jsqlparser.parser.CCJSqlParser.generateParseException(CCJSqlParser.java:5450)
        at net.sf.jsqlparser.parser.CCJSqlParser.jj_consume_token(CCJSqlParser.java:5326)
        at net.sf.jsqlparser.parser.CCJSqlParser.Update(CCJSqlParser.java:162)
        at net.sf.jsqlparser.parser.CCJSqlParser.Statement(CCJSqlParser.java:114)
        at net.sf.jsqlparser.parser.CCJSqlParserManager.parse(CCJSqlParserManager.java:38)
        ... 1 more

Caused by:

net.sf.jsqlparser.parser.ParseException: Encountered "<EOF>" at line 1, column 13.

Was expecting one of:
    "AS" ...
    "SET" ...
    <S_IDENTIFIER> ...
    <S_QUOTED_IDENTIFIER> ...

        at net.sf.jsqlparser.parser.CCJSqlParser.generateParseException(CCJSqlParser.java:5450)
        at net.sf.jsqlparser.parser.CCJSqlParser.jj_consume_token(CCJSqlParser.java:5326)
        at net.sf.jsqlparser.parser.CCJSqlParser.Update(CCJSqlParser.java:162)
        at net.sf.jsqlparser.parser.CCJSqlParser.Statement(CCJSqlParser.java:114)
        at net.sf.jsqlparser.parser.CCJSqlParserManager.parse(CCJSqlParserManager.java:38)
        at JsqlparserTest.main(JsqlparserTest.java:34)
作者: cookie    时间: 2011-3-2 17:26     标题: 抱歉,原来是我SQL打错了

抱歉,原来是我SQL打错了「String sql = new String("UPDATE table1 SET column1 = 1 column2 = 2 WHERE column3 = 3;");」中

SET的不同COLUMN中间要有「,」号
虚惊一场
不过还是非常感恩Admin大大的教导^^

----------修改後的原始碼----------

import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.parser.CCJSqlParserManager;
import java.io.StringReader;
import net.sf.jsqlparser.statement.update.Update;
import java.util.List;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.expression.Expression;

public class JsqlparserTest
  {
    public static void main( String[] args)
      {
        String sql = new String("UPDATE table1 SET column1 = 1, column2 = 2 WHERE column3 = 3;");
        try
          {
            Statement stat = new CCJSqlParserManager().parse(new StringReader(sql));
            Update update = (Update) stat;
            
            System.out.println("Get table name: " + (String)update.getTable().getName());
            System.out.println("Get table schema name: " + (String)update.getTable().getSchemaName());
          }
        catch(Exception e)
          {
            System.err.println("Error occured-");
            e.printStackTrace();
          }
      }
  }
作者: admin    时间: 2011-3-3 10:05

好了就好
作者: hero4china    时间: 2011-4-22 10:59

楼主我的需求这这样的,如有这样的语句 select xx1,xx2,xx3 from Xtable where (xx1 like 'abc%' escape '\\’ or xx1 like 'abc%' or xx1 = 'abc' ) and stime between 1234 and 4567;
对于查询条件整理,最后只剩下xx1 like 'abc%' escape '\\’ 。
用这个包处理到了下面的一句
Expression where = ((PlainSelect) select.getSelectBody()).getWhere();
我发现我取不出了那个具体的条件,求指导
作者: admin    时间: 2011-4-22 12:34

我帮你看一下,你只需要取到下图所示的 LikeExpression 那个实例就行了. 怎么样取到这个实例,你懂的.
作者: hero4china    时间: 2011-4-22 13:43

谢谢楼主,其实早上我也取到了。
作者: eric30401    时间: 2011-5-5 16:45

您好,請問 您怎麼樣 將 SQL 架構取出來阿 (用圖形的方式)

謝謝 ^^
作者: admin    时间: 2011-5-5 16:56

你问的是不是9# 楼的那个贴图,这个贴图是eclipse的调试窗口噢!
作者: eric30401    时间: 2011-5-9 11:13

對阿~
請問 您是怎麼用出來的呢 ?
是否要使用什麼 步驟  才會跑出來呢  ?

謝謝^^

[ 本帖最后由 eric30401 于 2011-5-9 13:54 编辑 ]
作者: admin    时间: 2011-5-10 09:28

使用eclipse的单步调试即可.
作者: eric30401    时间: 2011-5-11 16:58

謝謝 ^^
已經用出來了
萬分感謝
作者: fullish    时间: 2011-6-13 11:24     标题: 关于jsqlparser的问题

admin大哥,加我QQ 1342104056
问关于jsqlparser的问题。
急急急。
谢谢,恳求你同意。
作者: jennifer    时间: 2011-6-14 11:21

感谢这位朋友的信任,不过,有问题,还是在这里提,一则,加qq不方便,二则,便于其他朋友共同学习,sorry
作者: fullish    时间: 2011-6-15 10:37

admin大哥,现在的问题是有个sql语句 select * from table where a=1 and b=2
我有个值传过来a=3,我不让其通过,就像你例子里的eval函数,可你的BinaryOperator.eval,我没找到这个类啊。
我该如何验证传过来的变量是否符合where条件。

具体情形是jms activemq在接收消息时,有个消息选择,具体请看j2ee api 的jms规范里的Session接口的createConsumer方法
MessageConsumer createConsumer(Destination destination,
                               String messageSelector)
                               throws JMSException

messageSelector就是按照sql语法来过滤message的,我不知道他是如何实现的,

他只在接收的时候验证哪些消息可以接收 我现在想在发送的时候也验证下,可activemq没有实现。我自己又不知道他是如何过滤掉不符合条件的消息的。

看了你的例子,通过eval实现了这个过滤功能,但还是不太懂,之所以要加QQ,只是练习方便,这个是比较着急的问题,所以加QQ联系方便,谢谢。
作者: jennifer    时间: 2011-6-15 11:17

BinaryOperator.java 可以从简表源码中得到,其作用是封装了 beanshell,beanshell是一个开源的脚本引擎,可以识别java语法,进行条件判断等运算。
使用方法是:
1. 将简表里的 bsh2.0.jar,拿出来,置于你的类路径中。
2. 将 源码中的 BinaryOperator.java 复制出来,放到你的项目源码中,即可.

源码可以从 http://www.jatools.com/jor下载


[ 本帖最后由 jennifer 于 2011-6-15 11:19 编辑 ]
作者: fullish    时间: 2011-6-15 12:12

我按照你说的做了,已经可以打印出结果了,通过或不通过,可是我在测试where条件有and or 时候抛异常了
bsh.InterpreterError: unimplemented binary operator
        at bsh.Primitive.booleanBinaryOperation(Unknown Source)
        at bsh.Primitive.binaryOperationImpl(Unknown Source)
        at bsh.Primitive.binaryOperation(Unknown Source)
        at sqlparser.BinaryOperation._eval(BinaryOperation.java:40)
        at sqlparser.BinaryOperation.eval(BinaryOperation.java:28)
        at sqlparser.WhereExpressionVisitor.visit(WhereExpressionVisitor.java:270)
        at net.sf.jsqlparser.expression.operators.conditional.AndExpression.accept(AndExpression.java:36)
        at sqlparser.WhereExpressionVisitor.eval(WhereExpressionVisitor.java:70)
        at sqlparser.TestSQL2.main(TestSQL2.java:36)

其中TestSQL2.java是我自己写的测试类。请问是什么问题?为什么不支持and或or呢,即复杂的sql
作者: fullish    时间: 2011-6-15 17:41

单个条件测试是没有问题,假如在where条件里多个条件的话,该如何解决呢,我搞了下 还是不行,望指点。
a=1 and b=2 等等类似的条件

跪求。。。
作者: jennifer    时间: 2011-6-16 09:28

我用这个代码测了一下,and表达式可以支持,完整代码见附件。
复制内容到剪贴板
代码:

作者: fullish    时间: 2011-6-16 10:28

谢谢,版主大哥,我的问题已经解决了,非常非常感谢。
非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢非常感谢

打了这么多字 有点刷屏的感觉 但确实是真心表达我的谢意。呵呵。
作者: 小三    时间: 2011-9-15 16:46     标题: 中文的sql语句解析出异常

我用带sql语句解析是出现异常  这是源码
              Statement statement =pm.parse(new StringReader("select * from a where 姓名='崔永远'"));
                if (statement instanceof Select) {
                        Select selectStatement = (Select) statement;
                        PlainSelect ps= (PlainSelect)selectStatement.getSelectBody();
                        System.out.println(selectStatement.getSelectBody());
                        System.out.println(ps.getWhere().toString());
                        System.out.println(((GreaterThan) ps.getWhere()).getRightExpression());
                        System.out.println(((GreaterThan) ps.getWhere()).getStringExpression());
                        SqlParsersUtil sqlParsersUtil = new SqlParsersUtil();
                        List tableList = sqlParsersUtil.getTableNames(selectStatement);
                        for (Iterator iter = tableList.iterator(); iter.hasNext();) {
                                System.out.println(iter.next().toString());
                        }
                }


下面是异常信息
Exception in thread "main" net.sf.jsqlparser.parser.ParseException: Encountered "<EOF>" at line 0, column 0.
Was expecting one of:
    "DROP" ...
    "WITH" ...
    "DELETE" ...
    "CREATE" ...
    "SELECT" ...
    "INSERT" ...
    "UPDATE" ...
    "REPLACE" ...
    "TRUNCATE" ...
    "(" ...
   
        at net.sf.jsqlparser.parser.CCJSqlParser.generateParseException(CCJSqlParser.java:5530)
        at net.sf.jsqlparser.parser.CCJSqlParser.jj_consume_token(CCJSqlParser.java:5406)
        at net.sf.jsqlparser.parser.CCJSqlParser.Statement(CCJSqlParser.java:138)
        at com.ytec.bi.ride.analytics.util.SqlParsersUtil.main(SqlParsersUtil.java:172)
作者: admin    时间: 2011-9-21 09:50

中文不能解析,请参照这里:
http://bbs.jatools.com/viewthread.php?tid=561&extra=page%3D1
作者: ritchie511    时间: 2012-7-12 23:33     标题: 这样的语句怎么会出现问题

update tb_tt set grpcustno='22',changenum='33' where (orgcode,grpcustno) in (select orgcode,grpcustno from tb_tt where changenum='12');


net.sf.jsqlparser.JSQLParserException
at net.sf.jsqlparser.parser.CCJSqlParserManager.parse(CCJSqlParserManager.java:40)
at com.testsql.TestSql1.main(TestSql1.java:60)
Caused by: net.sf.jsqlparser.parser.ParseException: Encountered " <S_IDENTIFIER> "orgcode "" at line 1, column 55.
Was expecting one of:
    "(" ...
    "(" ...
    "(" ...
    "(" ...
    "(" ...
    "(" ...
    "(" ...
    "(" ...
   
at net.sf.jsqlparser.parser.CCJSqlParser.generateParseException(CCJSqlParser.java:5530)
at net.sf.jsqlparser.parser.CCJSqlParser.jj_consume_token(CCJSqlParser.java:5406)
at net.sf.jsqlparser.parser.CCJSqlParser.Expression(CCJSqlParser.java:1493)
at net.sf.jsqlparser.parser.CCJSqlParser.Expression(CCJSqlParser.java:1487)
at net.sf.jsqlparser.parser.CCJSqlParser.WhereClause(CCJSqlParser.java:1257)
at net.sf.jsqlparser.parser.CCJSqlParser.Update(CCJSqlParser.java:187)
at net.sf.jsqlparser.parser.CCJSqlParser.Statement(CCJSqlParser.java:116)
at net.sf.jsqlparser.parser.CCJSqlParserManager.parse(CCJSqlParserManager.java:38)
... 1 more
Caused by:
net.sf.jsqlparser.parser.ParseException: Encountered " <S_IDENTIFIER> "orgcode "" at line 1, column 55.
Was expecting one of:
    "(" ...
    "(" ...
    "(" ...
    "(" ...
    "(" ...
    "(" ...
    "(" ...
    "(" ...
   
at net.sf.jsqlparser.parser.CCJSqlParser.generateParseException(CCJSqlParser.java:5530)
at net.sf.jsqlparser.parser.CCJSqlParser.jj_consume_token(CCJSqlParser.java:5406)
at net.sf.jsqlparser.parser.CCJSqlParser.Expression(CCJSqlParser.java:1493)
at net.sf.jsqlparser.parser.CCJSqlParser.Expression(CCJSqlParser.java:1487)
at net.sf.jsqlparser.parser.CCJSqlParser.WhereClause(CCJSqlParser.java:1257)
at net.sf.jsqlparser.parser.CCJSqlParser.Update(CCJSqlParser.java:187)
at net.sf.jsqlparser.parser.CCJSqlParser.Statement(CCJSqlParser.java:116)
at net.sf.jsqlparser.parser.CCJSqlParserManager.parse(CCJSqlParserManager.java:38)
at com.testsql.TestSql1.main(TestSql1.java:60)
异常信息====================:null

[ 本帖最后由 ritchie511 于 2012-7-12 23:34 编辑 ]
作者: admin    时间: 2012-9-18 08:46

(orgcode,grpcustno) in ...不能这么用吧? 只能用一个字段吧。
作者: ligyu110    时间: 2013-1-17 17:35     标题: 真正杰出的好贴

研究JSqlParser好几天了,网上资料不是很多,而且大多都是英文资料,看着很晕。
下载了文件不知道如何解析对象,获得内容,看了此贴豁然开朗。感谢!
另外请教个问题,此应用程序可以在MyEclipse上运行吗?网上说的相关驱动都是适用于Eclipse的。
作者: admin    时间: 2013-1-18 14:27

可以在myeclipse上运行的,放心.
作者: chenboss    时间: 2015-11-11 21:27     标题: jsqlparser架包提供的方法是否能获取sql select语句关键字,求代码,求帮忙

jsqlparser 比如一个select 语句获取其中使用的函数、获取or的个数 获取and的个数 求大神指导 很急
作者: hpasoft    时间: 2020-9-3 12:08

请回有BinaryOperation的源码吗?




欢迎光临 杰表技术论坛 (http://www.jatools.com/) Powered by Discuz! 6.1.0