Oracle SQL - 带函数的计算列

Oracle SQL - computed column with function

创建计算列并使用函数计算值的解决方案是否可行?

例如

table_1

id   type  date_from    date_to       TOTAL_CURRENT_YEAR (computed column)
-------------------------------------------------------------------
1    A     01.01.2022   01.05.2022    if type = A call function to calculate TOTAL_CURRENT_YEAR  => Select f_calculate_A(date_from,nvl(check_out,sysdate)) from dual)
2    B     01.01.2022   01.05.2022    if type = B call function to calculate TOTAL_CURRENT_YEAR  => Select f_calculate_B(date_from,nvl(check_out,sysdate)) from dual)

如何定义TOTAL_CURRENT_YEAR(计算列)?

Alter table table_1 add  TOTAL_CURRENT_YEAR.........

is it good solution create computed column where use function to calculate value?

如果函数是确定性的(即,如果您给它相同的输入值,那么它将 ALWAYS return 相同的输出)那么您可以使用虚拟列.

由于 SYSDATE 不是确定性函数,您不能在虚拟列中使用它,如果您尝试,您将得到异常:

ORA-54002: only pure functions can be specified in a virtual column expression

如果您要将 NVL(check_out, SYSDATE) 从列定义移动到您的函数内部,那么该函数将不是确定性的(因为它现在依赖于 SYSDATE 和 return 值并且1 秒后的 return 值会有所不同。

因此,使用虚拟列并不是一个好的解决方案。

注意:您可以使用一些 hack,例如在确定性函数中包装对 SYSDATE 的调用以诱使编译器接受它;但这是一个 hack,如果 SQL 引擎缓存函数的输出,它可能会导致意外行为,它期望它是确定性的,因此可以合理地期望能够继续使用缓存的值,然后重用缓存的值而不是从 SYSDATE 重新计算,然后你的时钟会停留一段时间,然后随着缓存更新而向前跳转。


相反,您应该创建一个视图并计算视图中的值。