Database/Oracle

java.sql.SQLException: ORA-01008: 일부 변수가 바인드되지 않았습니다.

FreeEnd 2011. 6. 14. 16:17
반응형


문제발생!!

아직 학생인 후배의 다급한 요청!!
DAO 를 만드는 중인듯한데.. 쿼리를 execute 시키면 에러가 난다는..

완전 초보시란다.
뭐 여튼.

다짜고짜 소스 먼저 보내줘서 대충 살펴 보았다.

쿼리도 잘 만들었고..
바인드도 잘 해줬구...

코드상 문제가 없는듯 했는데...

일단 에러 트래백을 먼저 보내달라고했다.



원인탐색

java.sql.SQLException: ORA-01008: 일부 변수가 바인드되지 않았습니다.

insert into member(pass_subno,s_no,sub_no)values(?,?,?)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:745)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:216)
at racle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:966)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1170)
at oracle.jdbc.driver.OracleStatement.executeInternal(OracleStatement.java:1696)
at oracle.jdbc.driver.OracleStatement.execute(OracleStatement.java:1662)
at StatusDao.getPsub(StatusDao.java:59)
at Status.pdbSelect(Status.java:199)
at Status.mouseClicked(Status.java:213)
... 중략...
 


뭐 여튼 이런 에러였다.

에러가 나는 부분을 다시 보니..

String sql = "insert into member(pass_subno,s_no,sub_no)"
+ "values(?,?,?)";
try {
ps = con.prepareStatement(sql);
ps.setString(1, ps_no);
ps.setInt(2, s_no);
ps.setString(3, sub_no);
ps.execute(sql);
}catch
... 중략 ..

 

 


아하!

 PreparedStatement에 쿼리도 잘 넣어주고 변수를 잘 세팅 해서 넣어줬으면서, 쿼리 실행시에는 ?에 바인드를 하지 않은 sql을 넣어 execute 시켜버렸다.

(첨언하자면 ps.execute(sql); 은 sql 문을 수행하는거고, executeUpdate() 는 prepareStatement(sql) 로 지정한 sql 에 ps.setxxx 로 각 ? 를 바인딩한 쿼리를 수행 하는것이다. 2022/06/28)

그래서 친절하게 일부 변수가 바인드 되지 않았다고 에러를 출력했던 것이다.


해결
 ps.execute(sql); ps.executeUpdate(); 로 바꾸어서 해결!!


참고
 뭐 간단한 문법 실수이다. 초급 개발자라면 당연히 이런 문제를 겪을수 있지만 중급 이상의 개발자라면 이러시면 곤란하시죠. 푸훗.
 근데 왜 포스팅 하냐구? 갑자기 executeQuery()executeUpdate()랑 차이가 궁금해졌거든.

 저 둘의 차이는 리턴 타입을 보면 잘 알 수 있다.
다음은 해당 메소드의 javadoc의 내용이다.

ResultSet executeQuery() throws SQLException;
Executes the SQL query in this PreparedStatement object and returns the ResultSet object generated by the query.
return a ResultSet object that contains the data produced by the query; never null

int executeUpdate() throws SQLException;
Executes the SQL statement in this PreparedStatement object, which must be an SQL INSERT, UPDATE or DELETE statement; or an SQL statement that returns nothing, such as a DDL statement.
either (1) the row count for INSERT, UPDATE, or DELETE statements
or (2) 0 for SQL statements that return nothing


내용에서도 알수 있듯이 ..
executeQuery() 는 Query의 결과 오브젝트를 만들어 리턴을 해주고
executeUpdate() 는 Insert, Update, Delete등의 Query를 실행시키고 해당 결과의 row count를 리턴한다.

 INSERT, UPDATE, DELETE는 자칫 그냥 executeQuery() 로도 시행 시킬 수 있다.  하지만 정확한 데이터 처리를 위해 해당 알맞은 메소드 사용과 결과 처리를 한다면 더 나은 세상을 만드는데 기여 할 수 있을 것으로 기대 된당. 우후훗. 지영옹.


반응형