【发布时间】:2023-05-08 19:07:02
【问题描述】:
存在一个共享包,它定义了一个学生记录类型和一个返回学生的函数:
CREATE OR REPLACE PACKAGE shared.student_utils IS
--aggregates related data from several tables
TYPE student_rec IS RECORD (
id student.id%TYPE,
username student.username%TYPE,
name student.name%TYPE,
phone phone.phone%TYPE
/*etc.*/
);
FUNCTION get_student(student_id IN student.id%TYPE) RETURN student_rec;
END;
现在,我正在编写一个包,它为 Apex 应用程序提供一个 API 来使用。特别是,我需要以可以通过 SQL 选择的格式(并显示在 Apex 的报告页面中)提供学生记录和其他相关数据。
到目前为止,我一直在尝试找到在 SQL 中选择数据的最直接方法。显然,记录类型不能在 SQL 中使用,所以我的快速而肮脏的想法是在我的包规范中定义一个表类型,并在我的包规范/正文中定义一个 PIPELINED 函数:
CREATE OR REPLACE PACKAGE my_schema.api IS
TYPE student_tab IS TABLE OF shared.student_utils.student_rec;
FUNCTION get_all_student_data(student_id IN student.id%TYPE) RETURN student_tab PIPELINED;
END;
/
CREATE OR REPLACE PACKAGE BODY my_schema.api IS
FUNCTION get_all_student_data(student_id IN student.id%TYPE) RETURN student_tab PIPELINED IS
BEGIN
PIPE ROW(shared.student_utils.get_student(student_id));
END;
END;
...这让我可以像这样选择它:
SELECT * FROM TABLE(my_schema.api.get_all_student_data(1234));
这行得通,但只为一行构建流水线表是多余的,Oracle 的解释计划似乎同意。
据说在 Oracle 12c 中,应该有更多可用的选项:
More PL/SQL-Only Data Types Can Cross PL/SQL-to-SQL Interface
...但在我的场景中我似乎无法弄清楚。将函数更改为:
FUNCTION get_all_student_data RETURN student_tab IS
r_student_tab student_tab;
BEGIN
r_student_tab(1) := shared.student_utils.get_student(student_id);
RETURN r_student_tab;
END;
...会编译,但我不能像以前那样从中SELECT。
好吧,废话不多说,这是我的实际问题——调用返回记录类型并在 SQL 中选择/操作结果的 PL/SQL 函数的最直接方法是什么?
【问题讨论】:
-
也许这个链接会对你有所帮助,*.com/questions/1020348/…
-
我的个人(!)感觉是:您经常在学生书籍和教程中看到 Oracle 对象类型,它们是许多 PL/SQL 培训中的一个重要主题。然而,实际上对象类型几乎不用于生产应用程序。 “几乎”并不意味着“从不”——但我只是觉得它们在教育中比在生产中处理得更多。
-
@eifla001 在更仔细地阅读了您链接的问题之后,它似乎相当完整地回答了我的问题。我不知道为什么,在我所有的搜索中,我自己从来没有找到这个问题。希望欺骗目标可以帮助下一个人找到它。
标签: sql oracle plsql oracle12c user-defined-types