我一直在从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_id
是VARCHAR(255 BYTE)
类型。 order_id
是character varying(255)
修改
未检测到小的架构更改,导致订单ID实际上是人员名称的错误,而不是订单ID。我头上的笨蛋错误。无论如何,现在我已经解决并提取正确的订单ID我发现我挂在executeUpdate
上。目前正在处理该问题。如果我无法解决,我可能会创建一个新问题。
答案 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());
}