2016-10-13 15 views
0

私の関数をより効率的にする方法を知りました。また、同じテーブルのselectステートメントと同じループ反復中に発生するため、updateステートメントは処理されていないと思います。私はこの機能を効率的かつ実際に動作させるためにどのように書くべきなのだろうと思っていました。私はこの機能を発注時にトリガで使用します。 ありがとうございます。Oracle PL/SQL関数 - 同じループで更新して選択します

create or replace function get_gewicht_product(p_dieet_id number) 
return number 
is 
    cursor c_Rids 
    is 
     select recept_id 
      from relation_6 
     where dieet_id = p_dieet_id; 

    type type_coll_med 
     is table of relation_5%rowtype 
     index by pls_integer; 
    t_med type_coll_med; 

    product_id number; 
    gewicht_id number; 
    restvoorraad_id number; 
    result number; 
begin 

    for r_med in c_Rids 
    loop 
     select * 
      bulk collect into t_med 
      from relation_5 
     where recept_recept_id = r_med.recept_id; 

     for i in 1 .. t_med.count 
     loop 
      select restvoorraad 
       into restvoorraad_id 
       from voorraad 
      where product_product_id=t_med(i).product_product_id; 

      dbms_output.put_line(t_med(i).gewicht); 
      dbms_output.put_line(restvoorraad_id); 

      gewicht_id := t_med(i).gewicht; 
      result := restvoorraad_id-gewicht_id; 

      dbms_output.put_line(result); 

      update voorraad 
       set restvoorraad = result 
      where product_id = t_med(i).product_product_id; 
     end loop; 
    end loop; 

    return 1; 
end get_gewicht_product; 
+0

あなたは身体中の関数名でそれらの前に付ける場合は、P_を使用してパラメータをプレフィックスする必要はありません。例えば"relation_6からrecept_idを選択します。ここで、dieet_id = get_gewicht_product .dieet_id;" –

答えて

1

私は全体の手順を1つのMERGEステートメントに減らすことができると思います。いいえ(ネスト)が必要ループない:

merge into voorraad v 
using 
(
    select r5.product_product_id, r5.gewicht, v.restvoorraad, v.restvoorraad - r5.gewicht as result 
    from relation_6 r6 
    join relation_5 r5 on r5.recept_recept_id= r6.recept_id 
    join voorraad v on v.product_product_id = r5.product_product_id 
    where r6.dieet_id = p_dieet_id 
) t ON (t.product_product_id = v.product_id) 
when matched then update 
    set restvoorraad = t.result; 

内のクエリは、各製品のrestvoorraadの新しい値を計算するためのロジックです。私はすべてのジョインが正しいとは思いませんが、これを正しく計算するSELECTクエリを書くことができれば、それをMERGEステートメントに接続してください。

+0

私はまだマージについて学んだことはありませんが、これは非常に便利です。私は自分の機能(手順)のためにそれを試してみよう。 – Colivar

+0

"t"のselectステートメントが2つ以上のレコードを取得する場合、これは機能しますか? – Colivar

+0

@Colivar:はい、もちろんです。条件を満たすすべての行が更新されます。内部selectが 'product_id'に1つ以上の行を返す場合、' group by 'を適用する必要があります - 内部選択は、ターゲットテーブルの一意のキーごとに1つの行を返さなければなりません。 –

0

カーソルと行単位の処理なしでSQL文を使用すると、パフォーマンスが向上します。

0

私はこのマージが正しいとカーソルよりもはるかに効率的であると考えている:

merge into voorraad v 
using (select r5.* from relation_5 r5 inner join relation_6 r6 on (r6.recept_id = r5.recept_recept_id) where r6.dieet_id=p_dieet_id) r 
on (r.product_product_id = v.product_product_id) 
update set v.restvoorraad = v.restvoorraad_id - r.gewicht; 
関連する問題