“时我第一次呼叫功能它返回第一staff_id = 1;当我第二次呼叫功能它返回第一staff_id = 2;当我n个时间呼叫功能它返回第一staff_id = N;且之后,循环再次重复“
程序思维通常是一种代码味道。关系数据库用于处理数据集。但是,到底什么时候,让我们享受一些午餐时间的乐趣吧:
我们需要一个包,因为包变量允许我们维护函数调用的状态。 (有这样做的其他方式,如上下文的命名空间,但一个包是容易实现的。)
create or replace package pkg_test is
function get_staff_id (p_dept_id number) return number;
end pkg_test ;
/
create or replace package body pkg_test is
-- variables to maintain state across function calls
ids_nt dbms_utility.number_array;
idx number := 0;
last_dept_id number := 0;
function get_staff_id (p_dept_id number) return number
is
return_value number;
begin
if idx = 0
or last_dept_id != p_dept_id
then
select staff_id
bulk collect into ids_nt
from staff
where dept_id = p_dept_id;
last_dept_id := p_dept_id;
idx := 0;
end if;
idx := idx + 1;
return_value := ids_nt(idx);
if idx = ids_nt.count() then
idx := 0;
end if;
return return_value;
end get_staff_id ;
end pkg_test ;
/
注意
- 保持这样的全局状态一般不考虑好实践。它在这里工作,但在更复杂的过程中,状态很容易被我们不期望的调用改变。
- 状态保持在会话级别。两个单独的会话将获得两组数据,而不是一个交错组。所以对于使用连接池的应用程序来说这不是一个好的实现。
来源
2017-05-26 11:32:14
APC
这不是很清楚。你有一张表,但你想要一个函数来对这张表进行查询,但是在一个双重查询中?你不能简单地查询你的表吗?这个函数的返回类型应该是什么。此外,请发布数据作为格式化文本,[不截图](http://meta.stackoverflow.com/questions/285551/why-may-i-not-upload-images-of-code-on-so-when-问一个问题/ 285557#285557) – Aleksej
那么你想从一个你不从纯SQL获得的函数中获得什么好处?从dept_id = 443'的staff中选择staff_id? – APC
当我第一次调用函数时,首先返回staff_id = 1; 当我第二次调用函数时,它首先返回staff_id = 2; 当我n次调用函数时,首先返回staff_id = n; 然后循环再次重复 – Tiko