Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

oracle FOR LOOP không lặp lại trong SYS_REFCURSOR

Lưu ý các nhận xét mở rộng sau:

Có lẽ trung tâm của câu hỏi là sự hiểu lầm về con trỏ là gì. Nó không phải là một vùng chứa đầy các bản ghi, nó là một đặc tả cho một tập hợp kết quả, tại một thời điểm, dựa trên một truy vấn SQL duy nhất. Vì vậy, nếu bạn

open rc for select id from table1;

và chuyển rc quay lại trình gọi, bạn không chuyển bất kỳ dữ liệu nào, bạn đang chuyển một con trỏ đến vùng bộ nhớ riêng có chứa một truy vấn đã chuẩn bị. Bạn không đẩy kết quả, người gọi sẽ kéo chúng. Nó giống như một chương trình mà người gọi sẽ thực thi để tìm nạp các hàng. Bạn không thể mở thêm một chút nữa để thêm một hàng khác, mà tôi nghĩ đó là điều bạn đang hy vọng.

Để sử dụng tập hợp trong con trỏ trong một thủ tục, loại tập hợp phải được tạo dưới dạng một đối tượng lược đồ riêng biệt (mặc dù tất nhiên bạn có thể sử dụng lại các loại tập hợp trong các thủ tục khác, vì vậy nó không quá hạn chế).

Nếu bạn không thể tạo một loại, hãy xem những loại nào đã tồn tại mà bạn có thể sử dụng:

select owner, type_name
from   all_coll_types t
where  t.coll_type = 'TABLE'
and    t.elem_type_name = 'NUMBER';

Ví dụ:

create or replace type number_tt as table of number;

create table table1 (id primary key, currency, t_id) as
    select 10, 'GBP', 'PB1' from dual union all
    select 15, 'GBP', 'RB' from dual union all
    select 20, 'GBP', 'CC' from dual union all
    select 25, 'AUD', 'DC' from dual;

create table table2 (id,country,account) as
    select 10, 'UK', 'PB1' from dual union all
    select 15, 'Wales', 'RB' from dual union all
    select 20, 'SH', 'CC' from dual;

Bây giờ thủ tục có thể là:

create or replace procedure myproc
    ( rc out sys_refcursor)
as
    l_names number_tt;
begin
    select id bulk collect into l_names
    from   table1
    where  currency = 'GBP';

    open rc for
        select t.id,t.country,t.account from table2 t
        where  t.id member of l_names;
end myproc;

Đầu ra con trỏ:

        ID COUNT ACC
---------- ----- ---
        10 UK    PB1
        15 Wales RB
        20 SH    CC

(Tôi đã xóa i_id trong thủ tục của bạn vì tôi không rõ bạn muốn sử dụng nó như thế nào.)

Có lẽ đây là một phiên bản đơn giản hóa của vấn đề thực tế, vì như vậy bạn có thể sử dụng truy vấn đầu tiên làm truy vấn con và bạn sẽ không cần bộ sưu tập:

create or replace procedure myproc
    ( rc out sys_refcursor)
as
begin
    open rc for
        select t.id,t.country,t.account from table2 t
        where  t.id in
               ( select id 
                 from   table1
                 where  currency = 'GBP' );
end myproc;

hoặc chỉ tham gia nó, như Littlefoot đã đề xuất:

create or replace procedure myproc
    ( rc out sys_refcursor)
as
begin
    open rc for
        select t2.id, t2.country, t2.account
        from   table1 t1
               join table2 t2 on t2.id = t1.id
        where  t1.currency = 'GBP';
end myproc;

Tuy nhiên, bạn đã nhận xét về câu trả lời đó rằng bạn không thể làm điều đó vì yêu cầu của bạn dường như là làm điều đó thông qua một bộ sưu tập, một vòng lặp, một số băng keo, hai con mèo và một máy phát điện nhiệt hạch.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Toán tử nối chuỗi trong Oracle, Postgres và SQL Server

  2. Làm thế nào để ánh xạ TYPE TABLE OF VARCHAR2 (5) trong java?

  3. Oracle SQL Tạo PDF từ dữ liệu

  4. Làm cách nào để sử dụng ngày hiện tại trong truy vấn HQL với cơ sở dữ liệu Oracle?

  5. ORA-01403 không tìm thấy dữ liệu lỗi