본문 바로가기

JAVA

오류 : MySql에서 NVL 사용

기존에 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를 붙여 별칭을 부여해서 특정할 수 있도록 해주면 해결된다.