ORA-01422:在RETURNING INTO中,精确提取的返回次数超过了请求的行数

时间:2013-07-02 12:28:17

标签: sql oracle ora-01422

我有以下sql(oracle)删除除最新的100之外的表中的所有行。

DELETE FROM my_table tab_outer
WHERE tab_outer.rowid IN (
    -- Fetch rowids of rows to delete
    SELECT rid FROM (
        SELECT rownum r, rid FROM (
            SELECT tab.rowid rid
                FROM my_table tab
                ORDER BY tab.created_date DESC
            )
        )
        -- Delete everything but the 100 nesest rows
        WHERE r > 100
)
-- Return newest date that was removed
RETURNING max(tab_outer.created_date) INTO :latestDate

此代码有时会提供ORA-01422: exact fetch returns more than requested number of rows声称在latestDate中插入了多行。这怎么可能? RETURNING INTO子句中的聚合函数(max)应该确保只返回一行,不是吗?它可能与显式使用或rowid有关(我不知道如何)?

1 个答案:

答案 0 :(得分:1)

我认为在返回子句中不可能使用聚合,因为我从未尝试过它而且没有提到in the documentation,但它实际上有效(11gr2)!!

请参阅下面的PL / SQL:

SQL> CREATE TABLE my_table (created_date DATE);

Table created

SQL> INSERT INTO my_table
  2     (SELECT SYSDATE + ROWNUM FROM dual CONNECT BY LEVEL <= 500);

500 rows inserted

SQL> DECLARE
  2     latestDate DATE;
  3  BEGIN
  4     DELETE FROM my_table tab_outer
  5     WHERE tab_outer.rowid IN (
  6         -- Fetch rowids of rows to delete
  7         SELECT rid FROM (
  8             SELECT rownum r, rid FROM (
  9                 SELECT tab.rowid rid
 10                     FROM my_table tab
 11                     ORDER BY tab.created_date DESC
 12                 )
 13             )
 14             -- Delete everything but the 100 nesest rows
 15             WHERE r > 100
 16     )
 17     -- Return newest date that was removed
 18     RETURNING max(tab_outer.created_date) INTO latestDate;
 19     dbms_output.put_line(latestDate);
 20  END;
 21  /

06/08/14

甚至在SQL * Plus(10.2.0.1.0客户端,11.2.0.3.0数据库)中:

SQL> VARIABLE latestDate VARCHAR2(20);
SQL> DELETE FROM my_table tab_outer
  2  WHERE tab_outer.rowid IN (
  3      -- Fetch rowids of rows to delete
  4      SELECT rid FROM (
  5          SELECT rownum r, rid FROM (
  6              SELECT tab.rowid rid
  7                  FROM my_table tab
  8                  ORDER BY tab.created_date DESC
  9              )
 10          )
 11          -- Delete everything but the 100 nesest rows
 12          WHERE r > 100
 13  )
 14  -- Return newest date that was removed
 15  RETURNING max(tab_outer.created_date) INTO :latestDate;

400 rows deleted.

SQL> select :latestDate from dual;

:LATESTDATE
--------------------------------------------------------------------------------
06/08/14

您是否可以发布完整的示例和数据库/客户端版本。