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")  

private IbatisPersistence ibatisPersistence;

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");--返回执行信息

























上一篇:数据库技术基础:数据库管理系统的功能介绍笔记


下一篇:DB DBMS SQL关系以及表的理解