【问题标题】:ORA-01427: Subquery returns more than one row - Problem [closed]ORA-01427: 子查询返回多于一行 - 问题 [关闭]
【发布时间】:2022-01-16 10:47:33
【问题描述】:

我有这个 SQL 查询来更新基于另一个表的表:

UPDATE table_a ao
SET capital_stock = 
(WITH
table_c_ec (company_code,change_date,cap_stock_changed, next_change_date) AS
(
SELECT company_code,change_date,cap_stock_changed, 
       LEAD(change_date,1,TO_DATE('14.01.01','YY.MM.DD')) OVER (PARTITION BY c.company_code order by  c.change_date) as next_change_date 
       FROM table_c c
)
SELECT c.cap_stock_changed 
  FROM table_a a 
       JOIN table_b b ON a.entity_id = b.lcompany_fiscal_num
       JOIN table_c_ec c ON b.lcompany_code = c.company_code AND a.create_date BETWEEN c.change_date AND c.next_change_date
 WHERE a.entity_id =ao.entity_id AND a.document_id = ao.document_id
);

经过 8 小时的脚本编写,我得到“ORA-01427:子查询返回多于一行”...

“表 a”中有成千上万条记录,这些记录是要使用此更新子句更改的候选... 我可以更改什么来消除错误?我知道'IN'子句一般可以解决这个错误,但我不知道在这种情况下是否可以应用

【问题讨论】:

  • 嗯.. 以WITH 开头的子查询为更新表中的某些行返回多个值/行。在这些情况下你想做什么?随机更新任何值?不更新?选择最大值,最小值?目前甲骨文正在抛出一个错误,因为它不知道该怎么做。首先,你需要决定在这些情况下你想做什么;那么解决方案可以很简单。
  • 你能检查一下我做的这个question吗?在那里我解释了我的问题以及我正在尝试做的事情。
  • 不确定该链接与@TheImpaler 告诉您的内容有何相关性。您需要修复您的 SQL,以便它只为 ao 表中的每条记录返回一条记录
  • 在链接中,解释了我要更新的内容以及它是如何制作的。基本上我想用表 C 中的数据更新表 A 中的一列,但我必须考虑一些要点
  • 我回答了原始问题 - 不确定还要添加什么 - 正如其他人评论的那样 - 您在 WITH 子句语句中有多个行,这些行在您的示例数据中不存在。数据库无法更新,因为您要求它将列更新为一个值,但它有多个可用于该行的值。在那种情况下你想发生什么?一旦你弄清楚了,你的问题就可以得到回答......

标签: sql oracle


【解决方案1】:

使用BETWEEN是错误的。

如果create_datechange_date 完全匹配,则输入行将匹配table_c 中的两个

我还建议将代码简化如下(使用MERGE 以避免更新已经正确的行)

MERGE INTO
  table_a
USING
  (
    SELECT
      a.*,
      c.capital_stock   AS revised_capital_stock
    FROM
      table_a   a
    INNER JOIN
      table_b   b
        ON a.entity_id = b.entity_id
    CROSS APPLY
    (
      SELECT capital_stock
        FROM table_c
       WHERE change_date   <= a.create_date
         AND lcompany_code  = b.lcompany_code
    ORDER BY change_date DESC
       FETCH FIRST 1 ROWS ONLY
    )
      c
  )
    revision
      ON (    revision.entity_id   = table_a.entity_id
          AND revision.document_id = table_a.document_id
          AND revision.create_date = table_a.create_date
         )
WHEN
  MATCHED THEN UPDATE
    SET capital_stock = revision.revised_capital_stock
  WHERE
    capital_stock <> revision.revised_capital_stock

演示:https://dbfiddle.uk/?rdbms=oracle_21&fiddle=b00017ed2a1a1bbced3f81557b06eb0c

【讨论】:

    猜你喜欢
    • 2018-12-25
    • 1970-01-01
    • 2017-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多