2015-10-16 89 views
-1

当我使用下面的代码时,它完美运行。在createStatement中获取错误

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

我想与您的查询,你需要用'单引号和双引号userID' ......像'” '用户ID'“'。但说实话,你最好使用第一个查询 – ryekayo

+0

尝试像这样'ResultSet rs = st.executeQuery(“select * from users where username ='”+ userId +“'”);''但PreparedStatement'优先。 – drgPP

回答

5

用户标识是一个字符串(SQL调用此类型为CHAR或VARCHAR),如果在SQL请求中使用它,则必须将其放入引号中。就像这样:

select * from users where username='12345' 

的PreparedStatement是因为SQL injection的更好的解决方案。你不能只是写:

ResultSet rs = st.executeQuery("select * from users where username=\""+userId+"\""); 
                 WRONG CODE - ^^^^^^^^^^^^^^^ 

,因为用户的ID可以包含如[“],[”]或[\]这取决于SQL服务器上,有时甚至是更复杂的比它看起来像如果使用控制字符。 PreparedStatement的,它会自动通过JDBC驱动程序管理

1

你需要把字符串转换为报价:。

Statement st = con.createStatement(); 
ResultSet rs = st.executeQuery("select * from users where username=\'"+userId+"\'"); 

\escape character

注意: 您准备好的语句是处理SQL查询的首选方式。请参阅@ 30thh回答为什么(SQL注入攻击)。

+0

通常,在数据库中,字符串用单引号表示,而不是用双引号表示,因此您的查询是错误的。 – drgPP

+0

@drgPP谢谢,我会编辑答案。 – showp1984

+0

@Pshemo我刚刚告诉这个问题的作者为什么他的代码失败了,我不会就额外的安全问题提供建议。特别是因为他在他的问题中已经有了一个准备好的陈述,显然也是有效的。不过,我会把这个问题加在我的答案上。 – showp1984

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)); 
+0

是的。这就是为什么使用第一个选项更好。但他没有说为什么他想用第二个而不是第一个。 – augustoccesar

+0

那就好。咖啡时间! – augustoccesar