请问怎样分析一个sql语句查询了哪几张表。
例如,有下边几种情况
select * from ta tb               
select * from ta as tb
select ta.*,tb.* from ta,tb,tc where  xxx=xxx  
select ta.*,tb.* from ta t1,tb t2,tc  t3 where   
select ta.*,tb.* from ta  join  tb  on  xxx  join tc   
select ta.*,tb.* from ta  t1 join  tb  t2  on  xxx  join tc t3 on xxxxx  有什么好的算法分析这些语句,可以得到查询的物理表。
随便给个思路 或者伪代码都行,分不够再加。谢谢!

解决方案 »

  1.   

    从from截取到第一个sql 关键字结束,然后用“,”分割这个串,对于每个元素取空格前的。
    大致思路,不一定完整。
      

  2.   

    恩,同上,对含有join得语句,先讲join替换为","就可以了
      

  3.   


    import java.util.*;public class testSQL {    public static void main(String[] args) {
            String sql = "select ta.*,tb.* from ta  t1 join  tb  t2  on  xxx  join tc t3 on xxxxx ";
            ArrayList list = new ArrayList();
            int indexOfWhere;
            int indexOfFrom;
            sql = sql.replaceAll("join", ",");
            if (sql.indexOf("where") != -1) {
                indexOfWhere = sql.indexOf("where");
            } else {
                indexOfWhere = sql.length();
            }
            indexOfFrom = sql.indexOf("from");
            sql = sql.substring(indexOfFrom + 4, indexOfWhere);
            
            
            StringTokenizer st = new StringTokenizer(sql, ",") ;
            while(st.hasMoreElements()) {
                String temp = st.nextToken().trim();
                list.add(temp.substring(0,temp.indexOf(" ")).trim());
            }        for(Iterator iter = list.iterator(); iter.hasNext();) {
                System.out.println((String)iter.next());
            }
        }}
      

  4.   

    可以借用编译原理的经典理论
    SELECT语句的EBNF表达式可以在SQL Server或者Oracle的帮助文档里找到,然后构造词汇表,词法分析,造语法树,就可以了分析了。这样最准确,但是会比较麻烦,建议你用已经写好的第三方工具类库,比如antlr。你可以查一下antlr的用法。Hibernate在分析HQL转成SQL的过程就是用的antlr, WebLogic把EJB QL转SQL也使用的这个类库。如果你的SQL只包含你的例子中那几种情况,那么或许可以简单的处理,自己写一个词法分析器,parse过程中你可以把FROM后面和JOIN后面的处理一下。这样扩展性差,只适用于比较简单的。总之无论如何,此法分析器一定要写的,不能直接String.indexof("FROM")或者String.indexof("JOIN"),比如这种情况:
    SELECT 'It''s a Message from the ' + address from contact 
    你必须用词法分析器把这个SQL解释为
    SELECT:关键字
    'It''s a Message from the ':literal
    +:运算符
    address:标识符
    from:关键字
    contact:标识符然后你才能根据EBNF语法定义找语法树中关键字from后面的标识符作为表名
    如果对于这个SQL你直接用String.indexof("FROM"),那么第一个from后面是the,这就毫无道理的乱套了
      

  5.   

    所以你的程序基本绝对不应该出现
    String.replace("JOIN", ",")
    String.indexOf("FROM")
    String.indexOf("JOIN")
      

  6.   

    个人觉得,这个可以简单的看成字符串提取的问题
    用正则表达式就可以
    例如:
    select ta.*,tb.* from ta,tb,tc where  xxx=xxx    String s="select ta.*,tb.* from ta,tb,tc where  sdfdsf sdafsd xxx=xxx";
        Pattern p = Pattern.compile("from\\s+([^\\s]+)\\s");    Matcher m = p.matcher(s);    boolean rs=m.find();
        for (int i = 1; i <= m.groupCount(); i++) {
          System.out.println(m.group(i));
        }
    得出结果:ta,tb,tc ,然后再对结果以,区分出各个表
    当然如果SQL中还有join就比较麻烦了,但是同样写出正则表达式,再过滤一次就可以了
      

  7.   

    to  tjjzs(王、) 还是老问题,如果把这条SQL
      SELECT 'It''s a Message from the ' + address from contact 
    按你给的正则表达式
      from\\s+([^\\s]+)\\s
    来匹配,明显结果是错误的还有很多其他的情况,也会出错,就不一一列举了