1. 程式人生 > 其它 >ibatis,欄位存在表中,根據表中欄位拼接成動態sql語句,執行查詢,再將查詢結果寫入檔案中

ibatis,欄位存在表中,根據表中欄位拼接成動態sql語句,執行查詢,再將查詢結果寫入檔案中

根據需求分析

1.動態sql查詢欄位不固定,故 ibatis 返回List<Map> 結果集,select * 查出的結果集欄位順序會亂,返回值需使用LinkedHashMap

<select id = "searchHashlsdzShlson" resultClass="java.util.LinkedHashMap" remapResult="true">

  <![CDATA[

    SELECT * FROM ZHDZT

  ]]>

</select>

2.由於每次查詢欄位不固定,Oracle沒有現成的函式支援,故寫儲存過程,使用EXECUTE IMMEDIATE 執行 拼接的動態sql,建立臨時表,並插入資料 create table as select * from ...

防止欄位數量過多,導致拼接的sql很長,採用 clob 欄位儲存動態sql,拼接採用DBMS_LOB.append()

儲存過程如下

CREATE OR REPLACE PROCEDURE SHZHDZON(FSMCHTNO IN VARCHAR2,--商戶號

                        FSDATE IN VARCHAR2,--對賬日期

                        RTNSTATE OUT NUMBER,--執行狀態 0:成功 -1:失敗

                       OUTMSG OUT VARCHAR2)--失敗原因

AUTHID CURRENT_USER --解決儲存過程中建立表許可權不足問題

IS

  SQLSTR CLOB;--儲存動態sql

  NUM NUMBER;

  MARK NUMBER;

  SIGN NUMBER;

  CURSOR ASSEMBLE IS

    SELECT TRIM(T1.FL_FIELDNAME) AS FL_FIELDNAME

      FROM HA_SHLSDZ_MOULD T1,

          HA_SHLSDZ_MCHTINF T2

      WHERE T1.FL_MOULDNUM = T2.FL_ON_MOULDNUM

        AND T2.FS_MCHTNO = FSMCHTNO

        ORDER BY T1.FL_SEQ;

  CURRENT_ROW ASSEMBLE%ROWTYPE;--遊標當前行

  LAST_ROW ASSEMBLE%ROWTYPW;--遊標最後一行

BEGIN

  RTNSTATE:=0;--預設執行狀態為成功

  OUTMSG:='執行成功';--預設返回資訊為執行成功

  MARK:=1;

  SIGN:=1;

  SELECT COUNT(1) INTO NUM FROM USER_TABLES WHERE TABLE_NAME = 'ZHDZT';--判斷臨時表存在,則刪除臨時表

  IF NUM>0 TNEN

  EXECUTE IMMEDIATE 'DROP TABLE ZHDZT';

  END IF;

  DBMS_LOB.createtemporary(SQLSTR,true);--建立一個臨時的lob

  DBMS_LOB.append(SQLSTR,'cretae table zhdzt as SELECT ');--開始拼接建立臨時表的SQL語句

  OPEN ASSEMBLE;--開啟遊標

  FETCH ASSEMBLE INTO LAST_ROW;--遊標巢狀一層,便於迴圈時判斷最後一條記錄

  WHILE ASSEMBLE%FOUND THEN

  LOOP

  FETCH ASSEMBLE INTO CURRENT_ROW;

  IF ASSEMBLE%NOTFOUND THEN--如果遊標迴圈到最後一次,拼接SQL時,不加最後那個逗號

    IF INSTR(LAST_ROW.FL_FIELDNAME,'''')>0 THEN--判斷結果為空字串

      DBMS_LOB.append(SQLSTR,''' '''||' AS TEMP'||MARK);--為欄位起臨時別名

      MARK:=MARK+1;

    ELSE

      DBMS_LOB.append(SQLSTR,LAST_ROW.FL_FIELDNAME||' AS '||LAST_ROW.FL_FIELDNAME||SIGN);--為防止欄位重複,為每個欄位加上編號

    END IF;

  ELSE  

    IF INSTR(CURRENT_ROW.FL_FIELDNAME,'''')>0 THEN--判斷結果為空字串

      DBMS_LOB.append(SQLSTR,''' '''||' AS TEMP'||MARK||',');--為欄位起臨時別名

      MARK:=MARK+1;

    ELSE

      DBMS_LOB.append(SQLSTR,CURRENT_ROW.FL_FIELDNAME||' AS '||LAST_ROW.FL_FIELDNAME||SIGN||',');--為防止欄位重複,為每個欄位加上編號

    END IF;

  END IF;

  SIGN:=SIGN+1;

  END LOOP;

  CLOSE ASSEMBLE;

  DBMS_LOB.append(SQLSTR,' from ha_shlddz_shlson where fs_date = '||FSDATE);

  DBMS_LOB.append(SQLSTR,' AND fs_mcht_no in (select fs_mchtno1 from ha_shlsdz_mchtno='||FSMCHTNO||')');

  EXECUTE IMMEDIATE SQLSTR;

EXCEPTION

  WHEN OTHERS THEN

    RTNSTATE:=-1;--異常時,返回執行狀態置為失敗

    OUTMSG:='執行失敗:'||SUNSTR(SQLERRM,1,100);--返回資訊,對異常進行擷取

    ROLLBACK;--回滾

END;

java呼叫    

@Resource(name="ibatisPersistence")

privateIbatisPersistenceibatisPersistence;

Map<String,Object> map = new HashMap<String,Object>();
map.put("FSMCHTNO","12345");
map.put("FSDATE","20210601");
ibatisPersistence.findObject("HashlsdzShlon.HashlsdzShlonPro",map);
int result = map.get("RTNSTATE");--執行結果
String msg = map.get("OUTMSG");--返回執行資訊