Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 通过游标循环时出现PL/SQL错误ORA-01722_Oracle_Plsql_Oracle Apex_Ora 01722 - Fatal编程技术网

Oracle 通过游标循环时出现PL/SQL错误ORA-01722

Oracle 通过游标循环时出现PL/SQL错误ORA-01722,oracle,plsql,oracle-apex,ora-01722,Oracle,Plsql,Oracle Apex,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

对于一个项目,我需要根据同一属性的值修改表中的某些属性。我决定使用游标,并写了以下内容:

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;
声明
总租金。saldo%类型;
光标c_boven1000为
选择r.reknummer,
r、 萨尔多,
rt.rentepercentage,
ABS(圆形(r.saldo*(rt.rentepercentage/100),2))为teBetalen
来自雷克宁r
在rt.naam=r.rekeningtype上加入rekeningtype rt
其中r.saldo<0且saldo>=-1000;
1000上的光标c_为
选择r.reknummer,
r、 萨尔多,
rt.rentepercentage,
ABS(圆形(r.saldo*((rt.rentepercentage*2)/100),2)如teBetalen
来自雷克宁r
在rt.naam=r.rekeningtype上加入rekeningtype rt
其中r.saldo<-1000;
类型rek_saldo是rekening的表格。saldo%类型;
类型reknummer是rekening的表。reknummer%类型;
类型\ U百分比是rekeningtype.rentepercentage%类型的表格;
类型rek_tebetalen是rekening的表格。saldo%类型;
雷克苏·萨尔多斯雷克苏·萨尔多;
雷克努默斯雷克努默尔;
类型\百分比类型\百分比;
rek_tebetalen rek_tebetalen;
开始
打开c_boven1000;
将c_boven1000批量收集到rek_saldos、rek_nummers、type_Percentage、rek_tebetalens中;
关闭c_boven1000;
对于rek_nummers.first..rek_nummers.last循环中的x
更新rekening r
设置r.saldo=r.saldo-rek_tebetalens(x)
其中r.reknummer=rek_nummers(x);
总租金:=总租金+租金(x);
端环;
打开c_onder1000;
将1000个大批量收集的c_onder1000收集到rek_saldos、rek_nummers、type_Percentage、rek_tebetalens中;
关闭c_onder1000;
对于rek_nummers.first..rek_nummers.last循环中的x
更新rekening r
设置r.saldo=r.saldo-rek_tebetalens(x)
其中r.reknummer=rek_nummers(x);
总租金:=总租金+租金(x);
端环;
更新rekening r
设置saldo=saldo+总租金
其中r.reknummer='2250';
结束;
在这种情况下,
reknummer
是一个Varchar,
saldo
是一个数字(10,2),
rentepercentage
是一个数字(3,2)

执行时,我得到以下错误:

ORA-01722:执行PL/SQL代码的编号无效

不确定它是否重要,但此代码块位于单击按钮的动态操作中。 我试图找到我的错误,但一直无法找到。
有人能帮忙吗?

您选择列的顺序和变量的顺序不一样

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

 into rek_saldos
          ,rek_nummers
          ,type_percentages
您可以在游标中使用case语句,如下所示:

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
选择r.reknummer
,r.saldo
,rt.rentepercentage
案例
当saldo>=-1000时
abs(圆形(r.saldo*(rt.rentepercentage/100),2))
其他的
abs(圆形(r.saldo*((rt.rentepercentage*2)/100),2))
以特贝塔伦结束
来自雷克宁r
加入rekeningtype rt
关于rt.naam=r.rekeningtype
其中r.saldo<0

选择列的顺序与变量的顺序不同

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

 into rek_saldos
          ,rek_nummers
          ,type_percentages
您可以在游标中使用case语句,如下所示:

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
选择r.reknummer
,r.saldo
,rt.rentepercentage
案例
当saldo>=-1000时
abs(圆形(r.saldo*(rt.rentepercentage/100),2))
其他的
abs(圆形(r.saldo*((rt.rentepercentage*2)/100),2))
以特贝塔伦结束
来自雷克宁r
加入rekeningtype rt
关于rt.naam=r.rekeningtype
其中r.saldo<0

这是完整的错误信息吗?我的第一个建议是重新考虑您的算法。您打开光标两次,只检索一条记录。这可以在没有游标的情况下完成(游标旨在检索记录的数据集/集合,然后逐个循环)。一旦您更改了代码并消除了所有错误(包括01722),请使用更多信息更新您的问题。我将根据属性rekening.saldo的值使用两个不同的游标,因为如果saldo<-1000,则需要使用rekeningtype.rentepercentage的两倍值来计算rekening.saldo的新值。我不知道有什么不同的方法可以做到这一点。您对如何进行不同的操作有什么建议吗?
c_boven1000
c_onder1000
中的列顺序与
批量收集到
子句中的收集顺序不匹配;您交换了
saldo
reknumer
?这看起来太复杂了…这是一个完整的错误信息吗?我的第一个建议是重新考虑你的算法。您打开光标两次,只检索一条记录。这可以在没有游标的情况下完成(游标旨在检索记录的数据集/集合,然后逐个循环)。一旦您更改了代码并消除了所有错误(包括01722),请使用更多信息更新您的问题。我将根据属性rekening.saldo的值使用两个不同的游标,因为如果saldo<-1000,则需要使用rekeningtype.rentepercentage的两倍值来计算rekening.saldo的新值。我不知道有什么不同的方法可以做到这一点。您对如何进行不同的操作有什么建议吗?
c_boven1000
c_onder1000
中的列顺序与
批量收集到
子句中的收集顺序不匹配;您交换了
saldo
reknumer
?这似乎太复杂了…谢谢你的澄清,对我来说,这些小事情总是最难发现的。它现在正按预期完美工作。谢谢你清理它,对我来说,最难发现的总是那些小东西。它现在正按预期完美工作。