英文:
GTT row not found on delete but found on insert
问题
以下是翻译好的内容:
我从未在 Oracle 和 Java 下使用过 GTT。
我想使用它来管理一些数据,我想为产品添加一些预测,并且希望在插入之前通过 ID 查找并删除任何现有行。
以下是我的 GTT:
CREATE GLOBAL TEMPORARY TABLE "M_PRODUCT_FORECAST"
(
"M_PRODUCT_FORECAST_ID" NUMBER(10,0) NOT NULL ENABLE,
"FORECAST_MODE" CHAR(1 BYTE) DEFAULT 'D' NOT NULL ENABLE,
"FORECAST_QTY" NUMBER DEFAULT 1 NOT NULL ENABLE,
CHECK (forecast_mode IN ('D','P')) ENABLE,
CONSTRAINT "M_PRODUCT_FORECAST_KEY" PRIMARY KEY ("M_PRODUCT_FORECAST_ID", "FORECAST_MODE") ENABLE
) ON COMMIT PRESERVE ROWS ;
然后这是我的 Java 代码:
private void addProductToForecast() {
Integer productId = (Integer) productSearchEditor.getValue();
BigDecimal qty = qtyNumberBox.getValue();
String mode = developementCheckbox.isSelected() ? 'D' : 'P';
PreparedStatement ps = null;
try {
String deletePreviousForcastIfExists = " DELETE FROM " + M_PRODUCT_FORECAST
+ " WHERE " + M_PRODUCT_FORECAST_ID + " = ? "
+ " AND " + FORECAST_MODE + " = ?";
ps = DB.prepareStatement(deletePreviousForcastIfExists, null);
ps.setInt(1, productId);
ps.setString(2, mode);
int update = ps.executeUpdate();
log.info(deletePreviousForcastIfExists + "return update value :: " + update);
} catch (SQLException e) {
e.printStackTrace();
}finally {
Util.closeCursor(ps, null);
ps = null;
}
try {
String insertIntoForcast = " INSERT INTO " + M_PRODUCT_FORECAST
+ " VALUES(?,?,?)";
ps = DB.prepareStatement(insertIntoForcast, null);
ps.setInt(1, productId);
ps.setString(2, mode);
ps.setBigDecimal(3, qty);
int update = ps.executeUpdate();
log.info(insertIntoForcast + "return update value :: " + update);
} catch (SQLException e) {
e.printStackTrace();
} finally {
Util.closeCursor(ps, null);
ps = null;
}
}
注意:
在调试第一个删除操作时,返回的更新值为 0,我猜这意味着没有找到要删除的任何行,然而插入操作引发了唯一键冲突异常,这意味着存在数据。
>java.sql.SQLIntegrityConstraintViolationException: ORA-00001: 违反唯一约束条件 (M_PRODUCT_FORECAST_KEY)
英文:
I have never used GTT under Oracle and Java.
I want to use it to manage some datas, I want to add some forecasting of products and I wish to remove any existing row before inserting looking it by ID
Here is my GTT
CREATE GLOBAL TEMPORARY TABLE "M_PRODUCT_FORECAST"
(
"M_PRODUCT_FORECAST_ID" NUMBER(10,0) NOT NULL ENABLE,
"FORECAST_MODE" CHAR(1 BYTE) DEFAULT 'D' NOT NULL ENABLE,
"FORECAST_QTY" NUMBER DEFAULT 1 NOT NULL ENABLE,
CHECK (forecast_mode IN ('D','P')) ENABLE,
CONSTRAINT "M_PRODUCT_FORECAST_KEY" PRIMARY KEY ("M_PRODUCT_FORECAST_ID", "FORECAST_MODE") ENABLE
) ON COMMIT PRESERVE ROWS ;
Then here is my Java code
private void addProductToForecast() {
Integer productId = (Integer) productSearchEditor.getValue();
BigDecimal qty = qtyNumberBox.getValue();
String mode = developementCheckbox.isSelected()?"D":"P";
PreparedStatement ps = null;
try {
String deletePreviousForcastIfExists = " DELETE FROM "+M_PRODUCT_FORECAST
+ " WHERE "+M_PRODUCT_FORECAST_ID+" = ? "
+ " AND "+FORECAST_MODE+" = ?";
ps = DB.prepareStatement(deletePreviousForcastIfExists, null);
ps.setInt(1, productId);
ps.setString(2, mode);
int update = ps.executeUpdate();
log.info(deletePreviousForcastIfExists + "return update value :: "+update);
} catch (SQLException e) {
e.printStackTrace();
}finally {
Util.closeCursor(ps,null);
ps = null;
}
try {
String insertIntoForcast = " INSERT INTO " +M_PRODUCT_FORECAST
+" VALUES(?,?,?)";
ps = DB.prepareStatement(insertIntoForcast, null);
ps.setInt(1, productId);
ps.setString(2, mode);
ps.setBigDecimal(3, qty);
int update = ps.executeUpdate();
log.info(insertIntoForcast + "return update value :: "+update);
} catch (SQLException e) {
e.printStackTrace();
} finally {
Util.closeCursor(ps, null);
ps = null;
}
}
NB
While debugging the first remove update value return 0, I guess this means it doesn't find any row to be deleted, however the insert is rising the violation of unique key exception which means there is data.
>java.sql.SQLIntegrityConstraintViolationException: ORA-00001: violation de contrainte unique (M_PRODUCT_FORECAST_KEY)
答案1
得分: 1
首先,我建议使用 merge
而不是 delete
+insert
:
merge into M_PRODUCT_FORECAST m
using (
select :id as id,
:mode as mode,
:qty as qty
from dual) n
on (m.M_PRODUCT_FORECAST_ID = n.id and m.FORECAST_MODE = n.mode)
when matched then update
set m.M_PRODUCT_FORECAST_ID = n.mode
when not matched then
insert
values (n.id,n.mode,n.qty)
另外,我会检查数据插入到数据库中的内容。我是指绑定变量及其类型,只是为了确认是否存在隐式数据类型转换或类似的情况。
英文:
First of all, I would suggest to use merge
instead of delete
+insert
:
merge into M_PRODUCT_FORECAST m
using (
select :id as id,
:mode as mode,
:qty as qty
from dual) n
on (m.M_PRODUCT_FORECAST_ID = n.id and m.FORECAST_MODE = n.mode)
when matched then update
set m.M_PRODUCT_FORECAST_ID = n.mode
when not matched then
insert
values (n.id,n.mode,n.qty)
In addition, I would check what exactly is coming into db. I mean bind variables and their types, just to confirm that there is no implicit datatype conversion or something like that
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论