-1

私は、本質的に計算のバッチであるプロジェクトを持っています。かなりの数のパラメーターに依存しますが、それらは定数ではありませんが (時間の経過とともに変化する可能性があります)、バッチ コンテキストで変化する方法はありません。

明確にするために、VAT 率について考えてみてください。時間の経過とともに変化する可能性がありますが、会計期間を締めると、決算自体に関係するものに対して定数のように動作します。

これらのパラメーターはあちこちにあるため、DB ルックアップをできるだけ制限する方法を見つけたいと考えています。理想的には、DETERMINISTIC関数を実装しますが、これは問題外です-関連ドキュメントで示唆されています。

アイデア/提案はありますか?

前もって感謝します。

編集: これらの値はデータベースに保存されることにも注意してください。特定の時点での値を知ることができるように、VAT 率を保持する場合があるためです。予期されていませんが、以前の期間に関するバッチが再度実行される可能性があります。その場合、そのパラメータの値を当時のように知る必要があります。

DETERMINISTIC 関数の利点は、一貫性のある結果 (同じ入力は常に同じ出力を与える) を生成するという事実を考えると、これらの値が定数であり、それらを追跡したくない場合に行うことです。しかし、ドキュメントには、関数が db ルックアップを行う場合、DETERMINISTIC であってはならないことが明確に記載されています。

4

1 に答える 1

1

「ほぼ」決定論的な関数を作成することはできません。正しく呼び出すと、決定論的関数を作成できます。VAT の金額を計算する単純な関数を作成していると仮定すると、2 つの方法で実行できます。まず、関数でテーブルを直接参照します。

create or replace function calculate_vat is ( 
       P_Sale_Value in number ) return number is

   l_vat number;

begin

   select trunc(vat_rate * P_Sale_Value, 2) into l_vat
     from vat_table
    where ...

   return l_vat;

end;
/

これは次のように呼ばれます。

select sale_value, calculate_vat(sale_value)
  from sales_table

表の値が変更される可能性があるため、この関数を決定論的として作成することはできません。ドキュメントが言うように:

パッケージ変数を使用する関数や、関数の戻り結果に影響を与える可能性のある方法でデータベースにアクセスする関数を定義する場合は、この句を指定しないでください。

ただし、VAT 値をパラメーターとして渡すと、別の方法で関数を作成できます。

create or replace function calculate_vat is ( 
       P_Sale_Value in number
     , P_VAT_Rate in number
       ) return number deterministic is

begin    
   return trunc(P_VAT_Rate* P_Sale_Value, 2);    
end;
/

次に、VAT テーブルで JOIN を使用して呼び出して、有効な決定論的関数を提供できます。

select s.sale_value, calculate_vat(s.sale_value, v.vat_rate)
  from sales_table s
  join vat_table v
    on ...
 where ...
于 2013-11-13T13:38:56.170 に答える