Oracle中同一表、不同行、非空列的多列更新:接收错误01407
我犯了一个我不明白的错误 我有一个Oracle数据库11g,我认为它有一个具有多列唯一标识符的表。它是一个事务表,从不同的表中获取数据的前后快照。到目前为止一切正常 我们的代码中有一个bug,现在bug已经修复了,我正在尝试修复数据。该错误导致“after”快照中有两列被调零,而在这种情况下,它们本应保留“before”。因此,我将更新由事务类型编号标识的“after”快照,使其在这两列中具有相同的值 我在多列更新方面找到了各种各样的帮助,我想我已经找到了,除了…它生成了一个错误,它无法将非null列更新为null,而我无法看到null进入其中。显然,我做错了什么;我就是不知道是什么 在某些情况下,一列可以为null—有一个对象类型列定义该记录是否可以具有null值 该表包含以下数据:Oracle中同一表、不同行、非空列的多列更新:接收错误01407,oracle,sql-update,Oracle,Sql Update,我犯了一个我不明白的错误 我有一个Oracle数据库11g,我认为它有一个具有多列唯一标识符的表。它是一个事务表,从不同的表中获取数据的前后快照。到目前为止一切正常 我们的代码中有一个bug,现在bug已经修复了,我正在尝试修复数据。该错误导致“after”快照中有两列被调零,而在这种情况下,它们本应保留“before”。因此,我将更新由事务类型编号标识的“after”快照,使其在这两列中具有相同的值 我在多列更新方面找到了各种各样的帮助,我想我已经找到了,除了…它生成了一个错误,它无法将非nu
object_name object_type trans_type trans_date quantity actual_cost
no-quantity 1 1 04/16/2014 {null} 20.00
no-quantity 1 9 04/16/2014 {null} 0.00
needs quantity 2 1 04/16/2014 3 15.00
needs quantity 2 9 04/16/2014 0 0.00
因此,我需要将第二行no quantity,trans_type 9更新为实际成本20;数量可以保持为空。我需要将第4行更新为数量3,实际成本15
以下是我尝试运行的失败查询-create和insert语句如下:
update demo_table new
set (quantity, actual_cost) =
(
SELECT quantity, actual_cost
FROM demo_table old
WHERE old.object_name = new.object_name
and old.object_type = new.object_type
and old.trans_date = new.trans_date
and old.trans_type = 1
and new.trans_type = 9
)
当我运行此命令时,我得到:
ORA-01407:无法将myschema.DEMO_TABLE.ACTUAL_COST更新为NULL
我尝试过另一种方法-更新select col1、col2等-但表的设置不正确。太糟糕了,因为那样看起来更容易理解
我可能也需要一个外罩吗?其他的帖子没有表明我有,我也不知道我会如何表述它
我甚至在这次尝试中得到了not null错误:
update demo_table new
set (actual_cost) =
(
SELECT actual_cost
FROM demo_table old
WHERE old.object_name = new.object_name
and old.object_type = new.object_type
and old.trans_date = new.trans_date
and old.trans_type = 1
and new.trans_type = 9
and old.object_type = 2
)
2的对象类型没有空数量,而且无论如何,我不会在这个类型中尝试数量
我运行select语句检查实际where子句是否正确,如下所示:
SELECT old.object_name as old_name, old.object_type as old_type, old.trans_type as old_trans, old.trans_date as old_date,
new.object_name as new_name, new.object_type as new_type, new.trans_type as new_trans, new.trans_date as new_date,
old.quantity as old_quantity, old.actual_cost as old_cost, new.quantity as new_quantity, new.actual_cost as new_cost
FROM demo_table old, demo_table new
WHERE old.object_name = new.object_name
and old.object_type = new.object_type
and old.trans_date = new.trans_date
and old.trans_type = 1
and new.trans_type = 9
这将获得正确的值,正确的旧/新字段,正如我所期望的,只返回2行
以下是我的create和insert语句:
create table demo_table (
object_name varchar2(30) not null,
object_type number(3) not null,
trans_type number(3) not null,
trans_date timestamp(6) not null,
quantity number(3),
actual_cost number(17,2) not null
)
insert into demo_table (object_name, object_type, trans_type, trans_date, quantity, actual_cost)
values (
'no-quantity', 1, 1, '16-APR-14', null, 20
)
insert into demo_table (object_name, object_type, trans_type, trans_date, quantity, actual_cost)
values (
'no-quantity', 1, 9, '16-APR-14', null, 0
)
insert into demo_table (object_name, object_type, trans_type, trans_date, quantity, actual_cost)
values (
'needs quantity', 2, 1, '16-APR-14', 3, 15
)
insert into demo_table (object_name, object_type, trans_type, trans_date, quantity, actual_cost)
values (
'needs quantity', 2, 9, '16-APR-14', 0, 0
)
我希望我的问题很清楚。我确实到处找了很多,但我找不到任何与之匹配的东西。同一个表的内容没有真正涵盖,不可为null的列也没有真正涵盖。或者更确切地说,是这样,但我看不出所描述的问题是如何影响我的处境的
我知道,我们可以说,桌子的布置很不理想。今晚无法解决此问题。首先-+1关于此问题-写得很好,有很多支持信息,请接受一个巨大的感谢,感谢您提供足够的信息来解决此问题,包括表定义和填充表的语句 第一次更新的唯一真正问题是WHERE子句中作为新表子集的行应从子查询中拉出,并放入update语句的WHERE子句中,如下所示:
update demo_table new
set (new.quantity, new.actual_cost) =
(
SELECT old.quantity, old.actual_cost
FROM demo_table old
WHERE old.object_name = new.object_name
and old.object_type = new.object_type
and old.trans_date = new.trans_date
and old.trans_type = 1
)
where new.trans_type = 9;
为了弄清楚到底发生了什么,我不得不花了很长一段时间玩弄这个。有趣的问题
分享和享受。谢谢,太好了。工作起来很有魅力。在我更复杂的现实生活问题中,我确实有一个问题:我在写这篇文章时忘了提到,只有某些对象类型会以这种方式更新,所以当我这样做时,我再次遇到了空问题。简单的解决方法就是把它们也放在外面的where里。我可能还会在where里添加一些其他的东西——我把它们放在里面的where里,但我认为它们也都需要放在外面的where里。有一个我没有包括的“所有者”列,只会更新特定所有者和特定交易日期的数据。我认为一般的答案是‘join’信息应该在内部子句中;'where的限制应该在内部子句和外部子句中,即使在where子句和外部子句中都是相同的。再次感谢。我很高兴你喜欢这篇文章;我花了两个小时才把它写成一种我认为足够有用的方式!