2017-02-10 52 views
2

我爲學習目的創建了一個虛擬數據庫,並且有意地在其中一個表中創建了一些重複的記錄。在每種情況下,我想標記一個重複記錄爲Latest ='Y',另一個記錄爲'N',並且對於每個記錄,最新的標誌將是'Y'。如何使用計算值更新PL/SQL的列

我試圖用PLSQL要經過我所有的記錄,但是當我嘗試使用先前計算的值(這將告訴它是一個複製的記錄),它說:

ORA-06550:行20,列17: PLS-00201:標識符「計數器」必須聲明

這是我嘗試使用的語句:

DECLARE CURSOR cur IS SELECT order_id, order_date, person_id, amount, successfull_order, country_id, latest, ROWCOUNT AS COUNTER FROM (SELECT order_id, order_date, person_id, amount, successfull_order, country_id, latest, ROW_NUMBER() OVER (PARTITION BY order_id, order_date, person_id, amount, successfull_order, country_id ORDER BY order_id, order_date, person_id, amount, successfull_order, country_id) ROWCOUNT FROM orders) orders FOR UPDATE OF orders.latest; rec cur%ROWTYPE; BEGIN FOR rec IN cur LOOP IF MOD (COUNTER, 2) = 0 THEN UPDATE orders SET latest = 'N' WHERE CURRENT OF cur; ELSE UPDATE orders SET latest = 'Y' WHERE CURRENT OF cur; END IF; END LOOP; END;

我是新來PLSQL所以我試圖修改我在這裏找到的聲明: http://www.adp-gmbh.ch/ora/plsql/cursors/for_update.html

我應該在聲明中更改哪些內容?還是應該使用其他方法?

感謝您的提前解答! Botond

+0

您應該從像'MOD光標參照訪問它(rec.COUNTER,2)' –

回答

0

您在光標中將ROWNUM設爲COUNTER
在拿,你應該從遊標引用訪問它像MOD (rec.COUNTER, 2)

+0

謝謝,對於答案,但這樣我有一個新問題。它不想更新,因爲我使用了分區。我使用了一種替代方法。 –

0

您需要聲明變量COUNTER,然後您需要在循環中維護(即增加)它。 我懷疑你的例子只是爲了學習PL/SQL。但是請注意,與使用遊標循環相比,使用單個SQL語句執行操作通常要高效得多。

+0

由於我使用的解決方法,通過用一些幫助列創建一個全新的表。這樣我不必使用PLSQL。 –

0

你的問題是,COUNTER是光標記錄rec,而不是一個PL/SQL變量的屬性。所以:

IF MOD (COUNTER, 2) = 0 

應該是:

IF MOD (rec.COUNTER, 2) = 0 

但是,你並不需要使用PL/SQL或遊標,它可以在一個單一的MERGE語句來完成:

的Oracle安裝

CREATE TABLE orders (order_id, order_date, latest) AS 
SELECT 1, DATE '2017-01-01', CAST(NULL AS CHAR(1)) FROM DUAL UNION ALL 
SELECT 1, DATE '2017-01-02', NULL FROM DUAL UNION ALL 
SELECT 1, DATE '2017-01-03', NULL FROM DUAL UNION ALL 
SELECT 2, DATE '2017-01-04', NULL FROM DUAL UNION ALL 
SELECT 2, DATE '2017-01-01', NULL FROM DUAL UNION ALL 
SELECT 3, DATE '2017-01-06', NULL FROM DUAL; 

更新語句

MERGE INTO orders dst 
USING (SELECT ROW_NUMBER() OVER (PARTITION BY order_id 
            ORDER BY order_date DESC) AS rn 
     FROM orders 
    ) src 
ON (src.ROWID = dst.ROWID) 
WHEN MATCHED THEN 
    UPDATE SET latest = CASE src.rn WHEN 1 THEN 'Y' ELSE 'N' END; 

輸出

SELECT * FROM orders; 

ORDER_ID ORDER_DATE LATEST 
-------- ---------- ------ 
     1 2017-01-01 N 
     1 2017-01-02 N 
     1 2017-01-03 Y 
     2 2017-01-04 Y 
     2 2017-01-01 N 
     3 2017-01-06 Y