为什么我的JDBC更新不起作用?

时间:2013-10-23 13:16:44

标签: java oracle jdbc

我一直在从PostgreSQL 9.1迁移到Oracle 11gR2,并遇到了一个奇怪的问题。

当客户已添加到我们的ERP系统时,我一直在运行更新表格的代码。自3月以来,此代码一直在PostgreSQL上运行,没有任何问题。现在我正在切换到Oracle,相同的代码不再更新。

原始代码

update = "UPDATE store SET added_customer = 'y' WHERE order_id = ?";
try {
    PreparedStatement pStmnt = getConn().prepareStatement(update);
    pStmnt.setString(1, orderId);               
    results = pStmnt.executeUpdate();

    if (results > 0) {
        added = true;                   
    }       
} catch (SQLException ex) {
    LOGGER.error(ex.toString());
}

没有抛出任何异常,但没有数据发生变化,所以我认为“自动提交一定不能正常工作,让我们手动提交”:

新代码

update = "UPDATE shop_ca_orders SET added_customer = 'y' WHERE order_id = ?";
try {                 
    getConn().setAutoCommit(false); //Added
    PreparedStatement pStmnt = getConn().prepareStatement(update);
    pStmnt.setString(1, orderId);               
    results = pStmnt.executeUpdate();

    if (results > 0) {
        added = true;
        getConn().commit(); //Added
        getConn().setAutoCommit(true); //Added
    }       
} catch (SQLException ex) {
    LOGGER.error(ex.toString());
}

仍然没有运气,所以我在LOGGER.debug("Update to order returned {}",results);语句后添加了executeUpdate,发现我返回0,所以没有记录正在更新。

有趣,所以我通过SQL Developer尝试了查询并正确更新了。这让我想到了我的问题:

为什么我无法通过JDBC更新数据库?

基本数据:

  • order_idVARCHAR(255 BYTE)类型。
  • Java 7
  • 在Amazons RDS上运行的Oracle 11GR2
  • 从Heroku上运行的PostgreSQL 9.1迁移
  • On PostgreSQL order_idcharacter varying(255)

修改

未检测到小的架构更改,导致订单ID实际上是人员名称的错误,而不是订单ID。我头上的笨蛋错误。无论如何,现在我已经解决并提取正确的订单ID我发现我挂在executeUpdate上。目前正在处理该问题。如果我无法解决,我可能会创建一个新问题。

3 个答案:

答案 0 :(得分:1)

getConn()返回什么?我怀疑每次都是不同的(汇集?)连接。

此:

getConn().setAutoCommit(false); //Added
PreparedStatement pStmnt = getConn().prepareStatement(update);

应该可读:

Connection c = getConn();
c.setAutoCommit(false); //Added
PreparedStatement pStmnt = c.prepareStatement(update);

即。如果getConn()每次都返回不同的连接,那么你就会遇到问题。

答案 1 :(得分:1)

所以我的问题有两个方面:

首先我的初始结果集存在问题。在迁移过程中删除了一列,我认为所有引用的列都在代码中更改,但是缺少一列。解决此问题后,订单ID准确工作,并尝试更新数据库。

第二个问题是数据库挂在更新上的问题。事实证明,挂起是由SQL Developer对数据库(或表,不确定是哪个)进行锁定引起的 - 一旦我关闭SQL Developer,更新立即完成并且事情按预期进行。

答案 2 :(得分:0)

几年前我经历过这个问题,当我在WHERE子句上使用String值时,使用令牌,它没有用。顺便说一下,它也是一个Oracle数据库(10g)

最后,我放弃了,并更改了代码以连接值而不是将其标记为

update = "UPDATE shop_ca_orders SET added_customer = 'y' WHERE order_id = ?";
try {                 
    getConn().setAutoCommit(false); //Added
    PreparedStatement pStmnt = getConn().prepareStatement(update);
    pStmnt.setString(1, orderId);               
    results = pStmnt.executeUpdate();

    if (results > 0) {
        added = true;
        getConn().commit(); //Added
        getConn().setAutoCommit(true); //Added
    }       
} catch (SQLException ex) {
    LOGGER.error(ex.toString());
}

update = "UPDATE shop_ca_orders SET added_customer = 'y' WHERE order_id = ' + order_id + '";
try {                 
    getConn().setAutoCommit(false); //Added
    PreparedStatement pStmnt = getConn().prepareStatement(update);
    results = pStmnt.executeUpdate();

    if (results > 0) {
        added = true;
        getConn().commit(); //Added
        getConn().setAutoCommit(true); //Added
    }       
} catch (SQLException ex) {
    LOGGER.error(ex.toString());
}

这对我有用......这不是最优雅的解决方案,但是是一种解决方法

======================更新1 ======================= =====

我做了一些研究,因为我也遇到了这个问题但仍未得到有效答案

看起来Oracle驱动程序希望您传递一个长度与表定义类似的String。这只发生在固定长度的列(如CHAR)上,VARCHAR列似乎不受此影响。

这意味着,如果order_id是CHAR(10),那么您应填充String以完成列长度。更好的方法是修剪数据库值以匹配标记值。

update = "UPDATE shop_ca_orders SET added_customer = 'y' " + 
         " WHERE LTRIM(RTRIM(order_id)) = ?";
try {                 
    getConn().setAutoCommit(false); //Added
    PreparedStatement pStmnt = getConn().prepareStatement(update);
    pStmnt.setString(1, orderId);               
    results = pStmnt.executeUpdate();

    if (results > 0) {
        added = true;
        getConn().commit(); //Added
        getConn().setAutoCommit(true); //Added
    }       
} catch (SQLException ex) {
    LOGGER.error(ex.toString());
}