首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

JAVA正则表达式依据查询SQL自动生成统计SQL

2012-11-10 
JAVA正则表达式根据查询SQL自动生成统计SQL  JAVA的JDBC,对于取出的来结果集好象不能直接取到结果集的数量

JAVA正则表达式根据查询SQL自动生成统计SQL
  JAVA的JDBC,对于取出的来结果集好象不能直接取到结果集的数量,要使用一个计数器,不停的next(),一直到结束。这样才得到数量。

  这样的效率对于大量记录而言显然是不能忍受的。显然使用select count(*) from tableName可以获得最好的效率。那么,当有查询语句时,如何能方便、快捷的得到统计语句呢?这个需要在WEB项目上分页显示数据记录的时候用得比较多。

  最近用了几次正则表达式,让我想到一个办法,可以使用正则表达式动态的根据查询SQL语句,自动的将形如select name,sex from tableName的查询SQL语句转换成select count(*) from tableName这样的统计SQL语句。大家知道,正则表达式有查找、替换功能,这正是完成这样任务所需要的。



  做这样一个小任务的时候,先要理解正则表达式的贪心模式(也有叫贪婪模式)与非贪婪模式。

  所谓贪婪模式,就是对于这样的SQL查询语句:

  select name from (select name from tableName)

  当使用正则表达式:(^select)(.*)( from .*) 进行匹配时,中间的(.*)部分,

  在贪心模式
下,中间部分会尽可能多的匹配,其结果就是: name from (select name

  在非贪心模式
下,中间部分会尽可能少的匹配,其结果就是: name



  显然对于我的小任务而言,需要的是非贪心模式,那么如何让正则表达式切换到非贪心模式下呢?很简单,正则表达式写成这样就可以了:(^select)(.*?)( from .*)。这样就达到了预定的目的。

  完整的java函数如下:

    public String getCountSql(String sql) {

        String regex = "(^select)(.*?)( from .*)";

        Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);

        Matcher m = p.matcher(sql);

        boolean rs = m.find();

        if (rs == false || m.groupCount() != 3) {

            return "";

        } else

            return m.group(1) + " count(*) " + m.group(3);

    }





后记


  这个小小的函数,有个BUG,不知大家想到没有,就是处理这样的SQL语句会有问题:

  select (select max(id) from tableName)+1 id, name from tableName,

  这时应该用到括号的匹配来去除干扰,不过正则表达式该怎么写,我还没有想出来,欢迎知道的朋友留言告知。

/***********本人原创,欢迎转载,转载请保留本人信息*************/
作者:wallimn 电邮:wallimn@sohu.com 时间:2009-02-13
博客:http://blog.csdn.net/wallimn http://wallimn.iteye.com
网络硬盘:http://wallimn.ys168.com
/***********文章发表请与本人联系,作者保留所有权利*************/ + sql
+ ") CUSTOM_IMPORT_QUERY";
return Integer.valueOf(this.executeScalar(newSql, param).toString());

}


如果你有更好的方法,烦请电邮一份给我,谢谢!Email:CodingMouse@gmail.com 2 楼 CodingMouse 2010-01-03   忘了贴 executeScalar 方法了:

/**
* 执行查询SQL命令并返回单个值。<br><br>
*
* @param sql 要执行的带占位符SQL命令字串。
* @param param SQL参数对象(无SQL参数时请使用 null 关键字)。
* @return 单个值。
* @throws DataAccessException 数据访问异常。
*/
public Object executeScalar(
String sql,
SQLParameter param)
throws DataAccessException {

try {
this.conn = DB_CONNECTION_POOL.getConnection();
this.trans = new DBTransaction(this.conn);
this.trans.begin();
this.ps = DataTypeConverter.java2Jdbc(
this.conn.prepareStatement(sql),
param);
this.rs = this.ps.executeQuery();
Object value = null;
if (this.rs.next()) {
value = this.rs.getObject(1);
}
this.trans.commit();
return value;
} catch (Throwable e) {
this.trans.rollback();
throw new DataAccessException(e);
} finally {
this.closeAll();
}

}

如果你有更好的方法,烦请电邮一份给我,谢谢!Email:CodingMouse@gmail.com

热点排行