標籤:
Java拼接動態SQL的一般做法有
1、使用動態語句
很多資料庫都提供了處理動態SQL的文法,如Oracle的EXECUTE IMMEDIATE語句、MSSQL的EXEC和SP_EXECUTESQL、Mysql的預先處理語句等。這些功能讓我們在資料庫端來處理動態查詢提供了極大遍曆,但這種方式只適用於相對簡單地動態查詢,複雜的情況經常會採用下面的方式。
2、使用預存程序
對於複雜的情況,一般會在預存程序中來拼接動態SQL。使用預存程序完成相對靈活,但編碼複雜度過高,有時運行效率較低。
3、使用其他(如JAVA)程式
使用外部的其他進階語言(如JAVA)拼接後再交由資料庫執行也是一種選擇,其靈活性較高,但由於JAVA缺乏對集合計算的支援,完成這些準備工作並不輕鬆。
如果需要執行動態SQL的主控程式是JAVA的,那麼可以使用集算器來協助完成動態SQL類計算,集算器是動態解釋執行的指令碼,可以方便地拼出動態SQL執行。集算器提供了JDBC介面,可以置於Java應用程式與資料庫之間,讓應用程式繼續象訪問資料庫一樣執行集算器指令碼,應用結構幾乎不用改變。
下面通過例子來說明如何使用集算器完成動態SQL類計算,並整合進JAVA程式。
拼接動態SQL
在集算器中完成動態SQL拼接,並將拼接後的SQL再交由資料庫執行,以查詢出目標結果。集算器在完成時並不涉及目標計算,只拼接動態SQL。如下面的需求:
參數source和target代表兩個結構相同但資料不同的表,但表結構未知。要求以主鍵為標準用source更新target,比如table1和table2的主鍵都是A和B,資料如下:
用table2更新table1時,MERGE語句應當如下:
MERGE INTO table1 as t
USING table2 as s
ON t.A=s.A and t.B=s.B
WHEN MATCHED
THEN UPDATE SET t.C=s.C,t.D=s.D
WHEN NOT MATCHED
THEN INSERT VALUES(s.A,s.B,s.C,s.D)
實現指令碼:
A1,A2: 從系統資料表中讀出表source的主鍵存入變數pks,計算結果為集合["A","B"]。各種資料庫獲得主鍵的方法不同,這裡以MSSQL為例。
A3,A4:讀出source的完整欄位,columns的計算結果為["A","B","C","D"]。
A5:動態產生MERGE語句。pks.(…)是迴圈函數,可對集合(包括結果集)的成員依次計算,計算中可用~引用迴圈變數,用#引用迴圈計數。
A6:執行MERGE語句。
由於表結構未知,用預存程序或JAVA獲得表結構再動態拼出SQL非常麻煩。使用集合類計算支援良好的集算器來做,代碼簡單,指令碼通用,易於維護。
集算指令碼的計算結果可以作為報表資料來源供報表使用,還可以在JAVA程式中通過JDBC的方式讀取並使用,JAVA讀取調用集算指令碼代碼如下:
Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
//調用集算器指令碼(類似預存程序),其中p1是集算指令碼的檔案名稱
st =(com. esproc.jdbc.InternalCStatement)con.prepareCall("call p1()");
st.setObject(1,"table1");
st.setObject(2," table2");
//執行指令碼
st.execute();
……
調用集算器指令碼和訪問資料庫的方法完全一樣,熟悉JDBC的程式員可以很快掌握。
關於集算器JDBC的部署和調用的更詳細資料可參考集算器整合應用之被JAVA調用
。動態表間串連
相對靜態表間串連,動態表間串連事先並不知道要使用的表。如下面的資料查詢:
A表
B表
C表
現需要根據A表的TableName擷取B表或C表對應ID的Num值。
目標結果:
實現指令碼:
A1:執行SQL從A表取數;
A2:先按TableName分組,迴圈分組拼接動態查詢語句,最後把查詢結果按照ID排序。
通過集算器的集合計算能力(分組後仍然儲存著分組成員供後續使用),讓動態SQL的拼接工作簡單化。
特殊格式資料更新
除了動態資料查詢,有時還需要進行動態更新,更新的資料經常來源於第三方程式,其格式也多種多樣,如JSON格式、XML等。在特殊的業務背景下,有時需要將這些較特殊格式(相對傳統的二維表來說)的資料更新到(關係)資料庫中。這就需要藉助第三方程式完成,而像JAVA等進階語言存在缺少類庫、寫入程式碼困難等問題。這時可以採用集算器來完成,下面來看一個集算器解析JSON格式檔案入庫的例子,來源資料如下:
要求:將上述內容中指定節點,主要是imei的Service列表更新到資料庫2張表groups和Services中。
這裡的JSON串由於包含多層且很多層都是動態(如LIST和SERVICES下的節點數量和名稱都不固定),這為解析帶來了很大難度;而且其中屬性名稱部分還包含空格(如MOVISTAR SPAIN)和點號(如Requires.Network)這也大大增加瞭解析難度,使用JAVA非常難寫。
實現指令碼:
A1:讀入JSON格式檔案,結果為帶有層次的結果集;
A2-A3:建立儲存更新內容的兩個空序表;
A4-D10:迴圈A1,動態解析內容並將解析結果輸出到A2、A3目標結果序表中;
A11-A12:執行更新,將A2、A3序表更新到groups和services表中。
Java下拼接執行動態SQL語句