2013-05-17 29 views
5

Khi cố gắng sử dụng câu lệnh BULK COLLECT tôi gặp lỗi ORA-00947: not enough values.SỐ LƯỢNG LỚN THU THẬP vào một bảng các đối tượng

Một ví dụ kịch bản:

CREATE OR REPLACE 
TYPE company_t AS OBJECT ( 
    Company   VARCHAR2(30), 
    ClientCnt   INTEGER ); 
/

CREATE OR REPLACE 
TYPE company_set AS TABLE OF company_t;  
/

CREATE OR REPLACE 
FUNCTION piped_set (
    v_DateBegin IN DATE, 
    v_DateEnd IN DATE 
) 
return NUMBER /*company_set pipelined*/ as 
    v_buf company_t := company_t(NULL, NULL); 
    atReport company_set; 
    sql_stmt VARCHAR2(500) := ''; 
begin 

select * BULK COLLECT INTO atReport 
from (
    SELECT 'Descr1', 1 from dual 
    UNION 
    SELECT 'Descr2', 2 from dual) ; 

    return 1; 
end; 

Lỗi này xảy ra tại dòng select * BULK COLLECT INTO atReport.

PL/SQL thẳng hoạt động tốt bằng cách này (vì vậy không cần phải đề cập đến nó như là một giải pháp). Việc sử dụng BULK COLLECT vào loại bảng người dùng là câu hỏi.

Trả lời

9

company_set là bảng của đối tượng và bạn đang chọn giá trị, không phải đối tượng bao gồm các giá trị đó. Điều này sẽ biên dịch:

select * BULK COLLECT INTO atReport 
from (
    SELECT company_t('Descr1', 1) from dual 
    UNION 
    SELECT company_t('Descr2', 2) from dual) ; 

... nhưng khi chạy sẽ ném ORA-22950: cannot ORDER objects without MAP or ORDER methodunion không đặt ngầm để xác định và loại bỏ các bản sao, vì vậy sử dụng union all thay vì:

select * BULK COLLECT INTO atReport 
from (
    SELECT company_t('Descr1', 1) from dual 
    UNION ALL 
    SELECT company_t('Descr2', 2) from dual) ; 
+0

Cảm ơn, @ Alex, mã thực sự đã giúp! Như là một sự tiếp nối của vấn đề, có thể vượt qua kết quả của chèn số lượng lớn như là kết quả hàm pipelined? Hiện tại, tôi nhận được kết quả vào con kiến ​​atReport rồi thực hiện "FOR .. LOOP (pipe_row (atReportRow)) END LOOP;". Có lẽ phần này có thể đơn giản hóa không? – xacinay

+1

@xacinay - không phải với 'thu thập số lượng lớn'; bạn có thể làm nó như là một vòng lặp con trỏ thay vào đó ('cho rec in (select company_t() như comp ...) vòng lặp hàng ống rec.comp; vòng lặp kết thúc;' hoặc tương tự. Tôi tưởng tượng hiệu suất sẽ tương tự. hỏi một câu hỏi mới nếu bạn cố gắng và không thể làm cho nó hoạt động –

+0

Đó chính xác là cách nó hoạt động: 'cho x trong (chọn ..) hàng ống (company_t (x.Company, x.ClientCnt)))'. Tôi chỉ tự hỏi, nó có thể đơn giản hơn. Dù sao, kết quả hiện tại là khá tốt, cảm ơn! – xacinay

Các vấn đề liên quan