오라클 부적합한 열 이름 - olakeul bujeoghabhan yeol ileum

java.sql.SQLException: 부적합한 열 인덱스 오류

오라클 부적합한 열 이름 - olakeul bujeoghabhan yeol ileum

위의 사진과 같은 오류가 발생하였고, 코드는 아래와 같이 작성했었습니다. 

이와 같은 에러가 발생하는 이유는 즉, 들어갈 값이 부적절해서 발생하는 에러입니다.

	int result = 0;
    String sql = "insert into board values((select max(seq)+1 from board),?,?,?,sysdate,?,?)";
    PreparedStatement st = con.prepareStatement(sql);

	st.setString(2, board.getTitle());
	st.setString(3, board.getContents());
	st.setString(4, board.getWriter());
	st.setInt(6, board.getPassword());
	st.setInt(7, 0);
    
    st.executeUpdate();
            
            

PreparedStatement로 쿼리문 작성시 파라미터를 물음료포 표시하고,

"PreparedStatement변수명.setString(몇번째 물음표 인지 숫자로 표시, 들어갈 값)" 과 같이 작성해야합니다.

그러나 저는 insert에 들어가는 칼럼이 7개여서 거기에 맞춰 들어갈 칼럼 위치의 숫자로 표시해 실행을 시켜  맨 위와 같은 부적절한 인덱스 오류가 뜨게 되었습니다.

즉, 순서가 틀려서 서로 다른 부적합한 값이 들어가 에러가 발생했던 것이였습니다.

그래서 물음표만 넣은 위치 순서를 다시 넣어서 실행시킨 결과 아주 잘 실행되었습니다!!

	int result = 0;
    String sql = "insert into board values((select max(seq)+1 from board),?,?,?,sysdate,?,?)";
    PreparedStatement st = con.prepareStatement(sql);
    
    st.setString(1, board.getTitle());
    st.setString(2, board.getContents());
    st.setString(3, board.getWriter());
    st.setInt(4, board.getPassword());
    st.setInt(5, 0);
    
	result = st.executeUpdate();

ERROR

java.sql.SQLException: 부적합한 열 이름

오류내용
java.sql.SQLException: 부적합한 열 이름

원인 - xml에서 설정한 컬럼명과 레코드셋에서 받아오는 변수명이 같이 않아 발생함.

처리 - 쿼리 부분 컬럼명과 동일하게 맞쳐줌.

jsp 파일

 Id:  <%=rs.getString("id") %><br>
Pass:  <%=rs.getString("pass") %><br>
Name:  <%=rs.getString("name") %><br>
Address: <%=rs.getString("address") %><br>
Phone:  <%=rs.getString("phone") %><br>
Email:  <%=rs.getString("email") %><br>
<%-- 오류 부분
Today: <%=rs.getString("today") %><br><br> --%>

<%-- 처리 부분 --%>
Today: <%=rs.getString("regdate") %><br><br>

 
java 파일 - 해당 부분 실행되는 쿼리

 String sql="INSERT INTO USERINFO(ID,PASS,NAME,ADDRESS,PHONE,EMAIL,REGDATE)"+
     "VALUES(?,?,?,?,?,?,?)";

다양한 경우에서 이런 Exception이 출몰하는 것 같다.

아래의 경우는 사용되는 Column/Table들의 이름들을 동적으로 설정한 것이며,
그 외에 결과 값의 Column 이름들이 변하는 경우에도 동일하게 적용된다.

<select id="fileInfo"  resultClass="java.util.Map" parameterClass="java.util.Map">

원문: http://jace.tistory.com/trackback/57
----------------------------------------------------------------------------------
[ibatis] 동적으로 column명을 사용할때 java.sql.SQLException: 부적합한 열 이름 에러 해결

ibatis를 사용하는 경우 동적으로 table name과 column name을 생성하여
쿼리를 실행해야 하는 경우가 발생한다.

예를 들면 다음과 같다.
<select id="fileInfo"  resultClass="java.lang.String" parameterClass="java.util.Map">
    SELECT $columnName$
      FROM $tableName$
    WHERE $pkName$ = #pkValue#
</select>

전혀 이상없는 구문이나 실행시 에러가 발생한다.
이상하게도 처음 실행시에는 에러가 발생하지 않으나,
두번째 부터 에러가 발생하기 시작한다.

WAS를 재기동하면 또 첫번째는 이상없으나, 두번째 부터 에러가 발생한다.

에러 내용은 다음과 같다.
(본인은 Spring AOP를 이용하여 ibatis 트랜잭션을 핸들링 하고 있으므로
에러 로그는 틀릴수 있다.)

