<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 30,  comments - 85,  trackbacks - 0

    最近因工作需要寫一個能夠解析任何sql語句。并將該sql語句中涉及到表提取出來。得到這條sql語句查詢的都是那幾張表的一個工具。

    我采用了java正則表達(dá)式來處理這一需求。 下面是我的代碼。希望大家能夠參考。同時也提出我可能沒有想到的復(fù)雜sql是否能夠處理。呵呵! 謝謝!

    package com.ibm.easyoa.sqlparser;

    import java.util.ArrayList;
    import java.util.List;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    /**
     * SQL 解析
     * @author anwenhao
     *
     */
    public class SqlParserEngine {
     
     private static final String TABLE_VALUE = "([^()]+)";

     /**
      * 1. select * from table
      * 2. select * from table where
      * 3. select * from tableA , tableB
      * 4. select * from tableA where * from (select * from tableB)
      * 5. select * from tableA where * from (select * from tableB  where * from (select * from tableC))...
      * 6. select * from tableA union select * from tableB
      * 7. select * from tableA (left/right) join tableB on ...
      *
      * 考慮以上7種情況的SQL parser過程 這里采用正則表達(dá)式解析
      * @param sql
      * @return
      */
     public List parserSql(String sql){
      List result = new ArrayList();
      String metaRxp = "(?i)select ([^from]+) (?i)from " + TABLE_VALUE;
      Pattern pattern = null;
      Matcher matcher = null;
      pattern = Pattern.compile(metaRxp);
      matcher = pattern.matcher(sql);
      while (matcher.find()) {
       String result1 = matcher.group();
       result1 = this.parserTable(result1, metaRxp);
       //處理是否有where的情況
       String regx = TABLE_VALUE + " (?i)where ([^;]+)";
       Pattern pattern1 = Pattern.compile(regx);
       Matcher matcher1 = pattern1.matcher(result1);
       if (matcher1.find()) {
        String result2 = matcher1.group();
        String tableName = this.parserTable(result2, regx);
        result.addAll(getTableResult(tableName));
       }else{
        // 這里有兩種情況。一種是標(biāo)準(zhǔn)的另一種是join的
        String regx2 = TABLE_VALUE + " (?i)join " + "([^;]+)";
        Pattern pattern2 = Pattern.compile(regx2);
        Matcher matcher2 = pattern2.matcher(result1);
        if (matcher2.find()) {
         String result3 = matcher2.group();
         String table1 = this.parserTable(result3, regx2);
         String table2 = result3.substring(result3.toLowerCase().indexOf("join")+"join".length() , result3.toLowerCase().indexOf("on"));
         result.addAll(getTableResult(table1));
         result.addAll(getTableResult(table2));
        }else{
         result.addAll(getTableResult(result1));
        }
       }
      }
      return result;
     }
     
     /**
      * 將解析出來的table的表名和別名分別存儲
      * @param table
      * @return
      */
     private List getTableResult(String table){
      List result = new ArrayList();
      String[] tempTable = table.split(",");
      for(int i = 0 ; i < tempTable.length ; i++){
       table = tempTable[i].trim();
       String tableResult[] = new String[2];
       String regx = "([a-zA-Z0-9_]+)([\\s]+)([a-zA-Z0-9_]+)";
       Pattern pattern1 = Pattern.compile(regx);
       Matcher matcher1 = pattern1.matcher(table);
       if (matcher1.find()) {
        String[] temp = table.split("([\\s]+)");
        if(temp.length >= 2){
         tableResult[0] = temp[0];
         tableResult[1] = temp[1];
        }
       }else{
        tableResult[0] = table;
       }
       result.add(tableResult);
      }
      return result;
     }
      
     
     /**
      * 通過傳入符合規(guī)則的sql語句去得到當(dāng)前sql的table
      * @param sql
      * @param metaRxp
      * @return
      */
     private String parserTable(String sql, String metaRxp) {
      if (null == metaRxp || metaRxp.length() < 2) {
       return "";
      }
      int i = metaRxp.indexOf(TABLE_VALUE);
      if (i != -1) {
       String str1 = metaRxp.substring(0, i);
       String str2 = metaRxp.substring(i + TABLE_VALUE.length());
       String regex = str1 + TABLE_VALUE + str2;
       Pattern pattern = null;
       Matcher matcher = null;
       pattern = Pattern.compile(regex);
       matcher = pattern.matcher(sql);
       while (matcher.find()) {
        String functionMethod = matcher.group();
        if (functionMethod != null) {
         functionMethod = functionMethod.replaceAll(str1, "");
         functionMethod = functionMethod.replaceAll(str2, "");
         return functionMethod;
        }
       }
      }
      return null;
     }
     
     public static void main(String[] args){
      String sql = "select * from tableA aa , tableD dd where * from (select * from tableB  where * from (select * from tableC))";
      SqlParserEngine engine = new SqlParserEngine();
      List tempList = engine.parserSql(sql);
      for(int i = 0 ; i < tempList.size() ; i++){
       String[] result = (String[])tempList.get(i);
       System.out.println("表名 :" + result[0]);
       System.out.println("別名 :" + result[1]);
       System.out.println("==========================================");
      }
     }
     
    }


    posted on 2007-06-25 15:53 安文豪 閱讀(3047) 評論(10)  編輯  收藏

    FeedBack:
    # re: 解析SQL語句的engine
    2007-06-25 16:18 | 安文豪
    怎么沒有人回復(fù)呢!請大家?guī)蛶兔Πⅲ?nbsp; 回復(fù)  更多評論
      
    # re: 解析SQL語句的engine
    2007-06-25 16:54 | narry
    試試看,正需要一個這樣的工具  回復(fù)  更多評論
      
    # re: 解析SQL語句的engine
    2007-06-25 18:12 | BeanSoft
    我也試試看.  回復(fù)  更多評論
      
    # re: 解析SQL語句的engine
    2007-07-10 09:27 | sitinspring
    我也試試看.  回復(fù)  更多評論
      
    # re: 解析SQL語句的engine
    2007-07-10 14:47 | sitinspring
    select (select sysdate from dual), f01 from table1

    匹配不上啊  回復(fù)  更多評論
      
    # re: 解析SQL語句的engine[未登錄]
    2008-02-15 09:53 | tiger
    做的不錯喲  回復(fù)  更多評論
      
    # re: 解析SQL語句的engine
    2008-04-29 14:04 | 蔣家狂潮
    不錯,除了正則表達(dá)式的方法,還有別的方法嗎?不知道 java sql parser 行不?  回復(fù)  更多評論
      
    # re: 解析SQL語句的engine
    2008-04-29 17:52 | 蔣家狂潮
    我 運(yùn)行過你的程序,就是 正則表達(dá)式有點(diǎn)問題
    String metaRxp = "(?i)select ([^from]+) (?i)from " + TABLE_VALUE;
    加入 sql語句 包含from任一個字符,查詢便會出問題:
    譬如:select f from tableA;或者 select r from tableB
    我不是很懂正則表達(dá)式 我覺得 [^from] 應(yīng)該 匹配 不包含from 字符串的語句,而不是from的其中任意字符。我不知道 “不包含from 字符串 "正則表達(dá)式怎么寫:)  回復(fù)  更多評論
      
    # re: 解析SQL語句的engine
    2009-05-07 13:31 | wolfman09
    想問下:
    "(?i)select ([^from]+) (?i)from " + TABLE_VALUE;
    這個正則表達(dá)式里的的(?i)表示什么意思
      回復(fù)  更多評論
      
    # re: 解析SQL語句的engine
    2009-09-02 10:58 | he
    是啊,對于后面的group by。order by having , 也沒有匹配,而且,如果有select name as 'from' from test 做何處理?  回復(fù)  更多評論
      

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     

    <2007年7月>
    24252627282930
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234

    常用鏈接

    留言簿(6)

    隨筆檔案(28)

    文章分類(3)

    文章檔案(4)

    最新隨筆

    搜索

    •  

    積分與排名

    • 積分 - 86534
    • 排名 - 666

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 午夜影视日本亚洲欧洲精品一区| 久久乐国产精品亚洲综合| 亚洲午夜无码毛片av久久京东热 | 丁香花免费完整高清观看 | 免费视频成人片在线观看| 亚洲成AV人综合在线观看| 日本免费高清一本视频| a成人毛片免费观看| 亚洲香蕉久久一区二区三区四区| 免费一级毛片免费播放| 久久久久久AV无码免费网站下载 | 69成人免费视频| 一级免费黄色大片| 久久精品国产亚洲AV香蕉| 在线免费观看韩国a视频| 久久精品国产免费一区| 伊人久久亚洲综合影院首页| 亚洲一级特黄大片无码毛片| 国产精品成人免费福利| 有码人妻在线免费看片| 亚洲成a人片在线观看中文!!! | 亚洲人成色99999在线观看| 亚洲日韩精品一区二区三区无码 | 永久在线观看免费视频| 亚洲欧美国产国产一区二区三区| 亚洲色欲久久久综合网| 青草草在线视频永久免费| 久久精品国产这里是免费| 日韩亚洲翔田千里在线| 亚洲精品高清国产麻豆专区| 亚洲成a人片在线观看老师| 日本精品人妻无码免费大全 | 免费观看a级毛片| 精品免费久久久久久久| 国产国产人免费人成成免视频| 亚洲色一区二区三区四区| 夜夜亚洲天天久久| 国产亚洲一区二区三区在线| 亚洲AⅤ无码一区二区三区在线| 毛片免费在线观看网站| 6080午夜一级毛片免费看|