无法更新oracle sql表

Posted

技术标签:

【中文标题】无法更新oracle sql表【英文标题】:cannot update oracle sql table 【发布时间】:2020-11-26 21:43:40 【问题描述】:

有这个代码:

select clientinfo.client_surname, mi.medicine_price from clientinfo 
    join orderinfo oi on oi.client_id = clientinfo.client_id
    join ordered_medicines om on om.order_id = oi.order_id
    join medicine_instances mi on om.medicine_id_instance = mi.medicine_id_instance
    where add_months(birthdate, 65*12) < CURRENT_DATE and mi.medicine_price in (select max(medicine_price) from medicine_instances);
update
(select mi.medicine_price
from clientinfo 
    join orderinfo oi on oi.client_id = clientinfo.client_id
    join ordered_medicines om on om.order_id = oi.order_id
    join medicine_instances mi on om.medicine_id_instance = mi.medicine_id_instance
    where add_months(birthdate, 65*12) < CURRENT_DATE and mi.medicine_price in (select max(medicine_price) from medicine_instances)
    ) T
    set T.medicine_price = T.medicine_price * 0.98;

但是当我尝试运行它时出现错误: ORA-01779: 无法修改映射到非键保留表的列

我用谷歌搜索,但不明白如何解决它。有什么问题?

【问题讨论】:

我假设你的几个连接是“正确的类型”——你有连续的查找,并且在每种情况下你都连接到一个查找表,其中连接列是主键。唉,除非您通过约束或索引明确告诉 Oracle,某些列是“主键”或“唯一”,否则 Oracle 不会知道这一点,它会假设至少 可能歧义。如果我的假设是正确的,解决此问题的正确 方法是显式声明主键(或唯一键)约束。那么update 应该可以像写的那样工作。 【参考方案1】:

您可以按如下方式使用关联:

Update medicine_instances trg
  Set trg.medicine_price =
(select mi.medicine_price
  from   clientinfo 
         join orderinfo oi on oi.client_id = clientinfo.client_id
         join ordered_medicines om on om.order_id = oi.order_id
         join medicine_instances mi on om.medicine_id_instance = mi.medicine_id_instance
   where add_months(birthdate, 65*12) < CURRENT_DATE
     and mi.medicine_price in (select max(medicine_price) from medicine_instances)
     And mi.medicine_id_instance = trg.medicine_id_instance )
   Where exists
 (select 1
  from   clientinfo 
         join orderinfo oi on oi.client_id = clientinfo.client_id
         join ordered_medicines om on om.order_id = oi.order_id
         join medicine_instances mi on om.medicine_id_instance = mi.medicine_id_instance
   where add_months(birthdate, 65*12) < CURRENT_DATE
     and mi.medicine_price in (select max(medicine_price) from medicine_instances)
     And mi.medicine_id_instance = trg.medicine_id_instance )

【讨论】:

【参考方案2】:

您应该能够将查询放入MERGE 语句(与ROWID 伪列相关):

MERGE INTO medicine_instances dst
USING (
  select mi.ROWID AS rid
  from   clientinfo 
         join orderinfo oi
         on oi.client_id = clientinfo.client_id
         join ordered_medicines om
         on om.order_id = oi.order_id
         join medicine_instances mi
         on om.medicine_id_instance = mi.medicine_id_instance
  where  add_months(birthdate, 65*12) < CURRENT_DATE
  and    mi.medicine_price in (select max(medicine_price) from medicine_instances)
) src
ON ( src.rid = dst.ROWID )
WHEN MATCHED THEN
  UPDATE SET medicine_price = src.medicine_price * 0.98;

【讨论】:

以上是关于无法更新oracle sql表的主要内容,如果未能解决你的问题,请参考以下文章

只允许通过 sql server、oracle 和 postgres 中的 jdbc 更新表

Oracle SQL

Oracle - 无法使用绑定变量更新表记录

oracle存储过程中update语句一直在执行中,无法更新完成

合并更新 oracle 无法获得一组稳定的行

无法通过php更新sql表