原本我認為應該會合成這樣的一個SQL:
"SELECT id, name, color FROM animal where 1=1 and name='cat';"
But, 卻出現了錯誤。
嚴重: null org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1"
程式碼如下:
public static void main(String[] args) {
Connection conn;
String url = "jdbc:postgresql://localhost/demo?"
+ "user=postgres&password=abcd1234";
String sql = "SELECT id, name, color FROM animal where 1=1 ?;";
try {
//載入驅動器
Class.forName("org.postgresql.Driver");
//取得Connection(取得成功表示己與資料庫連上線)
conn = DriverManager.getConnection(url);
PreparedStatement st=conn.prepareStatement(sql);
st.setString(1, "and name='cat'");
//查詢資料(把查到的資料放進ResultSet)
ResultSet rs = st.executeQuery();
//讀取ResultSet中的資料
while (rs.next()) {
//id 是數值列態
System.out.print(rs.getInt("id") + "\t");
//name 及 color 是String型態
System.out.print(rs.getString("name") + "\t");
System.out.print(rs.getString("color") + "\n");
}
} catch (ClassNotFoundException e) {
System.exit(1);
} catch (SQLException ex) {
Logger.getLogger(DemoPreparedStatement.class.getName()).
log(Level.SEVERE, null, ex);
}
}
用Debug Mode看了一下合成出來的SQL:
SELECT id, name, color FROM animal where 1=1 'and name=''cat'''沒錯,它自動幫我再單引號的地方,再多加了一個單引號,並且在字串的前後也加上單引號,
因為在SQL語法中,2個單引號表示你要輸入的是一個單引號字元。這是它貼心的地方,
可以避免發生SQL Injection 。雖然這樣也會造成某使用上的些限制,
但PreparedStatement 對於只需替換參數的SQL語法有較好的效能。
以上是小弟在實作時遇到問題的經驗分享。
沒有留言:
張貼留言