2017-05-20 46 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(); 

注意,有在此查詢沒有佔位符,所以這是值得懷疑是否真的在使用PreparedStatement,而不是一個普通的老Statement任何優勢。

+0

那是一個SQL注入漏洞。在這裏插入口令表笑話<< –

+0

@TT簽名要求動態設置表名。有很多你可以用這些要求做的機器人。 – Mureinik

相關問題