sql >> データベース >  >> RDS >> Oracle

ループをトラバースして、繰り返される名前を見つけます

    このため、PL/SQLのループ内でループを実行しないでください。SQLを使用してデータをすぐに使用できるようにします。

    まず、いくつかのテストデータを使用してテーブルを作成します(データ型を推測しています-独自のものに置き換えます):

    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
    /
    

    mail_sendに送信したいもの 各product_holderの手順 product_noを含むコレクション(配列)です およびproduct_catalogue 。したがって、最初にこれら2つの要素を含む型:

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

    次に、そのタイプのネストされたテーブルタイプ(コレクションタイプ):

    create type t_prod_cat_no_table as
       table of t_prod_cat_no
    /
    

    プロシージャmail_send 次に、product_holderを受け入れる必要があります およびコレクションタイプ:

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

    (私はdbms_outputを使用してメールの作成をシミュレートしています。)

    次に、SQLでgroup by product_holderを実行できます。 そして、SQLにデータを含むコレクションを生成させます:

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

    上記のブロックの出力は次のようになります。

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

    GROUP BYを使用してSQLで実行する PL / SQLからSQLへの1回の呼び出しですべてを提供します。これは、product_holderの個別のセットを取得するための最初の1回の呼び出しよりもはるかに効率的です。 、それをループしてから、product_holderごとに1回呼び出します 各ホルダーの製品を入手します。

    更新:

    order byを追加しました collectに 上記のコードの関数を使用して、データがコレクションに入力される順序を制御できることを示します。



    1. DBテーブルへのセッションの保存が機能しない(Zend_Session_SaveHandler_DbTableを使用)

    2. Ruby on Rails:postgresqlのdatabase.ymlを編集するにはどうすればよいですか?

    3. 文字列演算子「+」はとても単純ですか?

    4. mysql_close(connection)を使用する必要がありますか?