如何使用计算值更新PL \ SQL列

时间:2017-02-10 09:55:51

标签: oracle plsql sql-update cursor

我创建了一个用于学习目的的虚拟数据库,我故意在其中一个表中创建了一些重复的记录。在每种情况下,我都希望将其中一个重复记录标记为Latest ='Y',将另一个记录标记为'N',并且对于每个记录,最新标记将为'Y'。

我尝试使用PlSQL来浏览我的所有记录,但是当我尝试使用之前计算的值(这会告诉它是一个重复的记录)时,它会说:

ORA-06550:第20行,第17栏: PLS-00201:必须声明标识符'COUNTER'

以下是我尝试使用的声明:

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

3 个答案:

答案 0 :(得分:0)

您需要声明变量COUNTER,然后您需要在循环中维护(即递增)它。 我怀疑你的例子只是为了学习PL / SQL。但请注意,与使用游标循环相比,使用单个SQL语句执行操作往往更高效。

答案 1 :(得分:0)

您可以在游标中引用ROWNUM作为COUNTER 在获取时,您应该从像MOD (rec.COUNTER, 2)

这样的游标引用访问它

答案 2 :(得分:0)

您的问题是rec是游标记录IF MOD (COUNTER, 2) = 0 的属性,而不是PL / SQL变量。所以:

IF MOD (rec.COUNTER, 2) = 0

应该是:

MERGE

但是,您不需要使用PL / SQL或游标,可以在一个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; 语句中完成:

Oracle安装程序

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

<强>输出

{{1}}