Java

[SPRING+iBATIS] 여러개의 SELECT문으로 구성된 쿼리결과 중에 일부 SELECT문의 결과를 리턴 받지 못할 때

특정페이지에서 제품별로 속성값들이 여러개 존재한다.
예를 들어, 자동차로 비유했을때, 차종, 제조사, 지역, 대리점 등등 의 정보를 공통코드로 관리한다고 보면된다.
그런데 문제가 발생했다. 제품의 속성정보가 여러개이거나 제품을 여러개 선택했을 때 특정 속성을 간헐적으로 가져오지 못하는 문제가 발생하였다.
원인을 찾기 위해 로그를 찍었고, 그 원인을 찾았다.
공통코드값을 일괄로 조회하기 위해 ‘|’구분자를 두고 프로시저를 호출하여 받는 구조로 되어 있었다.

DECLARE @V_SELECT_QRY VARCHAR(MAX) , @V_CNT INT, @V_MAX_CNT INT, @V_CODE_M VARCHAR(30) ; 
SET @V_CNT = 0; 

drop table #TBL_LIST 

CREATE TABLE #TBL_LIST(IDX INT, VALUE VARCHAR(200)); 

INSERT #TBL_LIST 
SELECT a.INDEX_NO - 1, a.Value FROM dbo.FN_TBL_SPLIT_TEXT('#DATE#|#TEST_1#|#TEST_2#|#TEST_3#|#TEST_4#|#TEST_5#|#TEST_6#|#TEST_7#|#TEST_8#|#TEST_9#|#TEST_10#|#TEST_11#|#TEST_12#', '|') a 
WHERE a.VALUE != '' ; 

SET @V_SELECT_QRY ='' 
SELECT @V_MAX_CNT = COUNT(Value) FROM #TBL_LIST 

--select * FROM ##TBL_LIST 

WHILE @V_CNT < @V_MAX_CNT 
BEGIN 
	SELECT @V_CODE_M = VALUE FROM #TBL_LIST 
    WHERE IDX = @V_CNT;
    
    IF @V_CODE_M = '#DATE#' 
    BEGIN 
      SET @V_SELECT_QRY = @V_SELECT_QRY + ' SELECT TODAY = CONVERT(VARCHAR(8), GETDATE(), 112)
      , TODAY_F_DOT = CONVERT(VARCHAR(10), GETDATE(), 102)
      , TODAY_F_ISO = CONVERT(VARCHAR(10), GETDATE(), 120)
      , TODAY_DT = CONVERT(VARCHAR(8), GETDATE(), 112) + REPLACE(CONVERT (VARCHAR(8), GETDATE(), 108), '':'' , '''')
      , TODAY_DT_F = CONVERT(VARCHAR, GETDATE(), 120)' ; 
      END 
    ELSE 
    BEGIN 
      SET @V_SELECT_QRY = @V_SELECT_QRY + ' SELECT CODE_D, CODE_D_NM, EXT_FIELD1, EXT_FIELD2, EXT_FIELD3, EXT_FIELD4, EXT_FIELD5 
      FROM TB_COMMON_CODE WHERE CODE_M = ''' + @V_CODE_M + ''' AND USE_YN = ''Y'' 
      ORDER BY (CASE WHEN ORD_SEQ IS NULL THEN 0 ELSE ORD_SEQ END)' ; 
    END 
    SET @V_CNT = @V_CNT + 1; 
END 

SELECT @V_SELECT_QRY EXEC( @V_SELECT_QRY);

샘플로 예를 든 프로시저의 스크립트는 위에서 보는 봐와 같이 구성되어 있다.
WHILE문을 통해 총 갯수만큼 SELECT문을 동적으로 만든 후 마지막에 EXEC문을 통해 일괄로 실행 후 리턴하는 구조로 되어 있다. 그런데 8개 이상부터는 쿼리결과를 받아오지 못했다.
Vue.js에서 제한을 걸어둔 소스는 발견되지않았다. mssql 프로시저 리턴 결과의 제한도 아니였다.
코드 변경 후 발생되는 문제 같았기에, 개선하면서 하드코딩 되어 있던 기존에 다른 개발자가 개발해놓은 코드를 복구하였다. 그리고 문제는 해결되었다. 그 코드는 다음과 같다.

const comboIds ='#DATE#|#TEST_1#|#TEST_2#|#TEST_3#|#TEST_4#|#TEST_5#|#TEST_6#|#TEST_7#|#TEST_8#|#TEST_9#|#TEST_10#|#TEST_11#|#TEST_12#';
const tmpArr = comboIds.split('|'); 
this.codeIds = ''; 
for (let i = 0; i < tmpArr.length - 1; i += 8) {
	this.codeIds = ''; 
    for (let j = 0; j < 8; j += 1) { 
    	this.codeIds = `${this.codeIds}${tmpArr[i + j]}|`; 
    } 
this.postCodeList(this.codeIds); 
}

원인이 무엇을까를 생각해 보던중 SPRING 프레임웍 ORM쪽 문제인가? 라는 생각이 들었다.
아이바티스를 사용중임으로 해당 프로시저를 호출하는 부분의 xml파일을 열어보았다.

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd">

<sqlMap namespace="Common"> 
<typeAlias alias="cmnMap" type="core.util.ParamMap"/>

<select id="common.codeList" 
  parameterClass="cmnMap" 
  resultClass="cmnMap,cmnMap" 
  remapResults="true"> 

EXEC SP_DATA @P_COMMON_ID = #comboId#, @P_PARAM = #param#, @P_PARAM1 = #param1# 
</select>

프로시저의 여러개의 SELECT문의 결과를 cmnMap이라는 ListOrderedMap에 담고 있다.
그런데 resultClass에 선언된 cmnMap의 개수가 여러개 존재한다. 보통 하나씩 두고 사용했는데, 이렇게 사용하는 것은 처음 접한다. 설마 select문당 1개씩 필요한건가? 혹시 몰라 9개까지 여분을 둔것일까? cmnMap를 여러개 더 추가해볼까?

import org.apache.commons.collections.map.ListOrderedMap; 

public class ParamMap extends ListOrderedMap implements Cloneable {
  private static final long serialVersionUID = 1848851032730232522L; 

  @Override 
  public Object put(Object key, Object value) { 
  	// TODO Auto-generated method stub 
  	return super.put(((String) key), value); 
  } 

  @Override public Object get(Object key) {
  if(super.containsKey(key)) { 
    Object obj = super.get(key) == null ? "" : super.get(key); 
    String className = obj.getClass().getName(); 
    
    if(className.equals("java.sql.Date")) obj = obj.toString(); 
    
    return obj; 
    
   } else { 
   	return ""; 
   } 
  } 

  @Override 
  public Object clone() throws CloneNotSupportedException {
      return super.clone(); 
  } 
}

바로 테스트에 들어갔다. 아래 코드처럼 여러개를 추가했다.

<select id="common.codeList" 
parameterClass="cmnMap" 
resultClass="cmnMap,cmnMap,cmnMap" 
remapResults="true"> 
	EXEC SP_DATA @P_COMMON_ID = #comboId#, @P_PARAM = #param#, @P_PARAM1 = #param1# 
</select>

예상은 적중하였다. 정상적으로 동작하였다. 임시방편으로 넉넉하게 30개의 resultClass에 선언을 해둔 상태이다.
해결은 되었으나 개수가 더 늘어날 경우 또 추가해줘야하는 문제들이 발생할 수 있다.

Leave a Reply

error: Content is protected !!