首页 > 解决方案 > Java & MySQL - setBoolean() 方法出错

问题描述

我收到错误消息:“列数与第 1 行的值计数不匹配”,但我已经计算过了,并且列数正确,我觉得错误出在 setBoolean() 方法上。我有 8 列,您会看到我在方法中传递了 7 个参数,因为其中一列是 AUTO_INCREMENTE。如果我不使用 setBoolean 方法将其替换为 setString、setInt 或其他任何东西,我的编码工作得非常好,但当我使用 setBoolean() 时则不然。

这是我的代码,我希望它能让我的问题更清楚:

我的 Java 中有一个自动代码,如果它不存在,它会创建数据库及其各自的表:

DB.createDB("userSecInfo");
DB.createTable("accountInfo", "userSecInfo", "("+
                                              "Username VARCHAR(40) NOT NULL, "+
                                              "Pass VARCHAR(40) NOT NULL, "+
                                              "chkPwChange BOOLEAN NOT NULL DEFAULT FALSE, "+
                                              "chkPwCntChange BOOLEAN NOT NULL DEFAULT FALSE, "+
                                              "chkPwNoExpires BOOLEAN NOT NULL DEFAULT FALSE, "+
                                              "chkPwExpires BOOLEAN NOT NULL DEFAULT FALSE, "+
                                              "expirydays INT, "+
                                              "UserID INT NOT NULL AUTO_INCREMENT, "+
                                              "PRIMARY KEY (UserID))");

我尝试以不同的方式为 MySQL 定义所有布尔变量,例如 BOOL,也可以是 BOOLEAN(如上)和 TINYINT & TINYINT(1); 但变量定义似乎不是问题。

然后程序,一旦它创建了数据库和表,它会继续提取用户输入的信息并将其插入到数据库中:

DB.insertUserSecAccountInfo("userSecInfo", "accountInfo", tFUsername.getText(),
                                            String.copyValueOf(pFPassword.getPassword()), chckbxUserMustChange.isSelected(), 
                                            chckbxUserCannotChange.isSelected(), chckbxPasswordNeverExpires.isSelected(), 
                                            chckbxPasswordExpiresAnd.isSelected(), Integer.parseInt(tFdays.getText()));

insertUserSecAccountInfo 方法如下:

public void insertUserSecAccountInfo(String db_name,String table_name, String Username, String Pass,
             boolean chkPwChange,  boolean chkPwCntChange, boolean chkPwNoExpires,boolean chkPwExpires,
             int expirydays) throws Exception {
            try {
                openConnection("whatever","password",db_name);
                String Query ="INSERT into "+ table_name +" values(?,?,?,?,?,?,?)";
                ps = Conexion.prepareStatement(Query);
                ps.setString(1, Username);              
                ps.setString(2, Pass);
                ps.setBoolean(3, chkPwChange);              
                ps.setBoolean(4, chkPwCntChange);       
                ps.setBoolean(5, chkPwNoExpires);   
                ps.setBoolean(6, chkPwExpires);
                ps.setInt(7, expirydays);
                ps.executeUpdate();
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(null, "Error saving data"));
                ex.printStackTrace();
            } finally {
                closeConnection();
            }
        }

当我运行它时,它向我显示错误:“列计数与第 1 行的值计数不匹配”。但后来我直接在 MySQL 中运行基本相同的行,如下所示,它插入它非常好:

insert into accountInfo(Username,Pass,chkPwChange,chkPwCntChange,chkPwNoExpires,chkPwExpires,expirydays) values ('Hola','No',true,true,true,true,56);

所以这让我觉得 setBoolean() 方法有问题,它可能没有正确地将布尔变量从 Java 映射或传递到 MySQL;有没有人有类似的问题?我非常感谢任何有关这方面的指导。

先感谢您。

标签: javamysqljdbc

解决方案


因为您没有明确命名每一列,所以所有列的隐式默认值都适用。其中一个具有默认值的事实是无关紧要的(并且自动计数不超过也不少于以下脚本:“制作一个序列,现在将此列的默认值设置为NEXTVAL(nameOfGeneratedSequence))。

这与 . 无关setBoolean

正如一些评论者所说,您需要始终明确命名您正在设置的列,因此:`INSERT INTO " + tableName + " (Username, Pass, etc) VALUES (?,?,... etc)" .

安全注意事项:在数据库中以纯文本形式存储密码不符合最低安全最佳实践。如果像这样部署并且它曾经泄漏,您可能会收到巨额罚款或更糟(在欧洲通过 GDPR;其他司法管辖区通常有类似的立法),更不用说很多当之无愧的媒体后果。不要这样做。– 使用 bcrypt 并存储哈希值。


推荐阅读