Java에서 Oracle JDBC Driver를 사용해서 Oracle DB에있는 테이블에 SQL 문을 작성하는데 에러가 발생했다.
java.sql.SQLSyntaxErrorException: ORA-00933: SQL 명령어가 올바르게 종료되지 않았습니다.
String sql = "SELECT * FROM MEMBER WHERE ID = ? AND PWD = ?;";
try {
psmt = con.prepareStatement(sql);
psmt.setString(1, "hsyoodev");
psmt.setString(2, "1234");
rs = psmt.executeQuery();
if (rs.next()) {
member.setId(rs.getString(1));
member.setPwd(rs.getString(2));
member.setName(rs.getString(3));
member.setRegidate(rs.getDate(4));
}
} catch (Exception e) {
e.printStackTrace();
}
java.sql.SQLSyntaxErrorException: ORA-00911: 문자가 부적합합니다.
String sql = "SELECT COUNT(*) FROM BOARD WHERE ? LIKE %?%";
try {
psmt = con.prepareStatement(sql);
psmt.setString(1, "TITLE");
psmt.setString(2, "CONTENT");
rs = psmt.executeQuery();
rs.next();
boardCount = rs.getInt(1);
} catch (Exception e) {
e.printStackTrace();
}
String sql = "SELECT * FROM MEMBER WHERE ID = ? AND PWD = ?";
Oracle SQL Developer를 사용할 때 세미콜론으로 SQL 문들을 나누어 작성한 경험이 있어서 Java에서도 똑같이 작성했었다. 이게 문제가 되어버렸다... SQL 문법 상 세미콜론은 하나의 SQL 문을 종료하는 단위이다.
PreparedStatement는 SQL Injection 공격 방지를 위해 종료되지 않는 SQL 문을 미리 컴파일한후에 ?에 데이터를 바인딩하기 때문에 SQL 문에 세미콜론을 추가하게 되면 SQL 문을 미리 컴파일하는 과정에서 에러가 발생하는 것 같다.
String sql = "SELECT COUNT(*) FROM BOARD WHERE ? LIKE %?%";
try {
psmt = con.prepareStatement(sql);
psmt.setString(1, "TITLE");
psmt.setString(2, "CONTENT");
...생략
SELECT COUNT(*) FROM BOARD WHERE 'TITLE' LIKE %'지금은'%
String sql = "SELECT COUNT(*) FROM BOARD WHERE ? LIKE ?";
try {
psmt = con.prepareStatement(sql);
psmt.setString(1, "TITLE");
psmt.setString(2, "%" + "지금은" + "%");
...생략
2023.10.12 추가 작성
정확하지 않은 데이터 결과
String sql = "SELECT * FROM BOARD WHERE ? LIKE ?"; try { psmt = con.prepareStatement(sql); psmt.setString(1, "TITLE"); psmt.setString(2, "%" + "지금은" + "%"); ...생략
SELECT * FROM BOARD WHERE 'TITLE' LIKE '%지금은%';
?에 컬럼 명을 바인딩 데이터로 하면 값이 제대로 나오지 않는다.
해결방법
조건문을 활용한 문자열 연산
String sql = "SELECT * FROM BOARD WHERE"; if(조건) { sql += " 컬럼명"; } else { sql += " 컬럼명"; } sql += " LIKE ?"; try { psmt = con.prepareStatement(sql); psmt.setString(1, "%" + "지금은" + "%"); ...생략
SELECT * FROM BOARD WHERE TITLE LIKE '%지금은%';