우요니
378
2018-06-14 18:52:16
5
888

ibatis 질문 하겠습니다.


ibatis 질문좀 하겠습니다.


iterate 태그에서 IN 구문에서 들어갈 값들이 1000개이상 넘어가면

ORA-01795 에러가 생겨서 OR문으로 변경하려하는데


iterate를 처음 써봐서 그런데


어떤식으로 바꿔야될까요?


팁좀주시면감사드리겠습니다.



<select id="selectTableExistList" parameterClass="commonVO" resultClass="commonVO">
		<![CDATA[
			SELECT table_name FROM tabs
		]]>
		
		<isNotNull property="table_name">
			where table_name = #table_name#
		</isNotNull>
		
		<isNull property="table_name">
			<iterate property="table_list" prepend=" WHERE table_name IN " open="(" close=")" conjunction=",">
				#table_list[]#
			</iterate>
			ORDER BY table_name asc
		</isNull>
	</select>


0
0
  • 답변 5

  • ansdbduf
    781
    2018-06-14 19:41:11

    프리페어 스테이트먼트에 인자는 1000개를 넘을수없습니다. 

    임시테이블에 값 인서트후 조인하세요

    0
  • DPJ
    502
    2018-06-14 19:51:41

    이런걸 경험해본적없는 신입개발자이나 저라면 이렇게 해결할수있지않을까 정도의 의견제시를 해보자면

    데이터가 1000개 이상으로 계속 늘어날 가능성이 있는데이터인지 아니면 계속 비슷한 갯수로 유지되는 데이터인지에 따라  실시간으로 처리해야되는지 배치인지에 따라도 다를수 있을거 같네요

    계속 비슷한 갯수로 고정되는것이고ㅠ변하지 않는다면 윗분 말씀대로 해도 될거같고 일정갯수만큼 분할(청크처럼?)하여 인서트문을 때리는건 어떨까ㅛ??

    0
  • 우요니
    378
    2018-06-14 21:05:32 작성 2018-06-14 21:12:52 수정됨

    네 데이터가 천개를 초과할때 ORA-01795 에러가 생성이되서 테이블의 구조를 바꾸면 해결된다고  인터넷상에 나와있더라구영


    근데 iterate IN 구문을 OR 구문으로 바꾸게된다면 어떤식으로 태그를 바꿔야할지 조언좀받고싶네요...


    <iterate property="table_list" prepend=" WHERE table_name IN " open="(" close=")" conjunction=",">
    				#table_list[]#
    </iterate>


    인터넷 참고해보니 <dynamic prepend="wheere">~ 이런식으로 시작하는 구문도있어서

    위에있는 기존에 있던걸 아래처럼 바꾸면 가능할련지 모르겠네요...


    <dynamic prepend="WHERE">
    <iterate property="table_list" prepend="table_name=" open="(" close=")" conjunction="OR">
    				#table_list[]#
    </iterate>
    </dynamic>


    위가 실행이되면

    쿼리문이 WHERE=(table_list[0] or table_list[1] or table_list[2]......)이런식으로 만들어질까요?

    0
  • sspkos
    117
    2018-06-15 10:51:39 작성 2018-06-15 11:23:24 수정됨

    이 문제는 iBatis문제가 아니라 오라클의 IN, OR  논리적 함수에 기인합니다.

    먼저 IN 은 999개 이내만 처리 가능토록 되어 있습니다.

    그래서 오라클은 IN 은 OR로 다시 파싱을 하게 됩니다.

    즉 , OR ,OR.....999개로 변경하여 실행이 됩니다.

    즉 IN이든 OR든 오라클에서는 999 개를 넘지 못하도록 설계 되어 있습니다.

    그러나 우리 프로그래머들은 그렇다고 우리가 안된다고는 할 수없어 다른 방법으로 처리하겠지요

    저는 이렇게 처리하여 관리하고 있습니다. 참조가 된다면 좋겠습니다.

    먼저 ,tab_list[]를 담을 수 있는 임시 테이블을 생성해 놓습니다.

    임시테이블에 입력되어온 table name을 무조건 insert처리합니다. 이렇게 하면

    1000개든 10000개든 다 입력이 될테니까요!!

    입력이 완료되면 "임시테이블과"  TABS 테이블과 equal join으로 처리하면 될겁니다.


    다만 여기서 이런  기능을 누군가와 동시에 수행할 수있으므로 "임시테이블"을 사용자별로 등록할 수

    있는 테이블 구조이어야 되겠지요

    그런다음 본 기능을   insert처리하겠지요.

    그런다음 "임시테이블"과 tabs 테이블을 equal 조인하여 현황을 출력합니다.

    아래 사용예를 참조하시기 바랍니다.

            UUID uuid = UUID.randomUUID();

                daoCommon.insert_tab_list(uuid, tab_list, ui);
                list = sqlMapClientTemplate.queryForList("namespace명.selectTableExistList", hm);
                daoCommon.delete_tab_list(uuid, ui);  ---조회후 반드시 해당 데이타 삭제 처리

    물론 다양한 방법이 있으리라 생각이 됩니다.

    저같은 경우 현장에서 날라오는 실시간의 데이타를 일괄 처리할때 대략 10000개든 그이상 ..

    대부분 이렇게 처리를 합니다.

    도움이 되셨기를 .....



    0
  • 우요니
    378
    2018-06-15 19:30:21

    sspkos님 충분한 피드백 감사합니다.

    덕분에 생각의 폭을 넓힐수 있어서 대단히 많이 도움되었습니다.

    좋은 주말보내세요^^

    0
  • 로그인을 하시면 답변을 등록할 수 있습니다.