当我使用以下代码时,它运行得很好。
PreparedStatement st = con.prepareStatement("select * from users where username=?");
st.setString(1, userId);
ResultSet rs = st.executeQuery();
但是当我使用以下代码时,我收到一个错误userId
(我作为参数传递)是一个无效的列名。
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select * from users where username="+userId);
为什么声明方法不起作用,我必须使用PreparedStatement
?
答案 0 :(得分:5)
用户ID是一个字符串(SQL调用此类型为CHAR或VARCHAR),如果在SQL请求中使用,则必须将其放在引号中。像这样:
select * from users where username='12345'
由于SQL injection,PreparedStatement是更好的解决方案。你不能只写:
ResultSet rs = st.executeQuery("select * from users where username=\""+userId+"\"");
WRONG CODE - ^^^^^^^^^^^^^^^
因为用户ID可以包含['],["]或[\]等控制字符。它取决于SQL服务器,有时比它看起来更复杂。如果使用PreparedStatement,它将由JDBC驱动程序自动管理。
答案 1 :(得分:1)
您需要将字符串放入引号:
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select * from users where username=\'"+userId+"\'");
注意:强> 您准备好的语句是处理SQL查询的首选方法。请参阅@ 30thh答案为何(SQL注入攻击)。
答案 2 :(得分:1)
首先,最好使用第一个。但如果你真的想要使用第二个,你需要将你的价值放在引号中。简单地将引号添加到值。但是如果要将它用作战利品,那么为它创建一个函数是很好的。像:
public String doubleQuoted(String value){
return "\"" + value + "\"";
}
或
public String singleQuoted(String value){
return "'" + value + "'";
}
并使用
ResultSet rs = st.executeQuery("select * from users where username="+singleQuoted(userId));