2010-02-05 136 views
2

我有下面的代碼分裂了sql語句並給出了列的索引。在java中解析sql需要幫助

String sql = "INSERT INTO Table1(SSN, EMPID) VALUES (?,?)"; 

    public static List<Object[]> indices(String stmt) { 
     List<Object[]> list = new ArrayList<Object[]>(); 
     String variables[] = null; 
     try { 
      variables = stmt.substring(stmt.indexOf('(')+1, 
       stmt.indexOf(')', stmt.indexOf('(')+1)).split("\\,"); 
     } catch (Exception e) {} 

     for (int i=0; i < variables.length; ++i) { 
      Object [] str = new Object [2] ; 
      str[0] = variables[i].trim() ; 
      str[1] = ((Integer)(i+1)) ; 
      list.add(str) ; 
     } 
     return list; 
    } 


Result - 

list[0] >> 

array[0] = SSN 
array[1] = 1 

list [1] >> 
array[0] = EMPID 
array[1] = 2 

有人點我可以用適當的正則表達式來拆分以下SQL代替 -

sql = "if not exists (select * from Table1 where SSN = ? and EMPID =?) 
     INSERT INTO Table1(SSN, EMPID) VALUES (?,?)" 

我猜的輸出會是這樣的 -

list[0] >> 
array[0] = SSN 
array[1] = 1 

list [1] >> 
array[0] = EMPID 
array[1] = 2 

list[2] >> 
array[0] = SSN 
array[1] = 1 

list [3] >> 
array[0] = EMPID 
array[1] = 2 

謝謝

回答

4

嘗試分析不平凡的語言,如使用正則表達式或其他低級別的字符串撲是一個壞主意SQL。最終會產生無法讀取的代碼和脆弱的「解析器」,這些解析器在提供無效或有效但輸入不同的輸入時會中斷。

你要麼需要執行正確的SQL語法分析程序(或使用現有的),或者改變你的代碼,這樣,你是不是解析SQL而是從別的組裝它。

我有一個應用程序取決於框架,不想引入新的庫!

這是一個不好的理由,否則正確解析。不使用另一個庫有什麼問題?

1

那這一個作爲替代:Zql, a SQL parser。可以更容易地訪問任何SQL語句的「元素」。

編輯

最簡單的第二SQL方法:

只是做了 sql.split("INSERT INTO")和現有代碼適用於第二陣列條目(應該是 " Table1(SSN, EMPID) VALUES (?,?)")。據我瞭解你的代碼,它應該給出正確的結果。

是的,我錯過了你的觀點。使用解析器。

+0

我有一個應用程序取決於框架,不想引入新的庫! – jagamot 2010-02-05 22:38:25

+0

我想你錯過了我的觀點...... PLZ看看需要從第二個SQL產生的輸出。它將是一個包含4個對象的列表。 – jagamot 2010-02-06 04:43:52

+0

那麼Zql能給我參數列名嗎? [如我的問題所示] – jagamot 2010-02-10 13:27:59

0

ZQL parser是巨大的。

它可以分析幾乎所有查詢除了CREATE

特點:

  • list colums
  • list tables
  • FOR clause
  • WHERE clause