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");--返回執行資訊