2017-02-10 2 views
2

Я создал базу данных фиктивных данных для обучения, и я целенаправленно создал несколько дублированных записей в одной из таблиц. В каждом случае я хочу отмечать одну из дублированных записей как «Последний», «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 Setup:

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 
Смежные вопросы