2016-11-09 4 views
0

Для проекта мне нужно изменить некоторые атрибуты в таблице, исходя из значения этого же атрибута. Я решил пойти с курсорами, и написал следующее:Ошибка PL/SQL ORA-01722 при переходе через курсор

DECLARE 
totale_rente rekening.saldo%TYPE; 
cursor c_boven1000 is 
select r.reknummer, 
     r.saldo, 
     rt.rentepercentage, 
     ABS(ROUND(r.saldo * (rt.rentepercentage/100), 2)) as teBetalen 
     FROM rekening r 
     join rekeningtype rt on rt.naam = r.rekeningtype 
     Where r.saldo < 0 and saldo >= -1000; 
cursor c_onder1000 is 
select r.reknummer, 
     r.saldo, 
     rt.rentepercentage, 
     ABS(ROUND(r.saldo * ((rt.rentepercentage*2)/100), 2)) as teBetalen 
     From rekening r 
     join rekeningtype rt on rt.naam = r.rekeningtype 
     Where r.saldo < -1000; 

TYPE rek_saldo IS TABLE OF rekening.saldo%TYPE; 
TYPE rek_nummer IS TABLE OF rekening.reknummer%TYPE; 
TYPE type_percentage IS TABLE OF rekeningtype.rentepercentage%TYPE; 
TYPE rek_tebetalen IS TABLE OF rekening.saldo%TYPE; 

rek_saldos rek_saldo; 
rek_nummers rek_nummer; 
type_percentages type_percentage; 
rek_tebetalens rek_tebetalen; 

BEGIN 
OPEN c_boven1000; 
FETCH c_boven1000 BULK COLLECT INTO rek_saldos, rek_nummers, type_percentages, rek_tebetalens; 
CLOSE c_boven1000; 
FOR x IN rek_nummers.first..rek_nummers.last LOOP 
    UPDATE rekening r 
    SET r.saldo = r.saldo - rek_tebetalens(x) 
    WHERE r.reknummer = rek_nummers(x); 
    totale_rente := totale_rente + rek_tebetalens(x); 
END LOOP; 
OPEN c_onder1000; 
FETCH c_onder1000 BULK COLLECT INTO rek_saldos, rek_nummers, type_percentages, rek_tebetalens; 
CLOSE c_onder1000; 
FOR x IN rek_nummers.first..rek_nummers.last LOOP 
    UPDATE rekening r 
    SET r.saldo = r.saldo - rek_tebetalens(x) 
    WHERE r.reknummer = rek_nummers(x); 
    totale_rente := totale_rente + rek_tebetalens(x); 
END LOOP;  

    UPDATE rekening r 
    SET saldo = saldo + totale_rente 
    WHERE r.reknummer = '2250'; 
END; 

В этом случае reknummer является Varchar, saldo ряд (10,2), rentepercentage ряд (3,2).

При выполнении, я получил следующее сообщение об ошибке:

ORA-01722: Invalid number for execute PL/SQL code.

Не уверен, если это важно, но этот блок кода внутри динамического действия по нажатию кнопки. Я попытался найти свою ошибку, но не смог. Может ли кто-нибудь помочь?

+0

Это полное сообщение об ошибке? – massko

+0

Самое первое, что у меня есть - это пересмотреть свой алгоритм. Вы дважды открываете курсор, чтобы получить только одну запись. Это можно сделать без курсора (курсоры нацелены на получение набора данных/коллекции записей, а затем поочередно прокручивают их). После того как вы изменили код и устранили все ошибки (в том числе 01722), обновите свой вопрос с дополнительной информацией. – FDavidov

+0

Я использую два разных курсора, основанных на значении атрибута rekening.saldo, потому что если saldo <-1000, новое значение rekening.saldo нужно рассчитать, используя двойное значение rekeningtype.rentepercentage. Я не знаю другого способа сделать это. Есть ли у вас какие-либо советы о том, как сделать это по-другому? –

ответ

2

Порядок, в котором вы выбираете свои столбцы и порядок переменных, не совпадает.

select r.reknummer 
     ,r.saldo 
     ,rt.rentepercentage 

into rek_saldos 
      ,rek_nummers 
      ,type_percentages 

Вы можете использовать тематическое заявление в курсор, как например:

select r.reknummer 
     ,r.saldo 
     ,rt.rentepercentage 
     ,case 
      when saldo >= -1000 then 
      abs(round(r.saldo * (rt.rentepercentage/100), 2)) 
      else 
      abs(round(r.saldo * ((rt.rentepercentage * 2)/100), 2)) 
     end as tebetalen 
    from rekening r 
    join rekeningtype rt 
    on rt.naam = r.rekeningtype 
where r.saldo < 0 
+0

Спасибо, что расчистили его, это самые мелочи, которые наиболее трудно найти для меня. Он работает отлично, как предполагалось сейчас. –

Смежные вопросы