在数组循环中使用游标

Posted

技术标签:

【中文标题】在数组循环中使用游标【英文标题】:using cursor inside array loop 【发布时间】:2017-09-27 09:45:03 【问题描述】:

我有一个存储过程,我试图在其中使用 tab_array 中的项目,以执行 select 语句。这是一个循环内的游标。我想将arrat的每个项目用作“表格”。该程序应该可以正常运行。

谁能帮帮我?我希望这个问题很清楚。 谢谢你。

 create or replace PROCEDURE PROVA AS 

 myRiga number;
 myDescRiga varchar2(1000);
 myCircuito  varchar2(1000);
 myPrevRiga number;
 myPrevCircuito  varchar2(1000);
 myCodeTipoRiga varchar2(1000);
 myPrevCodeTipoRiga varchar2(1000);

 type tab_array is array(5) of varchar2(1000);
 tab tab_array;
 tabella varchar2(100);

 BEGIN

 tab := tab_array ('TAB1', 'TAB2', 'TAB3', 'TAB4', 'TAB5');

for i in 1..tab.count loop
tabella:=tab(i);

declare cursor prova is

SELECT CODE_TIPO_RIGA,ATTR_PROG_RIGA, ATTR_DESC_RIGA_01 FROM ||tabella|| ORDER BY ATTR_PROG_RIGA ;

begin

for item in prova loop

myRiga:=item.attr_prog_riga;
myCircuito:=item.attr_desc_riga_01;
myCodeTipoRiga:=item.code_tipo_riga;

dbms_output.put_line('---INIZIO---');
dbms_output.put_line('myRiga: ' || myRiga);
dbms_output.put_line('myCircuito: ' || myCircuito);
dbms_output.put_line('myCodeTipoRiga: ' || myCodeTipoRiga);

dbms_output.put_line('myPrevRiga: ' || myPrevRiga);
dbms_output.put_line('myPrevCircuito: ' || myPrevCircuito);
dbms_output.put_line('myPrevCodeTipoRiga: ' || myPrevCodeTipoRiga);  


    if (myRiga!=myPrevRiga and myCircuito=myPrevCircuito and myPrevCodeTipoRiga=myCodeTipoRiga)  then

        if  myRiga > myPrevRiga then
        dbms_output.put_line('riga:'|| myRiga);
      update ||tabella|| set attr_desc_riga_01 = ' ' where ATTR_PROG_RIGA in (myRiga);
        end if;

    end if;

 myPrevRiga:=myRiga;
 myPrevCircuito:=myCircuito;
 myPrevCodeTipoRiga:=myCodeTipoRiga;   


 dbms_output.put_line('---FINE---');
 end loop;    
 end;    
 end loop;






 END PROVA;

【问题讨论】:

将更新和游标声明纳入 EXECUTE IMMEDIATE 谢谢!我会试试这个方法 【参考方案1】:

你可以这样做:

CREATE TABLE TAB1
(
   CODE_TIPO_RIGA      VARCHAR2 (10),
   ATTR_PROG_RIGA      NUMBER,
   ATTR_DESC_RIGA_01   VARCHAR2 (10)
);
/

程序:

CREATE OR REPLACE PROCEDURE PROVA
AS
   myRiga               NUMBER;
   myDescRiga           VARCHAR2 (1000);
   myCircuito           VARCHAR2 (1000);
   myPrevRiga           NUMBER;
   myPrevCircuito       VARCHAR2 (1000);
   myCodeTipoRiga       VARCHAR2 (1000);
   myPrevCodeTipoRiga   VARCHAR2 (1000);

   TYPE tab_array IS ARRAY (5) OF VARCHAR2 (1000);

   tab                  tab_array;
   tabella              VARCHAR2 (100);


   TYPE tab_col IS RECORD
   (
      CODE_TIPO_RIGA      VARCHAR2 (10),-- This datatype should be same as of your table column
      ATTR_PROG_RIGA      NUMBER,-- This datatype should be same as of your table column
      ATTR_DESC_RIGA_01   VARCHAR2 (10) -- This datatype should be same as of your table column
   );

   TYPE tab_var IS TABLE OF tab_col
      INDEX BY PLS_INTEGER;

   var_tab              tab_var;

   v_sql                VARCHAR2 (100);
   v_sql_1              VARCHAR2 (100);
