2017-02-10 56 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