有没有办法重新启动游标?神谕

时间:2012-09-27 21:27:22

标签: sql oracle

我正在尝试做以下事情:

for(int i = 0; i<10; i++)
{
    for(int j = 0; j<10; j++)
    {
        Blah;
    }
}

//As you can see each time that there is a different i, j starts at 0 again.

在Oracle中使用游标。但是,如果我是正确的,在我从游标中获取所有行后,它将不会重新启动。有没有办法做到这一点?

这是我的sql:

CREATE OR REPLACE PROCEDURE SSACHDEV.SyncTeleappWithClientinfo
as
teleCase NUMBER;

CURSOR TeleAppCursor
is
    Select 
        distinct(casenbr)
    from TeleApp;


CURSOR ClientInfoCursor
is
    Select casenbr 
    from clientinfo 
    where trim(cashwithappyn) is null;

BEGIN

    open TeleAppCursor;
    open ClientInfoCursor;

    LOOP
        fetch TeleAppCursor into teleCase;
        EXIT when TeleAppCursor%NOTFOUND;

        LOOP
            fetch ClientInfoCursor into clientCase;
            EXIT when ClientInfoCursor%NOTFOUND;
                if clientCase = teleCase then

                    update ClientInfo 
                    set cashwithappyn = (select cashwithappyn from teleapp where casenbr = clientCase) 
                    where casenbr = clientCase;

                    break;
                end if;
        END LOOP;
    END LOOP;

END;

我在网上查了一下,却找不到任何相关信息。

2 个答案:

答案 0 :(得分:2)

您可以使用表变量来存储sql语句的结果,然后在表上循环任意次数,而不是重新启动Cursor。

以下是使用SQL Fiddle Sample数据的示例。

DECLARE 
    CURSOR c1 IS 
      SELECT id, 
             TYPE, 
             details 
      FROM   supportcontacts; 

    TYPE contactrec 
      IS TABLE OF c1%ROWTYPE INDEX BY BINARY_INTEGER; 

    acontact    c1%ROWTYPE; 
    contactlist CONTACTREC; 
    counter     INTEGER; 
BEGIN 
    counter := 0; 

    OPEN c1; 

    LOOP 
        FETCH c1 INTO acontact; 

        IF c1%FOUND THEN 
          counter := counter + 1; 
        END IF; 

        Contactlist(counter) := acontact; 

        IF c1%NOTFOUND THEN 
          EXIT; 
        END IF; 
    END LOOP; 

    CLOSE c1; 



    FOR i IN 1..5 LOOP 
        FOR j IN 1..counter LOOP 
            dbms_output.Put_line(Contactlist(j).type  || ' ' || Contactlist(j).details); 
        END LOOP; 
    END LOOP; 
END; 

/ 

输出

Email admin@sqlfiddle.com
Twitter @sqlfiddle
Email admin@sqlfiddle.com
Twitter @sqlfiddle
Email admin@sqlfiddle.com
Twitter @sqlfiddle
Email admin@sqlfiddle.com
Twitter @sqlfiddle
Email admin@sqlfiddle.com
Twitter @sqlfiddle

这是SQL Fiddle,但我无法弄清楚如何查看dbms_output的输出

答案 1 :(得分:0)

您根本不需要第二个游标,只需使用Oracle中的set操作来更新相应的记录,而无需自己手动搜索它们:

DECLARE
    v_teleCase      TeleApp.teleCase%TYPE;
    v_cashwithappyn TeleApp.cashwithappyn%TYPE

    CURSOR TeleAppCursor
    is
        Select 
            distinct casenbr, cashwithappyn
        from TeleApp;

BEGIN

    open TeleAppCursor;

    LOOP
        fetch TeleAppCursor into v_teleCase, v_cashwithappyn;
        EXIT when TeleAppCursor%NOTFOUND;

        UPDATE ClientInfo
        SET cashwithappyn = v_cashwithappyn
        WHERE casenbr = v_teleCase
        AND trim(cashwithappyn) is null;

    END LOOP;

END;

没有与列名相同的变量也是个好主意。