【问题标题】:Value gets changed upon comiting. | CallableStatements提交时值会发生变化。 |可调用语句
【发布时间】:2010-12-29 01:00:53
【问题描述】:

我对 DAO 类和 StoredProcedure 有一个奇怪的问题,发生的事情是我使用了一个带有 15 个 IN 参数的 CallableStatement 对象,从 HTML 中正确检索了字段 id_color 的值它甚至在CallableStatement setter 方法中设置了它应该如何设置,但是当它被发送到数据库时,id_color 被值3 覆盖,这是“上下文”: 我有以下类DAO.CoverDAO 处理此表的CRUD 操作

CREATE TABLE `cover_details` ( `refno` int(10) unsigned NOT NULL AUTO_INCREMENT, `shape` tinyint(3) unsigned NOT NULL , `id_color` tinyint(3) unsigned NOT NULL ', `reversefold` bit(1) NOT NULL DEFAULT b'0' , `x` decimal(6,3) unsigned NOT NULL , `y` decimal(6,3) unsigned NOT NULL DEFAULT '0.000', `typecut` varchar(10) NOT NULL, `cornershape` varchar(20) NOT NULL, `z` decimal(6,3) unsigned DEFAULT '0.000' , `othercornerradius` decimal(6,3) unsigned DEFAULT '0.000'', `skirt` decimal(5,3) unsigned NOT NULL DEFAULT '7.000', `foamTaper` varchar(3) NOT NULL, `foamDensity` decimal(2,1) unsigned NOT NULL , `straplocation` char(1) NOT NULL ', `straplength` decimal(6,3) unsigned NOT NULL, `strapinset` decimal(6,3) unsigned NOT NULL, `spayear` varchar(20) DEFAULT 'Not Specified', `spamake` varchar(20) DEFAULT 'Not Specified', `spabrand` varchar(20) DEFAULT 'Not Specified', PRIMARY KEY (`refno`) ) ENGINE=MyISAM AUTO_INCREMENT=143 DEFAULT CHARSET=latin1 $$

封面的插入方式是通过一个存储过程,如下:


CREATE DEFINER=`root`@`%` PROCEDURE `putCover`(
                                    IN shape TINYINT,
                                    IN color TINYINT,
                                    IN reverse_fold BIT,
                                    IN x DECIMAL(6,3), 
                                    IN y DECIMAL(6,3),
                                    IN type_cut VARCHAR(10),
                                    IN corner_shape VARCHAR(10),
                                    IN cutsize DECIMAL(6,3),
                                    IN corner_radius DECIMAL(6,3),
                                    IN skirt DECIMAL(5,3),
                                    IN foam_taper VARCHAR(7),
                                    IN foam_density DECIMAL(2,1),
                                    IN strap_location CHAR(1),
                                    IN strap_length DECIMAL(6,3),
                                    IN strap_inset DECIMAL(6,3)
                                    )
BEGIN
    INSERT INTO `dbre`.`cover_details` 
    (`dbre`.`cover_details`.`shape`,
     `dbre`.`cover_details`.`id_color`,
     `dbre`.`cover_details`.`reversefold`,
     `dbre`.`cover_details`.`x`,
     `dbre`.`cover_details`.`y`,
     `dbre`.`cover_details`.`typecut`,
     `dbre`.`cover_details`.`cornershape`,
     `dbre`.`cover_details`.`z`,
     `dbre`.`cover_details`.`othercornerradius`,
     `dbre`.`cover_details`.`skirt`,
     `dbre`.`cover_details`.`foamTaper`,
     `dbre`.`cover_details`.`foamDensity`,
     `dbre`.`cover_details`.`strapLocation`,
     `dbre`.`cover_details`.`strapInset`,
     `dbre`.`cover_details`.`strapLength`
     )
    VALUES
    (shape,color,reverse_fold,
     x,y,type_cut,corner_shape,
     cutsize,corner_radius,skirt,foam_taper,foam_density,
     strap_location,strap_inset,strap_length);
END

你可以看到基本上它只是填充每个字段,现在,创建封面的 CoverDAO.create(CoverDTO cover) 方法是这样的:


public void create(CoverDTO cover) throws DAOException {
        Connection link = null;
        CallableStatement query = null;
        try {
            link = MySQL.getConnection();
            link.setAutoCommit(false);
            query = link.prepareCall(
                "{CALL putCover(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}"
                                    );
            query.setByte(1,cover.getShape().byteValue());
            query.setByte(2,cover.getColor().byteValue());
            query.setBoolean(3, cover.getReverseFold());
            query.setBigDecimal(4,cover.getX());
            query.setBigDecimal(5,cover.getY());
            query.setString(6,cover.getTypeCut());
            query.setString(7,cover.getCornerShape());
            query.setBigDecimal(8, cover.getZ());
            query.setBigDecimal(9, cover.getCornerRadius());
            query.setBigDecimal(10, cover.getSkirt());
            query.setString(11, cover.getFoamTaper());
            query.setBigDecimal(12, cover.getFoamDensity());
            query.setString(13, cover.getStrapLocation());
            query.setBigDecimal(14, cover.getStrapLength());
            query.setBigDecimal(15, cover.getStrapInset());
            query.executeUpdate();
            link.commit();
        } catch (SQLException e) {
            throw new DAOException(e);
        } finally {
            close(link, query);
        }
    }

CoverDTO 由 accessesor 方法组成,MySQL 对象基本上从池中返回连接。

以下是 pset 查询,其中包含虚拟但适当的数据: putCover(1,10,0,80.0,80.0,'F','Cut',0.0,0,15.0,'4x2',1.5,'A',10.0,5.0)(删除了一些尾随零) 正如您所看到的,当我在第二个参数中写入数据库而不是10 时,一切都很好,写入了3。我做了以下事情:

  • id_color 值跟踪到create 方法,仍然被替换为3
  • 在 DAO 创建方法中对值进行硬编码,仍然被替换为 3
  • 从 MySQL Workbench 调用该过程,它工作正常,所以我认为 create 方法中发生了一些事情,非常感谢任何帮助。
  • 【问题讨论】:

    • 你在哪里“硬编码DAO创建方法中的值”,你试过query.setInt(2,10);吗?
    • 应该query.setInt(2,cover.getColor())query.setByte(2,cover.getColor())
    • 有没有用过?你确定 DAO 和表定义一致吗?
    • @The Scrum Meister,是的,我试过了,仍然被 3 取代。
    • @Tony Ennis:是的,两者一致,这意味着程序处理适当的字段。

    标签: java mysql jdbc callable


    【解决方案1】:

    存储过程声明有误:

    IN color TINYINT(3)
    

    改成:

    IN color TINYINT
    

    希望它会起作用。

    【讨论】:

    • @ShahidAzim:你能详细说明一下吗? “显示宽度不限制列中可以存储的值的范围。”—dev.mysql.com/doc/refman/5.0/en/numeric-types.html
    • 它不应该工作,但在这种情况下它的行为是这样的。最好等待@Triztian 回复。
    • @ShahidAzim:我已经尝试过了,但讨厌的 3 仍然进入数据库。
    • 您还可以包含来自@trashgod 的建议,只要让代码更一致,调试起来就会更容易。例如,这两行更新相同的类型 (TINYINT) 但使用不同的方法 query.setLong(1,cover.getShape()); query.setByte(2,cover.getColor().byteValue());
    • 改了,没区别,我什至尝试删除byteValue()方法并使用包装类(java.lang.Byte)。
    【解决方案2】:

    鉴于shape tinyint(3)id_color tinyint(3) 的属性定义,我很惊讶地看到PROCEDURE putCover() 分别具有形式参数IN shape TINYINTIN color TINYINT(3)。此外,我希望create() 相应地使用setByte()

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-16
    • 2016-12-14
    • 2011-07-05
    • 2021-10-21
    相关资源
    最近更新 更多