Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Lintasi loop untuk menemukan nama yang berulang

Jangan lakukan loop di dalam loop di PL/SQL untuk ini - gunakan SQL untuk memberi Anda data yang siap digunakan.

Pertama kita buat tabel Anda dengan beberapa data uji (saya kira tipe data - Anda ganti dengan milik Anda sendiri):

create table product_master (
   product_no        varchar2(10)
 , product_holder    varchar2(10)
 , product_catalogue varchar2(10)
)
/

insert into product_master values ('1', 'SMITH', 'TEMP')
/
insert into product_master values ('2', 'SMITH', 'TEMP')
/
insert into product_master values ('3', 'HARRY', 'ARCH')
/
insert into product_master values ('4', 'TOM'  , 'DEPL')
/
commit
/

Apa yang ingin kami kirim ke mail_send prosedur untuk setiap product_holder adalah kumpulan (array) yang berisi product_no dan product_catalogue . Jadi pertama jenis yang berisi dua elemen tersebut:

create type t_prod_cat_no as object (
   product_no        varchar2(10)
 , product_catalogue varchar2(10)
)
/

Dan kemudian tipe tabel bersarang (tipe koleksi) dari tipe itu:

create type t_prod_cat_no_table as
   table of t_prod_cat_no
/

Prosedur mail_send maka harus menerima product_holder dan jenis koleksi:

create or replace procedure mail_send (
   p_parameter        in varchar2
 , p_product_holder   in varchar2
 , p_product_cats_nos in t_prod_cat_no_table
)
is
begin
   dbms_output.put_line('-- BEGIN '||p_parameter||' --');
   dbms_output.put_line('Dear '||p_product_holder);
   dbms_output.put_line('Your products are:');
   for i in 1..p_product_cats_nos.count loop
      dbms_output.put_line(
         'Catalogue: '||p_product_cats_nos(i).product_catalogue||
         ' - No: '||p_product_cats_nos(i).product_no
      );
   end loop;
end mail_send;
/

(Saya hanya menggunakan dbms_output untuk mensimulasikan pembuatan email.)

Kemudian Anda dapat dalam SQL melakukan group by product_holder dan biarkan SQL menghasilkan koleksi yang berisi data:

begin
   for holder in (
      select pm.product_holder
           , cast(
                collect(
                   t_prod_cat_no(pm.product_no,pm.product_catalogue)
                   order by pm.product_catalogue
                          , pm.product_no
                ) as t_prod_cat_no_table
             ) product_cats_nos 
        from product_master pm
       group by pm.product_holder
       order by pm.product_holder
   ) loop
      mail_send(
         'PRODMASTER'
       , holder.product_holder
       , holder.product_cats_nos
      );
   end loop;
end;
/

Output dari blok di atas adalah:

-- BEGIN PRODMASTER --
Dear HARRY
Your products are:
Catalogue: ARCH - No: 3
-- BEGIN PRODMASTER --
Dear SMITH
Your products are:
Catalogue: TEMP - No: 1
Catalogue: TEMP - No: 2
-- BEGIN PRODMASTER --
Dear TOM
Your products are:
Catalogue: DEPL - No: 4

Melakukannya dalam SQL dengan GROUP BY memberi Anda segalanya dalam satu panggilan dari PL/SQL ke SQL, yang jauh lebih efisien daripada satu panggilan pertama untuk mendapatkan rangkaian product_holder yang berbeda , ulangi itu, lalu satu panggilan per product_holder untuk mendapatkan produk untuk setiap pemegang.

PEMBARUAN:

Menambahkan order by ke collect fungsi dalam kode di atas untuk menunjukkan bahwa Anda memiliki kendali atas urutan data yang diisi dalam koleksi.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. jalankan kode sql oracle online

  2. Apakah Oracle NetSuite Advanced PDF Template memiliki Fungsi Group by dan SUM?

  3. Mengurai Komentar XML di Oracle

  4. Konversikan keep density_rank dari kueri Oracle menjadi postgres

  5. Oracle INSERT menjadi dua tabel dalam satu query