Java下拼接執行動態SQL語句

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表中。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章