Oracle中同一表、不同行、非空列的多列更新:接收错误01407

Oracle中同一表、不同行、非空列的多列更新:接收错误01407,oracle,sql-update,Oracle,Sql Update,我犯了一个我不明白的错误 我有一个Oracle数据库11g,我认为它有一个具有多列唯一标识符的表。它是一个事务表,从不同的表中获取数据的前后快照。到目前为止一切正常 我们的代码中有一个bug,现在bug已经修复了,我正在尝试修复数据。该错误导致“after”快照中有两列被调零,而在这种情况下,它们本应保留“before”。因此,我将更新由事务类型编号标识的“after”快照,使其在这两列中具有相同的值 我在多列更新方面找到了各种各样的帮助,我想我已经找到了,除了…它生成了一个错误,它无法将非nu

我犯了一个我不明白的错误

我有一个Oracle数据库11g,我认为它有一个具有多列唯一标识符的表。它是一个事务表,从不同的表中获取数据的前后快照。到目前为止一切正常

我们的代码中有一个bug,现在bug已经修复了,我正在尝试修复数据。该错误导致“after”快照中有两列被调零,而在这种情况下,它们本应保留“before”。因此,我将更新由事务类型编号标识的“after”快照,使其在这两列中具有相同的值

我在多列更新方面找到了各种各样的帮助,我想我已经找到了,除了…它生成了一个错误,它无法将非null列更新为null,而我无法看到null进入其中。显然,我做错了什么;我就是不知道是什么

在某些情况下,一列可以为null—有一个对象类型列定义该记录是否可以具有null值

该表包含以下数据:

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子句和外部子句中都是相同的。再次感谢。我很高兴你喜欢这篇文章;我花了两个小时才把它写成一种我认为足够有用的方式!