2017-05-20 6 views
1

그래서 난 그냥 잘 작동이 다음과 같은 방법이 있습니다SELECT COUNT 쿼리에서 테이블 이름을 Prepared Statement로 전달하는 방법은 무엇입니까?

static void getCount(final String url, final String username, final String password) throws SQLException { 
    final Connection connection = DriverManager.getConnection(url, username, password); 

    final String query = "SELECT COUNT(*) FROM app_user"; 
    final PreparedStatement preparedStatement = connection.prepareStatement(query); 
    final ResultSet resultSet = preparedStatement.executeQuery(); 

    resultSet.next(); 
    System.out.println(resultSet.getInt(1)); 

    resultSet.close(); 
    preparedStatement.close(); 
    connection.close(); 
} 

을하지만, 내가하려고하면

static void foobar(final String url, final String username, final String password, final String tablename) throws SQLException { 
    final Connection connection = DriverManager.getConnection(url, username, password); 

    final String query = "SELECT COUNT(*) FROM ? "; 
    final PreparedStatement preparedStatement = connection.prepareStatement(query); 
    preparedStatement.setString(1, tablename); 
    final ResultSet resultSet = preparedStatement.executeQuery(); 

    resultSet.next(); 
    System.out.println(resultSet.getInt(1)); 

    resultSet.close(); 
    preparedStatement.close(); 
    connection.close(); 
} 

를 내가 얻을 : 내가 잘못 뭐하는 거지

Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''app_user'' at line 1 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526) 

?

답변

1

구문 요소 나 개체 이름 (이 경우 테이블 이름)이 아닌 PreparedStatement의 값만 바인딩 할 수 있습니다. 이 쿼리에는 자리가 없음을

final String query = String.format("SELECT COUNT(*) FROM %s", tablename); 
final PreparedStatement preparedStatement = connection.prepareStatement(query); 
final ResultSet resultSet = preparedStatement.executeQuery(); 

참고, 그래서 정말 평범한 구식 Statement 대조적으로 PreparedStatement를 사용하여 어떤 이점이 있는지 여부 의문이다 : 당신은 문자열 조작에 의존해야합니다.

+0

바로 SQL 인젝션 취약점입니다. 삽입 바비 테이블 농담 << –

+0

@TT 서명은 동적으로 테이블 이름을 설정해야합니다. 이러한 요구 사항으로 수행 할 수있는 많은 기능이 있습니다. – Mureinik