sql >> Database >  >> RDS >> Oracle

Doorloop de lus om herhaalde namen te vinden

Maak hiervoor geen lussen binnen lussen in PL/SQL - gebruik SQL om u de gegevens klaar voor gebruik te geven.

Eerst maken we uw tabel met enkele testgegevens (ik vermoed datatypes - u vervangt deze door uw eigen):

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
/

Wat we willen verzenden naar mail_send procedure voor elke product_holder is een verzameling (array) met product_no en product_catalogue . Dus eerst een type dat deze twee elementen bevat:

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

En dan een genest tabeltype (verzamelingstype) van dat type:

create type t_prod_cat_no_table as
   table of t_prod_cat_no
/

De procedure mail_send moet dan de product_holder accept accepteren en het collectietype:

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;
/

(Ik gebruik gewoon dbms_output om het bouwen van een e-mail te simuleren.)

Dan kun je in SQL een group by product_holder en laat SQL de verzameling met de gegevens genereren:

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;
/

De uitvoer van het bovenstaande blok is:

-- 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

Doen in SQL met een GROUP BY geeft u alles in één aanroep van PL/SQL naar SQL, wat een stuk efficiënter is dan de eerste aanroep om de afzonderlijke set van product_holder te krijgen , loop daar overheen en dan één aanroep per product_holder om de producten voor elke houder te krijgen.

BIJWERKEN:

Toegevoegd order by naar de collect functie in de bovenstaande code om te laten zien dat u controle heeft over de volgorde waarin de gegevens in de verzameling worden ingevuld.



  1. mysql herstellen naar andere database

  2. Grote hoeveelheden gegevens verwerken in PHP zonder browsertime-out

  3. om een ​​bepaalde rij uit de database en de html-tabel te verwijderen op de bijbehorende knop klik

  4. lees/schrijf unicode-gegevens in MySql