1

我编写了以下匿名 PL SQL 块。

但是,该行 dbms_output.put_line(total_tckt_col.LAST)给我的输出是366(在 DBMS_OUTPUT 中是 SQL Developer),当没有设置限制时这是正确的。

如果100FETCH语句中设置了限制,那么dbms_output.put_line(total_tckt_col.LAST)给我66.

我在这里做错了什么?

    DECLARE

           CURSOR cur_total_tckt  
            is
                select  t.ticket_id ticket_id, t.created_date created_date, t.created_by created_by, t.ticket_status ticket_status, 
                t.last_changed last_changed, h.created_date closed_date
                    from n01.cc_ticket_info t
                    inner join n01.cc_ticket_status_history h 
                    on (t.ticket_id = h.ticket_id)
                    where t.last_changed >= '6/28/2012 17:28:59' and t.last_changed < (sysdate + interval '1' day);

        type total_tckt_colcn
        is
            TABLE OF cur_total_tckt%rowtype;
            total_tckt_col total_tckt_colcn;
            total_coach_col total_tckt_colcn;
        begin

        total_tckt_col  := total_tckt_colcn ();
        total_coach_col := total_tckt_colcn ();
            OPEN cur_total_tckt;
            loop
                fetch cur_total_tckt bulk collect into total_tckt_col;
 --  fetch cur_total_tckt bulk collect into total_tckt_col limit 100;
            EXIT
            WHEN (cur_total_tckt%NOTFOUND);
            END LOOP ;
            CLOSE cur_total_tckt;   

            dbms_output.put_line(total_tckt_col.LAST);  

            FOR i IN total_tckt_col.first..total_tckt_col.last
            LOOP

            dbms_output.put_line(i);

            END LOOP;
        end;
4

1 回答 1

3

问题是,当您在 limit 设置为 100 的情况下进行循环时,您将丢弃以前的 fetch 结果。

因此,每次循环时都会提取 3 次 100 行,然后在最后一轮中提取 66 行,因此您得到的结果为 66。

您需要累积所有结果才能获得正确的计数。

要正确使用带限制的批量收集,请参阅此示例:

PROCEDURE process_all_rows (limit_in IN PLS_INTEGER DEFAULT 100)
IS
    CURSOR employees_cur 
    IS 
        SELECT * FROM employees;

    TYPE employees_aat IS TABLE OF employees_cur%ROWTYPE
        INDEX BY PLS_INTEGER;

    l_employees employees_aat;
BEGIN   
    OPEN employees_cur;
    LOOP
        FETCH employees_cur 
            BULK COLLECT INTO l_employees LIMIT limit_in;

        FOR indx IN 1 .. l_employees.COUNT 
        LOOP
            analyze_compensation (l_employees(indx));
        END LOOP;

        EXIT WHEN l_employees.COUNT < limit_in;

   END LOOP;

   CLOSE employees_cur;
END process_all_rows;

因此,您的 for 循环应该位于正常循环中,您可以在其中使用限制进行批量收集。

所以正确的代码将是:

DECLARE

           CURSOR cur_total_tckt  
            is
                select  t.ticket_id ticket_id, t.created_date created_date, t.created_by created_by, t.ticket_status ticket_status, 
                t.last_changed last_changed, h.created_date closed_date
                    from n01.cc_ticket_info t
                    inner join n01.cc_ticket_status_history h 
                    on (t.ticket_id = h.ticket_id)
                    where t.last_changed >= '6/28/2012 17:28:59' and t.last_changed < (sysdate + interval '1' day);

        type total_tckt_colcn
        is
            TABLE OF cur_total_tckt%rowtype;
            total_tckt_col total_tckt_colcn;
            total_coach_col total_tckt_colcn;
        begin

        total_tckt_col  := total_tckt_colcn ();
        total_coach_col := total_tckt_colcn ();
            OPEN cur_total_tckt;
            loop

             fetch cur_total_tckt bulk collect into total_tckt_col limit 100;


            dbms_output.put_line(total_tckt_col.LAST);  

            FOR i IN total_tckt_col.first..total_tckt_col.last
            LOOP

            dbms_output.put_line(i);

            END LOOP;

            EXIT
            WHEN (cur_total_tckt%NOTFOUND);
            END LOOP ;
            CLOSE cur_total_tckt;
        end;
于 2013-08-11T13:57:41.570 回答