【问题标题】:SQL error Column count doesn't match value count at row 1SQL 错误列计数与第 1 行的值计数不匹配
【发布时间】:2023-04-05 19:16:01
【问题描述】:

我是否遗漏了以下错误,以将以下内容插入到具有四列 message_id(自动递增)message_sender、message_reciever、message_body 的表中。我检查了类似的问题,但没有找到解决方案。 '''

        <% String sender_id = request.getParameter("message_sender");
        String reciever_id = request.getParameter("message_reciever");
        String message = request.getParameter("message_body");

        try{
        Class.forName("com.mysql.jdbc.Driver");
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/fyp", "root", "Kmd116352323!");
        Statement st = con.createStatement();

        st.executeUpdate("INSERT INTO messages(message_sender,message_reciever,message_body) VALUES('"+sender_id+", "+reciever_id+" , "+message+" ')");

        out.println("Your request has been noted."
                + " Please return to your user profile or log out");

        } catch(Exception e){
        out.println(e);
                }
        %>

【问题讨论】:

  • 您使用了一个名为receiver_id 类型为String 的变量,但该名称暗示了一个数字标识符...脱离上下文,但很有用:使用PreparedStatement 以避免SQL 注入
  • learn to properly use a PreparedStament。不要将用户输入连接到 SQL 字符串中。如果你这样做,你的问题很可能也会消失
  • 与您的问题无关,但该代码不应位于 JSP 中,而应位于使用连接池的 servlet 中,而不是在表示层中硬编码连接字符串

标签: sql jsp jdbc


【解决方案1】:

您不应将值连接到查询字符串中。它使您的代码容易受到 SQL 注入或忘记值引号等错误的影响。您的具体问题是,您在第一个值之前有一个引号,在最后一个值之后有一个引号,这使其成为单个值而不是三个单独的值。

但是,您应该改用准备好的语句,而不是通过添加那些缺少的引号来解决眼前的问题:

try (PreparedStatement pstmt = connection.prepareStatement(
        "INSERT INTO messages(message_sender,message_reciever,message_body) VALUES(?, ?, ?)") {
    pstmt.setString(1, sender_id);
    pstmt.setString(2, reciever_id);
    pstmt.setString(3, message);

    pstmt.executeUpdate();
}

顺便说一句,您真的不应该将数据访问放在 JSP 中。它属于 DAO 或服务类。

【讨论】:

    【解决方案2】:

    这是不正确的:

    VALUES('"+sender_id+", "+reciever_id+" , "+message+" ')
    

    您有一个 ' 包装所有值...这意味着 sql 会认为您只发送 1 个值。如果它们都是文本值,它应该是这样的:

    VALUES('"+sender_id+"', '"+reciever_id+"' , '"+message+"')
    

    如果您知道某些值是 INT 类型,那么您不需要为该值使用 '

    VALUES("+sender_id+", "+reciever_id+" , '"+message+"')
    

    文本值需要用'包装

    【讨论】:

    • 更好的解决方案是使用准备好的语句。
    • @MarkRotteveel 绝对。但是一步一步……他也不应该通过scriptlet来做这件事。
    • 没错,但是,我认为教育人们不要使用串联的查询字符串很重要,这样做的安全隐患比使用或不使用 scriptlet 重要得多。
    • 是的,这值得告诉他。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    • 2021-10-17
    • 1970-01-01
    相关资源
    最近更新 更多