【问题标题】:Bulk Collect into is storing less no of rows in collection when using LIMIT?Bulk Collect into 使用 LIMIT 时在集合中存储的行数更少?
【发布时间】:2013-08-12 22:02:23
【问题描述】:

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

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

如果在FETCH 语句中将限制设置为100,则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;

【问题讨论】:

    标签: sql collections plsql plsqldeveloper bulk


    【解决方案1】:

    问题是当您在限制设置为 100 的情况下进行循环时,您会丢弃以前的提取结果。

    所以 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;
    

    【讨论】:

    • 感谢 Loki 的回答。这真的很有帮助。我现在明白它的工作原理了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-14
    相关资源
    最近更新 更多