BEGIN
   tab :=
      tab_array ('TAB1',
                 'TAB2',
                 'TAB3',
                 'TAB4',
                 'TAB5');

   FOR i IN 1 .. tab.COUNT
   LOOP
      tabella := tab (i);

      v_sql :=
            'SELECT CODE_TIPO_RIGA, ATTR_PROG_RIGA, ATTR_DESC_RIGA_01 FROM '
         || tabella
         || ' ORDER BY ATTR_PROG_RIGA';

      EXECUTE IMMEDIATE v_sql BULK COLLECT INTO var_tab;

      FOR i IN 1 .. var_tab.COUNT
      LOOP
         myRiga := var_tab (i).attr_prog_riga;
         myCircuito := var_tab (i).attr_desc_riga_01;
         myCodeTipoRiga := var_tab (i).code_tipo_riga;

         DBMS_OUTPUT.put_line ('---INIZIO---');
         DBMS_OUTPUT.put_line ('myRiga: ' || myRiga);
         DBMS_OUTPUT.put_line ('myCircuito: ' || myCircuito);
         DBMS_OUTPUT.put_line ('myCodeTipoRiga: ' || myCodeTipoRiga);

         DBMS_OUTPUT.put_line ('myPrevRiga: ' || myPrevRiga);
         DBMS_OUTPUT.put_line ('myPrevCircuito: ' || myPrevCircuito);
         DBMS_OUTPUT.put_line ('myPrevCodeTipoRiga: ' || myPrevCodeTipoRiga);


         IF (    myRiga != myPrevRiga
             AND myCircuito = myPrevCircuito
             AND myPrevCodeTipoRiga = myCodeTipoRiga)
         THEN
            IF myRiga > myPrevRiga
            THEN
               DBMS_OUTPUT.put_line ('riga:' || myRiga);

               v_sql_1 :=
                     'UPDATE  '
                  || tabella
                  || '  SET attr_desc_riga_01 = '' '' WHERE ATTR_PROG_RIGA IN (myRiga)';

               EXECUTE IMMEDIATE v_sql_1;
            END IF;
         END IF;

         myPrevRiga := myRiga;
         myPrevCircuito := myCircuito;
         myPrevCodeTipoRiga := myCodeTipoRiga;

         DBMS_OUTPUT.put_line ('---FINE---');
      END LOOP;
   END LOOP;
END PROVA;

输出:

SQL> set serverout on
SQL> /

Procedure created.

SQL> exec PROVA;
    ---INIZIO---
    myRiga: 1
    myCircuito: YY
    myCodeTipoRiga: XX
    myPrevRiga:
    myPrevCircuito:
    myPrevCodeTipoRiga:
    ---FINE---
    ---INIZIO---
    myRiga: 2
    myCircuito: BB
    myCodeTipoRiga: AA
    myPrevRiga: 1
    myPrevCircuito: YY
    myPrevCodeTipoRiga: XX
    ---FINE---
    ---INIZIO---
    myRiga: 3
    myCircuito: MM
    myCodeTipoRiga: LL
    myPrevRiga: 2
    myPrevCircuito: BB
    myPrevCodeTipoRiga: AA
    ---FINE---

    PL/SQL procedure successfully completed.

【讨论】:

以上是关于在数组循环中使用游标的主要内容,如果未能解决你的问题,请参考以下文章

Pl/Sql 在for循环中打开游标

Oracle SQL

在不使用循环但使用游标的情况下穿越 NSArray?

mysql存储过程 游标双重循环

在存储过程的循环中使用游标

sqlserver中怎样使用游标for循环