1. 程式人生 > >Java下拼接執行動態SQL語句

Java下拼接執行動態SQL語句

  在實際業務中經常需要拼接動態SQL來完成複雜資料計算,網上各類技術論壇都有討論,比如下面這些問題:

  拼接動態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的部署和呼叫的更詳細資訊可參考。

動態表間連線

   相對靜態的表間連線,動態表間連線事先並不知道要使用的表。如下面的資料查詢:

   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語句

  在實際業務中經常需要拼接動態SQL來完成複雜資料計算,網上各類技術論壇都有討論,比如下面這些問題:   拼接動態SQL的一般做法有:   1、使用動態語句   很多資料庫都提供了處理動態SQL的語法,如Oracle的EXECUTE IMMEDIATE語

存儲過程中執行動態Sql語句

查詢 需要 一點 定義 data 復制 ast 我們 臨時   在最近的項目中,有用到動態執行sql語句,SQL為我們提供了兩種動態執行SQL語句的命令,分別是EXEC和sp_executesql;通常,sp_executesql則更具有優勢,它提供了輸入輸出接口,而EXE

怎樣SQL存儲過程中執行動態SQL語句

緩存 參數 insert 每次 一點 證明 record scac 清空緩存 MSSQL為我們提供了兩種動態執行SQL語句的命令,分別是EXEC和sp_executesql;通常,sp_executesql則更具有優勢,它提供了輸入輸出接口,而EXEC沒有。還有一個最大的好

mysql儲存過程執行動態sql語句並返回值

Java程式碼 set @sql=’xxx’; prepare stmt from @sql; execute stmt; deallocate prepare stmt; select @curd1; set @sql=’xxx’; prepare stmt f

用sp_executesql執行動態SQL語句及獲得返回值

過去我執行拼湊出來的動態SQL語句,都直接使用EXEC @sql 的方式。有好幾次,都看到有資料說,應該儘量使用 sp_executesql。究其原因,是因為僅僅引數不同的情況下,sp_executesql可以重用執行計劃,這不就有跟儲存過程一樣的優勢了嗎?同時,sp_exe

儲存過程中執行動態Sql語句

  MSSQL為我們提供了兩種動態執行SQL語句的命令,分別是EXEC和sp_executesql;通常,sp_executesql則更具有優勢,它提供了輸入輸出介面,而EXEC沒有。還有一個最大的好處就是利用sp_executesql,能夠重用執行計劃,這就大大提供了執

oracle儲存過程中如何執行動態SQL語句

有時需要在oracle儲存過程中執行動態SQL語句 ,例如表名是動態的,或欄位是動態的,或查詢命令是動態的,可用下面的方法: set serveroutput ondeclare    n number;    sql_stmt varchar2(50);    t varc

mybaits(查詢與別名、日誌框架顯示sql語句、物件屬性和資料庫表字段不匹配resultMap使用、mysql資料查詢分頁、執行sql和儲存過程、動態SQL語句

主要是各種配置檔案,建議把整個專案搬到自己電腦上慢慢看。 建立maven專案 首先是各種配置檔案: pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://m

返回動態SQL語句執行結果值

--值,動態查詢結果返回 DECLARE @query NVARCHAR(MAX) DECLARE @testVal INT SET @query='select @testVal=

mybatis使用log4j列印sql語句執行結果

本來以為很簡單的問題, 結果自己搞了半天還是不行; 然後google, baidu, 搜出來各種方法, 有加slf4j*.jar的,有說去掉slf4j*.jar,還有說要配置mybatis.cfg.xml的, 有的甚至一眼看上去就是不可能成功的. 試了這麼多, 結果沒有一

java SSM第三章學習內容(動態SQL語句

一. if判斷語句 用法:可以在SQL語句下加if標籤用於判斷 xml <!-- if判斷 -->       <select id="selectif" resultMap="BillProviderResult">           SELECT

java用PrepareStatement實現多sql語句執行

try{ //連線資料庫 conn = ConnMysqlUtil.getConnection();//禁止自動提交(預設為自動提交,所以需要修改)conn.setAutoCommit(false);prst = conn.prepareStatement("update

動態sql語句 Java類寫sql

StockMarketMapper.java package com.oliver.mapper.inter; import java.util.List; import org.apache.ibatis.annotations.InsertProvid

為什麼在mysql資料庫可以執行SQL語句,在java裡卻報錯!!

一,解決方法 為儘快解決問題, 其他程式碼省略,直接說明解決辦 String sql = "select * from tablename"; //引發java虛擬機器報錯

Oracle 過程中執行動態 SQL 或 DDL 語句

如果你用的是 Oracle 8i 及以上的版本,那簡單,在過程中用 execute immediate sql_str 就行, sql_str 是一個拼湊的 SQL 語句,但這個動態語句中帶引數,或 Select 的結果要 into 到變數中時就要稍加留心一下了。而在

java-mybaits-00402-Mapper-動態sql

使用 關閉session 校驗 傳遞 靈活 logs sta 添加 參數 1、動態sql(重點) 通過mybatis提供的各種標簽方法實現動態拼接sql。 什麽是動態sql mybatis核心 對sql語句進行靈活操作,通過表達式進行判斷,對sql進行靈活拼接、組裝。

laravel中查看執行SQL語句

model http nec 條件 alt 今天 不能 conn obj 今天想查看laravel框架中執行的SQL語句,百度了一圈,才找到,這文檔真心看著不爽,下面上查看方法 DB::connection()->enableQueryLog();

Statement執行靜態SQL語句

pda ace ott rac sql name manager table esql package com.isoftstone.jdbc; import java.sql.Connection; import java.sql.DriverManager; imp

Mybatis中的update動態SQL語句 <trim></trim> 用法

color 單獨 null 多個 ride 逗號 myba 不用 log Mybatis Mapper中文件中 update時,需要set設置多個字段,有時逗號處理時,會報錯誤,所以會使用到<trim></trim> 使用trim就是為了刪掉最後

MySQL基礎----動態SQL語句

字段名 基礎 art prepare eat file 動態 執行 esql 尊重原創:http://blog.csdn.net/abc19900828/article/details/39501643 動態sql語句基本語法 1 :普通SQL語句可以用Exec執行 e