我试图在两种情况下返回记录表:
当我使用该功能时,一切正常,但当我试图将其转换为匿名块时,我收到上述错误。 以下是代码:
对于功能:
create or replace
function get_info(p_city varchar2) return info_type_table
as
l_info info_type_table := info_type_table();
begin
for i in (select e.employeeid,
e.lastname,
c.customerid,
c.companyname,
o.orderid,
o.orderdate
from ntw_employees e
inner join
ntw_orders o
on e.employeeid = o.employeeid
inner join
ntw_customers c
on o.customerid = c.customerid
where e.city = p_city)
loop
l_info.extend;
l_info(l_info.count) := (info_type(i.employeeid, i.lastname, i.customerid, i.companyname, i.orderid, i.orderdate));
end loop;
return l_info;
end;
这是匿名阻止:
declare
type info_type is record
(
emp_no number(3),
lastname varchar2(26),
cust_no varchar2(5),
CO_name varchar2(50),
orderid number(5),
orderdate date
);
type info_type_table is table of info_type;
l_info info_type_table := info_type_table();
begin
for i in (select e.employeeid,
e.lastname,
c.customerid,
c.companyname,
o.orderid,
o.orderdate
from ntw_employees e
inner join
ntw_orders o
on e.employeeid = o.employeeid
inner join
ntw_customers c
on o.customerid = c.customerid
where e.city = 'London')
loop
l_info.extend;
l_info(l_info.count) := (info_type(i.employeeid, i.lastname, i.customerid, i.companyname, i.orderid, i.orderdate));
dbms_output.put_line('angajat = ' || i.employeeid);
end loop;
end;
有人能解释一下我的匿名街区有什么问题吗?
谢谢。
答案 0 :(得分:5)
您的函数(可能)是指一个名为info_type
的对象类型。您的匿名块正在使用记录类型。记录类型没有构造函数。您必须单独分配每个列,并具有记录类型变量:
...
l_info_rec info_type;
begin
...
loop
l_info.extend;
l_info_rec.emp_no := i.employeeid;
l_info_rec.lastname := i.lastname;
l_info_rec.cust_no := i.customerid;
l_info_rec.CO_name := i.companyname;
l_info_rec.orderid := i.orderid;
l_info_rec.orderdate := i.orderdate;
l_info(l_info.count) := l_info_rec;
dbms_output.put_line('angajat = ' || i.employeeid);
end loop;
end;
您还可以使用显式游标并使用返回的行:
declare
cursor c is select e.employeeid,
e.lastname,
c.customerid,
c.companyname,
o.orderid,
o.orderdate
from ntw_employees e
inner join
ntw_orders o
on e.employeeid = o.employeeid
inner join
ntw_customers c
on o.customerid = c.customerid
where e.city = 'London';
type info_type_table is table of c%rowtype;
l_info info_type_table := info_type_table();
begin
for r in c
loop
l_info.extend;
l_info(l_info.count) := r;
dbms_output.put_line('angajat = ' || r.employeeid);
end loop;
end;
/
或者甚至将bulk collect
直接输入您的表格类型:
declare
cursor c is select e.employeeid,
...
where e.city = 'London';
type info_type_table is table of c%rowtype;
l_info info_type_table;
begin
open c;
fetch c bulk collect into l_info;
close c;
for i in 1..l_info.count loop
dbms_output.put_line('angajat = ' || l_info(i).employeeid);
end loop;
end;
/
...使用循环只显示该表中的值。
答案 1 :(得分:1)
基本上逐行处理类似于慢速处理。始终尽量使用BULK collect来避免系统性能故障。希望在片段下方有所帮助。
--Function with Bulk collect
CREATE OR REPLACE FUNCTION get_info(
p_city VARCHAR2)
RETURN info_type_table
AS
l_info info_type_table := info_type_table();
BEGIN
SELECT e.employeeid,
e.lastname,
c.customerid,
c.companyname,
o.orderid,
o.orderdate
BULK COLLECT -- Using bulk collect for the performance
INTO l_info
FROM ntw_employees e
INNER JOIN ntw_orders o
ON e.employeeid = o.employeeid
INNER JOIN ntw_customers c
ON o.customerid = c.customerid
WHERE e.city = p_city;
RETURN l_info;
END;
----Anonymous block with Bulk collect
DECLARE
type info_type
IS
record
(
emp_no NUMBER(3),
lastname VARCHAR2(26),
cust_no VARCHAR2(5),
CO_name VARCHAR2(50),
orderid NUMBER(5),
orderdate DATE );
type info_type_table
IS
TABLE OF info_type;
l_info info_type_table; -- default constructor not required in record type case
BEGIN
SELECT e.employeeid,
e.lastname,
c.customerid,
c.companyname,
o.orderid,
o.orderdate
BULK COLLECT
INTO
l_info
FROM ntw_employees e
INNER JOIN ntw_orders o
ON e.employeeid = o.employeeid
INNER JOIN ntw_customers c
ON o.customerid = c.customerid
WHERE e.city = 'London';
FOR I IN l_info.FIRST..l_info.LAST LOOP
dbms_output.put_line('angajat = ' || l_info(i).employeeid);
END LOOP;
END;