[03-05 20:41:52] ERROR StandardWrapperValve.java:253 : Servlet.service() for servlet jsp threw exception
java.sql.SQLException: 부적합한 열 이름
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208)
        at oracle.jdbc.driver.OracleStatement.getColumnIndex(OracleStatement.java:3296)
        at oracle.jdbc.driver.OracleResultSetImpl.findColumn(OracleResultSetImpl.java:1914)
        at oracle.jdbc.driver.OracleResultSet.getString(OracleResultSet.java:1515)
        at org.apache.tomcat.dbcp.dbcp.DelegatingResultSet.getString(DelegatingResultSet.java:225)
        at sun.reflect.GeneratedMethodAccessor36.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at com.ibatis.common.jdbc.logging.ResultSetLogProxy.invoke(ResultSetLogProxy.java:47)
        at $Proxy14.getString(Unknown Source)
        at com.ibatis.sqlmap.engine.type.StringTypeHandler.getResult(StringTypeHandler.java:35)
        at com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.getPrimitiveResultMappingValue(BasicResultMap.java:611)
        at com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.getResults(BasicResultMap.java:344)
        at com.ibatis.sqlmap.engine.mapping.result.AutoResultMap.getResults(AutoResultMap.java:55)
        at com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlExecutor.java:381)
        at com.ibatis.sqlmap.engine.execution.SqlExecutor.handleMultipleResults(SqlExecutor.java:301)
        at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.java:190)
        at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteQuery(GeneralStatement.java:205)
        at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:173)
        at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:104)
        at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:566)
        at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:541)
        at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:106)
        at org.springframework.orm.ibatis.SqlMapClientTemplate$1.doInSqlMapClient(SqlMapClientTemplate.java:243)
        at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:193)
        at org.springframework.orm.ibatis.SqlMapClientTemplate.queryForObject(SqlMapClientTemplate.java:241)
        at com.thinkfree.common.CommonDao.fileDelete(CommonDao.java:31)
        at com.thinkfree.common.CommonService.fileDelete(CommonService.java:29)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:299)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:139)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)

org.springframework.jdbc.BadSqlGrammarException: SqlMapClient operation; bad SQL grammar []; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:  
--- The error occurred in SqlMaps/StatBid.xml. 
--- The error occurred while applying a result map. 
--- Check the StatBid.getStatSR02List-AutoResultMap. 
--- Check the result mapping for the 'nation_name' property. 
--- Cause: java.sql.SQLException: S0022: 'nation_name'은(는) 잘못된 열 이름입니다.
com.ibatis.common.jdbc.exception.NestedSQLException:  
--- The error occurred in SqlMaps/StatBid.xml. 
--- The error occurred while applying a result map. 
--- Check the StatBid.getStatSR02List-AutoResultMap. 
--- Check the result mapping for the 'nation_name' property. 
--- Cause: java.sql.SQLException: S0022: 'nation_name'은(는) 잘못된 열 이름입니다.
 at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryWithCallback(MappedStatement.java:201)
 at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryForList(MappedStatement.java:139)
 at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:567)
 at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:541)
 at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:118)
 at org.springframework.orm.ibatis.SqlMapClientTemplate$3.doInSqlMapClient(SqlMapClientTemplate.java:231)
 at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:168)
 at org.springframework.orm.ibatis.SqlMapClientTemplate.executeWithListResult(SqlMapClientTemplate.java:190)
 at org.springframework.orm.ibatis.SqlMapClientTemplate.queryForList(SqlMapClientTemplate.java:229)
 at kr.or.icak.stat.bid.dao.StatBidDao.getStatSR02List(StatBidDao.java:29)
 at kr.or.icak.stat.bid.controller.StatBidController.getStatSR02List(StatBidController.java:139)
 at sun.reflect.GeneratedMethodAccessor62.invoke(Unknown Source)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at org.springframework.web.servlet.mvc.multiaction.MultiActionController.invokeNamedMethod(MultiActionController.java:393)
 at kr.or.icak.common.core.DefaultController.handleRequestInternal(DefaultController.java:33)
 at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
 at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:44)
 at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:723)
 at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:663)
 at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:394)
 at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:358)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:818)
 at jeus.servlet.engine.ServletWrapper.executeServlet(ServletWrapper.java:329)
 at jeus.servlet.filter.FilterChainImpl.internalDoFilter(FilterChainImpl.java:138)
 at jeus.servlet.filter.FilterChainImpl.doFilter(FilterChainImpl.java:90)
 at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:75)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:77)
 at jeus.servlet.filter.FilterChainImpl.internalDoFilter(FilterChainImpl.java:121)
 at jeus.servlet.filter.FilterChainImpl.doFilter(FilterChainImpl.java:90)
 at jeus.servlet.engine.ServletWrapper.execute(ServletWrapper.java:205)
 at jeus.servlet.engine.HttpRequestProcessor.run(HttpRequestProcessor.java:278)

해결하기 위해 구글링을 시작하였다.
역시나 다른 사람들 또한 이런문제로 고민을 했었다.

ibatis는 특정 id의 쿼리를 실행 한 후
해당 id의 쿼리를
캐쉬로 보관하고 있다가

동일한 id에 대한 요청시 캐쉬에 저장된 쿼리정보를 토대로 result값을 맵핑 시킨다고 한다.
(ibatis에서 제공하는 CacheModel과는 전혀무관한 얘기임)

이를 해결하기 위해선 remapResults="true" 속성을 추가해 주면 된다.
default가 remapResults="false" 이기때문에
항상 요청된 id와 동일한 게 캐쉬에 저장되어 있다면
캐쉬의 내용으로 맵핑하려 할것이고, 에러가 날것이다.

위 속성을 true로 지정하면
캐쉬의 내용을 무시하고 현재의 값을 가지고 맵핑시킴.

즉 아래와 같이 사용하면 된다.

<select id="fileInfo" remapResults="true"  resultClass="java.lang.String" parameterClass="java.util.Map">
    SELECT $columnName$
      FROM $tableName$
    WHERE $pkName$ = #pkValue#
</select>