我需要在以下场景中使用表函数。我在一个表中有一个person_ids列表,在另一个表中有一个learning_path_ids列表。所以我想找出是否有员工完成了任何学习途径。为此,我有一个名为Employees_Learning_Chk_f(person_I'd, learning_path_id)
的函数,它返回1
或0
。因此,通过传递person_id
和learning_path_id
,我可以了解该人是否已完成该学习路径。我需要为组织中的所有员工找到这个以获取数据转储。问题是我们有9000名员工和250条学习路径。所以我必须通过传递所有person_id:learning_path_id组合来循环运行上面的函数来获取数据转储的最终输出。
请注意,人员ID和学习路径之间的关系也会被丢弃,因为我们也需要历史信息(不仅与当前关系相关的详细信息,因为员工之前可能与学习路径有不同的关系) 。
以下是我的方法。
--Defining types required.
CREATE TYPE tf_row AS OBJECT (
person_id NUMBER,
learning_path_id NUMBER,
completion_status NUMBER,
);
/
CREATE TYPE tf__tab IS TABLE OF tf_row;
/
-- Build the table function.
CREATE OR REPLACE FUNCTION get_completion_status (person_id IN NUMBER) RETURN tf_tab AS
l_tab tf_tab := tf_tab();
status_flag number;
--Getting all learning path IDs using a cursor.
cursor c1 is
SELECT distinct learning_path_id
FROM learning_paths;
BEGIN
FOR learnings in c1
LOOP
--Calling an existing function which returns 1 if the employee
--holding this person_id has completed the learning path related to
--this learning_path_id.
select Employees_Learning_Chk_f(person_id, learnings.learning_path_id)
into status_flag
From Dual;
--If the learning path has been completed, the information is
--inserted to in memory table.
If dual = 1 then
l_tab.extend;
l_tab(l_tab.last) := tf_row(person_id, learnings.learning_path_id, status_flag);
end if;
END LOOP;
RETURN l_tab;
END;
现在我可以通过传递person_id来调用上面的函数,如下所示......
select from table (get_completion_status(123456));
输出将是这样的:
但我需要以类似的方式获得所有9000名员工的输出。这怎么可能?是否可以使用PIPELINED功能?如果是的话,你能解释一下吗?
注意: 我不允许在数据库中临时创建任何表格。
我正在使用Oracle-SQL Developer连接到Oracle 11g数据库。
答案 0 :(得分:1)
您可以使用笛卡尔积(交叉连接)在单个查询中执行此操作:
select p.person_id, l.learning_path_id, Employees_Learning_Chk_f(p.person_id, l.learning_path_id) as status
from per_all_people_f p
cross join ota_learning_paths l;
如果您可以描述Employees_Learning_Chk_f的作用,可以通过在查询中添加另一个表来消除它。