PL/SQL:我在用另一个表中的数据更新表时遇到问题

Posted

技术标签:

【中文标题】PL/SQL:我在用另一个表中的数据更新表时遇到问题【英文标题】:PL/SQL: I have problem updating a table with data from another table 【发布时间】:2021-11-27 04:10:44 【问题描述】:

第一桌ROOMDB

roomnumber rentalbalance
N327 0

第二桌RENTALINVOICE

invoicedate roomnumber totaldue
11/26/2021 N327 2,200.00

我的更新代码:

UPDATE ROOMDB
SET 
RENTALBALANCE = (SELECT TOTALDUE
                   FROM RENTALINVOICE
                  WHERE RENTALINVOICE.ROOMNUMBER=ROOMDB.ROOMNUMBER
                    AND INVOICEDATE=SYSDATE) ;

我需要用来自RENTALINVOICE 的数据更新ROOMDB 中的totaldue 列,尽管它成功地将2,200 输入到totaldue 列,同时它还清除了该列的其余记录在ROOMDB

每次我更新它时,它都会删除除我指定的roomnumber 之外的其余记录。请帮忙。

【问题讨论】:

【参考方案1】:

您似乎还更新了表roomdb 中的行,其中表rentalinvoice 中没有行,因此rentalbalance 列将设置为null。

看看下面的例子:

drop table a;
create table a (id number, cost number);
insert into a values (1, 1);
insert into a values (2, 2);

drop table b;
create table b (id number, cost number);
insert into b values (1, 100);

-- updates all rows in a and sets cost to null whenen there is no row in b
update a set cost = (select cost from b where a.id = b.id);
select * from a;

-- only updaes rows in a where there is a row in b
update a set cost = id;
update a set cost = (select cost from b where a.id = b.id) where exists (select 1 from b where a.id = b.id);
select * from a;

【讨论】:

感谢 doberkofler,这样更好吗? UPDATE ROOMDB SET RENTALBALANCE = (SELECT TOTALDUE FROM RENTALINVOICE WHERE INVOICEDATE=SYSDATE AND ROOMNUMBER=ROOMDB.ROOMNUMBER) WHERE EXISTS (SELECT 1 FROM RENTALINVOICE WHERE INVOICEDATE=SYSDATE AND ROOMNUMBER=ROOMDB.ROOMNUMBER) ; 看起来更好,但在您的update 中使用sysdate 可能会出现问题。我宁愿使用WHERE EXISTS (SELECT 1 FROM RENTALINVOICE WHERE INVOICEDATE=ROOMDB. INVOICEDATE AND ROOMNUMBER=ROOMDB.ROOMNUMBER) ;,并且在使用 sysdate 时必须小心,因为它还包含时间,所以您通常只将日期的日期部分与 trunc(sysdate) 之类的内容进行比较。【参考方案2】:

当您执行这样的更新命令时,Oracle 将更新所有表行。对于每一行,选择命令将使用这些行值执行。如果更新中select的结果没有找到任何记录将返回null。在这种情况下,RENTALBALANCE 列也会设置为 null。

(SELECT TOTALDUE
          FROM RENTALINVOICE
         where WHERE RENTALINVOICE.ROOMNUMBER = ROOMDB.ROOMNUMBER
                 AND INVOICEDATE = SYSDATE)

【讨论】:

你好像不知道怎么用markdown。

以上是关于PL/SQL:我在用另一个表中的数据更新表时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 pl/sql 中的游标将多列数据插入包含单列的表中?

在oracle怎样更新表中的数据

PL/SQL 插入一个表减去另一个表但同时插入另一列

如何在 PL/SQL 中增量集成数据

PL/SQL 使用一张表中的列数据更新表,基于不同表之间的相等性

为啥mssql的OPENQUERY取oracle某表时只返回了一行数据,而在pl/sql中可以查到表中有两行数据,求解答?