【发布时间】:2018-09-30 14:01:03
【问题描述】:
Oracle 定义了几个结构,这些结构利用了看似惰性求值但实际上是短路的结构。
例如:
x := case when 1 = 2 then count_all_prime_numbers_below(100000000)
else 2*2
end;
永远不会调用函数 count_all(...)。
不过,我更感兴趣的是看起来像常规函数调用的语法:
x := coalesce(null, 42, hundreth_digit_of_pi());
Hundreth_digit_of_pi() 不会被调用,因为 coalesce 不是一个常规函数,而是一种语法糖,看起来像一个 - 对于常规的,参数会在函数被调用时进行评估。
问题是: 是否可以在 plsql 中定义一个行为相同的自定义过程/函数?
如果你不相信我会举一个有用的例子:
我们使用“框架”进行日志记录。 要跟踪你称之为过程的东西:
trace_something('A text to be saved somewhere');
Trace_something 是执行以下步骤的“pragma 自主事务”过程: 1.查看是否启用了任何跟踪方法(例如文件/数据库表) 2. 对于每个启用的方法,使用该方法将参数保存在某处。 3. 如果保存到DB,提交。
在构建要跟踪的实际字符串时可能会出现问题,如果一开始甚至没有启用跟踪,我们就不想花费大量时间。
目标是,用伪代码:
procedure lazily_trace_something(some_text lazily_eval_type) {
if do_i_have_to_trace() = TRUE then
trace_something(evaluate(some_text));
else
NULL; -- in which case, some_text doesn't get evaluated
end if;
}
/*
*/
lazily_trace_something(first_50_paragraphs_of_lorem_ipsum(a_rowtype_variable));
可以在plsql中完成吗?
【问题讨论】:
-
我不这么认为。
-
This question 关于功能参数可能与您所要求的类似。
-
@Glenn 感谢您的评论,不幸的是它并没有为我剪掉它(在我的具体情况下,'first_50_paragraphs' 将行类型作为参数并且不是全局可见的,我已经编辑相应的问题)。我也尽可能避免立即执行。
标签: oracle plsql lazy-evaluation short-circuiting