SQL 错误列计数与第 1 行的值计数不匹配

Posted

技术标签:

【中文标题】SQL 错误列计数与第 1 行的值计数不匹配【英文标题】:SQL error Column count doesn't match value count at row 1 【发布时间】:2020-02-16 18:32:02 【问题描述】:

我是否遗漏了以下错误,以将以下内容插入到具有四列 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 中,而不是在表示层中硬编码连接字符串 【参考方案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 重要得多。 是的,这值得告诉他。

以上是关于SQL 错误列计数与第 1 行的值计数不匹配的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 抛出“java.sql.SQLException:列计数与第 1 行的值计数不匹配”[重复]

列计数与第 1 行的值计数不匹配 VendorError:1136

Codeigniter 模型出现错误:列计数与第 2 行的值计数不匹配

java.sql.SQLException:列计数与第 1 行的值计数不匹配,并且我的数据库的第 1 列是自动记录的

PHP ~ 列数与第 1 行的值数不匹配

错误代码:1136。列数与第 1 行的值计数不匹配,我找不到错误