-1

我有一个项目,本质上是一批计算。这取决于相当多的参数,虽然它们不是常量(它们可能会随着时间而改变),但它们不会在批处理上下文中改变。

为了清楚起见,想想增值税率:它可能会随着时间的推移而变化,但是当一个会计期间结束时,它的行为就像一个常数,与结束本身有关。

因为这些参数到处都是,所以我想找到一种方法来尽可能地限制 DB 查找。理想情况下,我会实现一个 DETERMINISTIC 函数,但是,这是不可能的 - 正如相关文档所建议的那样。

有什么想法/建议吗?

先感谢您。

编辑:还请记住,这些值存储在数据库中 - 因为我们可能会保留增值税率,以便我们可以知道它在给定时间点的值。虽然这不是预期的,但与之前某个时期有关的批次可能会再次运行 - 并且需要知道其参数的值,因为它们是当时的值。

DETERMINISTIC 函数的好处是,考虑到它产生一致的结果(相同的输入总是给出相同的输出),如果这些值是常量并且我不想跟踪它们,我会这样做。但是文档清楚地指出,如果一个函数进行数据库查找,它绝不能是确定的。

4

1 回答 1

1

您无法创建“几乎”确定性函数。如果调用正确,您可以创建确定性函数。如果我们假设您正在创建一个简单的函数来计算增值税金额,您可以通过两种方式进行;首先通过直接在函数中引用表:

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

不能将此函数创建为确定性函数,因为表中的值可能会更改。正如文档所说

不要指定此子句来定义使用包变量或以任何可能影响函数返回结果的方式访问数据库的函数

但是,如果您将增值税值作为参数传递,则可以以不同的方式创建函数:

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