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
重新计算,然后你的时钟会停留一段时间,然后随着缓存更新而向前跳转。
相反,您应该创建一个视图并计算视图中的值。
创建计算列并使用函数计算值的解决方案是否可行?
例如
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
重新计算,然后你的时钟会停留一段时间,然后随着缓存更新而向前跳转。
相反,您应该创建一个视图并计算视图中的值。