【问题标题】:How to give entry in the where clause when we use it in webpages?当我们在网页中使用 where 子句时,如何在 where 子句中输入?
【发布时间】:2010-10-08 18:45:03
【问题描述】:

根据用户的输入,我想从数据库中选择记录。这是我的代码:

<%
String jempid=request.getParameter("empid");
out.println(jempid);
int intempid=1223;
Connection conn=null;
String url="jdbc:mysql://localhost/employees";
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn=DriverManager.getConnection(url,"root","");
Statement st=conn.createStatement();
ResultSet rs=st.executeQuery("select * from empdetails where empnum=jempid");
%>

它会抛出以下错误

javax.servlet.ServletException: java.sql.SQLException: 'where 子句中的未知列'jempid'

【问题讨论】:

  • 嘿嘿..没有代码是完美的代码。

标签: sql html database jsp


【解决方案1】:

是的,有时它会引发未知列的错误,例如我们有台式自行车

假设我们有一个类似 select * from bikes where bikename=hayabusa;

的查询

如果您点击此查询,它可能会引发类似未知列的错误,因此您应该注意的最好的事情是引用您在 where 子句中给出的值,因此正确的方法是select * from bikename='hayabusa';

【讨论】:

    【解决方案2】:

    where 应该在" " 内输入。像这样:

    "select * from empdetails where empnum = "jempid";
    

    因此这应该有效:

    ResultSet rs = st.executeQuery("select * from empdetails where empnum=" +"'"+ jempid+"'");
    

    【讨论】:

      【解决方案3】:

      与其他响应相比,为什么不使用 PreparedStatement?

      基本上,您必须像这样编写代码:

      PreparedStatement st=conn.prepareStatement("select * from empdetails where empnum=?");
      st.setString(1, jempId);
      ResultSet rs=st.executeQuery();
      

      您应该使用 PreparedStatements 的原因是因为 SQL Injection 问题。例如,使用您在问题中发布的代码,黑客始终可以在您选择 jempid 的文本框中输入“1;delete * from empdetails”。

      因此形成的最终查询将是

      select * from empdetails where empnum=1;delete * from empdetails
      

      这将导致empdetails中的所有数据都被删除。

      所以总是使用 PreparedStatements!!

      【讨论】:

        【解决方案4】:

        使用字符串连接构造 SQL 是个坏主意——你只是让自己面临 SQL 注入攻击——特别是考虑到你直接从请求中获取“empid”的值。哎呀!

        更好的方法是使用参数化查询,如下所示:

        PreparedStatement st=conn.prepareStatement("select * from empdetails where empnum=?");
        st.setString(1, jempid);
        ResultSet rs=st.executeQuery();
        

        您还应该检查 jempid 是否不为空。

        【讨论】:

        • 很好地涵盖所有情况,但这里唯一的问题是他忘记将 jempID 设为变量。如此多的努力可能会使编写原始代码的人更加困惑。
        • @Chris,对 - 但其他来到这里的开发人员总是可以学习其他方法。
        • 如果有人问你“嘿——为什么我不能射自己的脚?” ——你是把枪上膛还是从他们手里拿走?
        • 好吧,这可能是一个不好的类比,但@Shivasubramanian 基本上是这样说的——如果有人正在阅读此页面以复制/粘贴代码或(希望)学习,我宁愿让他们以正确的方式学习构造 SQL 而不仅仅是连接字符串。
        【解决方案5】:

        看起来jsp页面中的代码太多了...... 说:

        ... empnum='"+jempid+"');" ......
        

        完成后一定要关闭数据库

        【讨论】:

        • 是的,@rbobby,但与问题无关。
        【解决方案6】:

        这是您的选择语句:

        select * from empdetails where empnum=jempid
        

        jempid 是硬编码的,而不是用作变量。除非您将其更改为客户输入的变量值,否则这永远不会起作用。

        改为:

        "select * from empdetails where empnum=" + CleanseUserInput(jempid)
        

        你可以走了。

        【讨论】:

        • 这是一个很好的例子,为什么你不应该在答案中涵盖所有内容,@rbobby。如果 jempid 是一个字符串呢?那将需要引号。最好回答手头的问题,而不是试图涵盖所有基础。
        • @Pax,说得好,但开发人员在允许 sql 注入攻击方面是出了名的糟糕。
        • 仍然,我的答案是一个(我不喜欢那些新奇的高falutin'参数化查询:-),所以为你+1。
        【解决方案7】:
        "select * from empdetails where empnum="+jempid
        

        但您确实想保护它免受 SQL 注入!

        【讨论】:

          【解决方案8】:
          ResultSet 
            rs=st.executeQuery("select * from empdetails where empnum=" + jempid + ";")
          

          【讨论】:

            【解决方案9】:

            试试这个:

            ResultSet rs=st.executeQuery(
                "select * from empdetails where empnum=" + jempid);
            

            您需要将 jempid 的 value 放入字符串,而不是 text "jempid"。

            【讨论】:

            • 是的,@rbobby,但与手头的问题并不真正相关。我们都知道您不应该允许注入攻击,但是,如果您想涵盖答案“错误”的所有方式,那么它们最终都会成为 10,000 字的论文。
            • 您可以简单地说我们应该删除不必要的代码,例如“int intempid=1223;” :-)
            猜你喜欢
            • 1970-01-01
            • 2016-03-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-04-14
            相关资源
            最近更新 更多