Oracle 11g - 如何使用表连接从函数返回记录
Posted
技术标签:
【中文标题】Oracle 11g - 如何使用表连接从函数返回记录【英文标题】:Oracle 11g - how to return record from function with table join 【发布时间】:2019-02-19 09:21:23 【问题描述】:在 Oracle 11g 中,我试图从与表连接的函数调用中返回多列。此函数将employee_id 作为输入,并应将first_name 和last_name 作为employees 表中的两个单独列返回。
我创建了一个类型
create or replace
type mytype as object
( val_1 varchar2(100),
val_2 number
);
/
和功能
create or replace
function myfunc(p_in number) return mytype is
v_deptname varchar2(100);
v_mgrid number;
begin
select department_name,manager_id into v_deptname,v_mgrid from DEPARTMENTS where department_id = p_in;
return
mytype(v_deptname,v_mgrid);
end;
/
两者都已成功创建。但是当我执行函数时,
select employee_id, salary, myfunc(department_id) from EMPLOYEES where employee_id in(100,101);
结果如下,
EMPLOYEE_ID SALARY
----------- ----------
MYFUNC(DEPARTMENT_ID)(VAL_1, VAL_2)
--------------------------------------------------------------------------------
100 24000
MYTYPE('Executive', 100)
101 17000
MYTYPE('Executive', 100)
但我希望我的结果像,
EMPLOYEE_ID SALARY VAL_1 VAL_2
----------- ---------- ------------------------------ ----------
100 24000 Executive 100
101 17000 Executive 100
请帮助实现这一目标。 谢谢
【问题讨论】:
您对变量做了一些不必要的使用。您必须简化代码,如下面的演示所示。此外,由于您使用的是标量变量,因此您的代码中的许多员工往往会失败。 【参考方案1】:好吧,您可能还缺少另一种类型,基于MYTYPE
。
这是一个示例(我使用 Scott 的架构,因为我没有您的表)。我已将DEPTNO
添加到MYTYPE
中,以便能够将结果(由函数返回)与EMP
表连接起来。
这就是你所拥有的:
SQL> create or replace type mytype as object
2 (deptno number,
3 dname varchar2(20),
4 loc varchar2(20));
5 /
Type created.
这就是你所缺少的:
SQL> create or replace type mytab as table of mytype;
2 /
Type created.
一个函数:注意第9行:
SQL> create or replace function myfunc (p_in number) return mytab is
2 v_dname varchar2(20);
3 v_loc varchar2(20);
4 begin
5 select dname, loc
6 into v_dname, v_loc
7 from dept
8 where deptno = p_in;
9 return mytab(mytype(p_in, v_dname, v_loc));
10 end myfunc;
11 /
Function created.
测试:
SQL> select * from table(myfunc(10));
DEPTNO DNAME LOC
---------- -------------------- --------------------
10 ACCOUNTING NEW YORK
SQL>
SQL> select e.ename, e.sal, m.dname, m.loc
2 from emp e join table(myfunc(e.deptno)) m on m.deptno = e.deptno
3 where e.deptno = 10
4 order by m.dname, e.ename;
ENAME SAL DNAME LOC
---------- ---------- -------------------- --------------------
CLARK 2450 ACCOUNTING NEW YORK
KING 10000 ACCOUNTING NEW YORK
MILLER 1300 ACCOUNTING NEW YORK
SQL>
【讨论】:
谢谢@Littlefoot。这件事完美无缺。我认为我们可以加入 emp 表并在 1=1 上运行。这可以在没有 m.deptno = e.deptno 的情况下工作。 不客气。诚然,您可以通过这种方式加入它,但是 - 拥有 DEPTNO - 您可能会在其他地方使用一些灵活性。没关系,我很高兴你解决了这个问题。【参考方案2】:你可以尝试如下:
--Tables
CREATE TABLE dept (
deptno NUMBER,
dname VARCHAR2 (20),
loc VARCHAR2 (20)
);
/
CREATE TABLE employee (
employee_id NUMBER,
salary NUMBER
);
代码:
CREATE OR REPLACE TYPE mytype AS OBJECT (
deptno NUMBER,
dname VARCHAR2 (20),
loc VARCHAR2 (20)
);
CREATE OR REPLACE TYPE mytab AS TABLE OF mytype;
CREATE OR REPLACE FUNCTION myfunc ( p_in NUMBER)
RETURN mytab
IS
v_var mytab := mytab ();
BEGIN
SELECT
mytype (
deptno,
dname,
loc
)
BULK COLLECT INTO
v_var
FROM
dept
WHERE
deptno = p_in;
return (v_var);
END myfunc;
/
执行:
SELECT
e.*,
t.deptno,
t.dname
FROM
employee e
CROSS JOIN
TABLE ( myfunc (100) ) t ;
输出:
Employee_Id SALARY DEPT DNAME
--------- ------ ---- ------
1001 20000 100 Executive
1002 25000 100 Executive
【讨论】:
以上是关于Oracle 11g - 如何使用表连接从函数返回记录的主要内容,如果未能解决你的问题,请参考以下文章