在循环中调用表函数以获取数据转储

时间:2015-03-22 11:39:34

标签: database plsql oracle11g oracle-sqldeveloper pipeline

我需要在以下场景中使用表函数。我在一个表中有一个person_ids列表,在另一个表中有一个learning_path_ids列表。所以我想找出是否有员工完成了任何学习途径。为此,我有一个名为Employees_Learning_Chk_f(person_I'd, learning_path_id)的函数,它返回10。因此,通过传递person_idlearning_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));

输出将是这样的:

enter image description here

但我需要以类似的方式获得所有9000名员工的输出。这怎么可能?是否可以使用PIPELINED功能?如果是的话,你能解释一下吗?

注意: 我不允许在数据库中临时创建任何表格。

我正在使用Oracle-SQL Developer连接到Oracle 11g数据库。

1 个答案:

答案 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的作用,可以通过在查询中添加另一个表来消除它。