[Error] Execution (1: 1): ORA-29275: 부분 다중 바이트 문자



[원인]

오라클 서버의 CHARACTERSET과 클라이언트의 CHARACTERSET이 서로 다르고 호환도 되지 않는 경우 발생하는 오류.


[해결법]


1. 서버의 characterset 확인.

select parameter, value
from nls_database_parameters
where parameter like '%CHARACTERSET%';


2. 클라이언트 characterset 확인.


실행 ( 윈도키+R ) > regedit 레지스터 편집기 실행 > LNS_LANG 검색 후 언어설정 확인.



경로는 HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE ...






일반 개발자에게 서버에 CHARSET을 변경할 권한은 당연히 없을것이고 DBA라고 하더라도 너무 무모한 짓이다.  로컬 PC의 레지스트리의 NLS_LANG 값을 서버 charset과 동일하게 KOREAN_KOREA.AL32UTF8 (KOREAN_KOREA.AL16UTF17) 로 바꾸는 방법이 한 방법이다.






Tools -> Preferences -> PL/SQL Beautifier  항목에서

Rules fils에서 파일위치 지정

PLSQL_Beautifier.br



Error : executeQueryForObject returned too many results.


queryForObject 사용시


결과값이 하나 이상이 넘어갈때 발생

queryForList로 사용한다, 아니면 단일값이 나오는 결과에 맞게 재구성한다.




단건 조회면 selectByPk를 호출하시면 되는데.. 아마도 해당 query가 하나의 데이터(ResultSet)이 아닌 여러 건이 리턴된 경우입니다.

iBatis는 query xml 작성 시 단건 select와 다건 select를 구분하지 않고 API 호출 할 때에 단건이나 다건이냐를 구분합니다.

selectByPk는 queryForObject를 통해 단건으로 처리하고, list는 queryForList로 다건을 처리합니다.

결론... boardPageDAO.selectBoardPage_S id로 지정된 query의 결과가 하나 이상 나오기 때문에 query에 where 조건을 추가하는 등의 수정이 필요합니다.

참고 


http://open.egovframe.kr/cop/bbs/selectBoardArticle.do?bbsId=BBSMSTR_000000000013&nttId=14188



쿼리가 다건 리턴하므로 dao에 select메소드로 되어 있는거 list메소드로 수정함


이렇게

select("CommuteDao.selectCommuteTimeInfo", param); 

=> list("CommuteDao.selectCommuteTimeInfo", param);


select 검색할때 파라미터를 리스트로 보내서 리스트에 있는 값을 하나하나씩 매핑시켜서 결과를 받을 때 유용한 쿼리죠. 

예를 들면 어떠한 리스트에 있는 값을 통해 쿼리문을 생성한다던지 하는 경우 iBatis에서는 iterate 태그로 for문과 같은 역할을 하여 동적 쿼리를 생성 할 수 있습니다.

<select id="getData" parameterclass="java.util.List" resultclass="int">
    SELECT  count(0)
    FROM    data_tb
    <iterate prepend="WHERE id IN" open="(" close=")" conjunction=",">
            #[]#
     </iterate>
</select>

위와 같이 parameterClass를 java의 List 형태로 전달해 주면 동적쿼리를 생성할수 있습니다. 만약 list에 1,2,3,4 의 데이터가 들어가 있으면 결과적으로 다음과 같은 쿼리가 실행되는 것과 같습니다.


<select id="getData" parameterclass="java.util.List" resultclass="int">
    SELECT  count(0)
    FROM    data_tb
    WHERE  id IN (1,2,3,4)
</select>

이렇게 iterate 를 사용하여 동적 쿼리문을 생성할 수 있습니다. 또한 parameterClass가 list형태가 아닌 Map이 List를 가지고 있는 형태도 iterate의 property 속성을 통해 접근할 수 있습니다.

만약 HashMap에 paramList라는 이름으로 list형이 들어가 있다고 가정하면

예)

 HashMap<String, Object> paramMap = new HashMap<String, Object>();

 List<Integer> paramList = new ArrayList<Integer>();

 paramMap.put("paramList", paramList);


<select id="getData" parameterclass="HashMap" resultclass="result">
    SELECT  *
    FROM    data_tb
    <iterate property="paramList" prepend="WHERE id IN" open="(" close=")" conjunction=",">
            #paramList[]#
    </iterate>
</select>

위와 같이 HashMap에 들어있는 list는 iterate의 property 속성을 통해 List를 가져 옵니다. ##사이는 HashMap에 put했던 list이름을 넣어주셔야 작동합니다.




select M_NAME,M_TIME from RESEARCH where M_TIME between to_date('2003-11-12', 'YYYY-MM-DD') and to_date('2003-11-14', 'YYYY-MM-DD');

위에서 2003년 11월12일 부터 2003년 11월14일사이의 데이터만 디비에서 셀렉트해오고 싶다고 가정할때 쿼리의 결과는
12일부터 13일사이의 데이터만가지고 오는데 문제는 14일데이터를 못가져오는것입니다.
12일부터 15일사이를 검색하면 되겠지만 사용자입장에서 좋은방법 같지가 않습니다.

방법 :
select M_NAME,M_TIME from RESEARCH where M_TIME between to_date('2003-11-12', 'YYYY-MM-DD') and to_date('2003-11-14' || ' 23:59:59', 'YYYYMMDD HH24:MI:SS');

 오늘은 오라클 ROWNUM, BETWEEN AND, TO_CHAR, LAG OVER, LEAD OVER, NVL, MAX 쿼리에 대해서 알아보겠습니다.


1
2
3
4
5
6
7
8
    SELECT *
    FROM (SELECT result1.*,ROWNUM rnum 
          FROM (SELECT num,writer,title,content,regdate
                FROM board_guest
                ORDER BY num DESC
                ) result1
         )
    WHERE rnum BETWEEN #{startRowNum} AND #{endRowNum}
cs


ROWNUM  : 보통 오라클에서 페이징을 하거나 top n 을 뽑을때 사용합니다.

 

BETWEEN  : 범위를 지정하여 조건을 걸 때 사용합니다.



1
2
3
4
5
6
7
8
9
        SELECT result1.*
        FROM 
            (SELECT num,writer,title,content,
            TO_CHAR(regdate, 'YYYY.MM.DD AM HH:MI') regdate,
            LAG(num, 10) OVER(ORDER BY num DESC) prevNum,
            LEAD(num, 10) OVER(ORDER BY num DESC) nextNum
            FROM board_guest
            ORDER BY num DESC) result1
        WHERE num=#{num}
cs


TO_CHAR(숫자 혹은 날자, format)  : 숫자나 날짜를 문자로 변환해 주는 함수입니다.


LAG : 이전(위) Row 값을 가져올때 사용합니다.


LEAD : 이후(아래) Row 값을 가져올때 사용합니다.


OVER : ORDER BY, GROUP BY 서브쿼리를 개선하기 위해 나온 함수라고 할 수 있습니다.

   참고 : http://blog.naver.com/whitefre/140148769754



1
2
        SELECT NVL(MAX(ROWNUM), 0)
        FROM board_guest
cs


MAX : 최고값에 해당하는 값을 가져올때 사용합니다.


NVL : 테이블에 not null 처리가 안되어 있는 컬럼에 대해서 자주 사용합니다.

어떤 컬럼이 Null이면 특정값으로 치환해야하는 경우에 사용합니다.

+ Recent posts