2013-07-02 1025 views
1

我有以下sql(oracle),它從表中除去100個最新的表中的所有行。ORA-01422:精確提取返回的請求數量超過請求的行數

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(我不知道如何)有什麼關係?

+0

任何機會,您傳遞給查詢的變量的名稱與表中的任何其他列的名稱相同?添加您正在運行此刪除的表的定義。以及如何在程序中調用此查詢? – Mikhail

回答

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 

您可以發佈一個完整的例子和你的數據庫/客戶端版本。

+0

令人難以置信的令人沮喪的是它不適用於INSERT;但是我相信自10g以來DELETE和UPDATE是可能的。 – Ben

相關問題