기존에 H2를 사용하던 프로젝트를 Mysql Database로 변경하면서 몇가지 오류가 발생했다.
NVL 오류도 그 중 하나인데 NVL은 H2와 Oracle에서 사용하지만 Mysql에서는 사용할 수 없기 때문이다.
Mysql에서는 NVL 대신 IFNULL 을 사용한다.
Mysql에서 NVL 사용시 발생하는 오류 :
Message:
### Error updating database.
Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
FUNCTION board.NVL does not exist
### The error may involve BoardDAO.insertBoard-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO BOARD(SEQ, TITLE, WRITER, CONTENT) VALUES((SELECT NVL(MAX(SEQ), 0)+1 FROM BOARD), ?, ?, ?)
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
FUNCTION board.NVL does not exist ;
bad SQL grammar []; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
FUNCTION board.NVL does not exist
오류가 발생한 코드의 원문은 아래와 같다.
<insert id="insertBoard" parameterType="board">
<![CDATA[
INSERT INTO BOARD(SEQ, TITLE, WRITER, CONTENT)
VALUES((SELECT NVL(MAX(SEQ), 0)+1 FROM BOARD), #{title}, #{writer}, #{content})
]]>
여기서 NVL 을 IFNULL으로 수정해서 만약 NULL 값일 경우도 제대로 작동하도록 수정해준다.
하지만 그래도 아래와 같은 오류가 발생할 수 있다.
Message:
### Error updating database.
Cause: java.sql.SQLException:
You can't specify target table 'BOARD' for update in FROM clause
### The error may involve BoardDAO.insertBoard-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO BOARD(SEQ, TITLE, WRITER, CONTENT) VALUES((SELECT IFNULL(MAX(SEQ), 0)+1 FROM BOARD), ?, ?, ?)
### Cause: java.sql.SQLException:
You can't specify target table 'BOARD' for update in FROM clause ;
uncategorized SQLException for SQL []; SQL state [HY000]; error code [1093];
You can't specify target table 'BOARD' for update in FROM clause;
nested exception is java.sql.SQLException:
You can't specify target table 'BOARD' for update in FROM clause
오류 메세지를 읽어보면 SQL문의 BOARD를 특정하지 못해 오류가 발생한다는 것을 알 수 있다.
<insert id="insertBoard" parameterType="board">
<![CDATA[
INSERT INTO BOARD(SEQ, TITLE, WRITER, CONTENT)
VALUES((SELECT IFNULL(MAX(SEQ), 0)+1 FROM BOARD B), #{title}, #{writer}, #{content})
]]>
이처럼 서브 쿼리 내부의 BOARD 테이블에 B를 붙여 별칭을 부여해서 특정할 수 있도록 해주면 해결된다.