我希望在以下示例中将表类型的集合与其他表联系起来 -
我有一个函数F_GetPendingFeeds,它返回feed_log类型的表集合。 我想加入这个返回的集合,其中一个表 -
CREATE OR REPLACE PACKAGE BODY L_DemoPkg
IS
TYPE t_feedLog IS TABLE OF feed_log%ROWTYPE
INDEX BY PLS_INTEGER;
FUNCTION F_GetPendingFeeds
RETURN t_feedLog
IS
lo_feedLog t_feedLog;
BEGIN
SELECT feed_log_seq
, processed_dt
, processed_by
, create_dt
, created_by
BULK COLLECT INTO lo_feedLog
FROM feed_log
WHERE status_cd = 0;
RETURN lo_feedLog;
EXCEPTION
WHEN OTHERS THEN
--TODO: Log Exception
RAISE;
END F_GetPendingFeeds;
PROCEDURE P_ProcessFeed
IS
o_pendingFeed t_feedLog;
ln_totalRecords t_feedLog;
BEGIN
-- Get the list of pending feed ids
o_pendingFeed := F_GetPendingFeeds();
-- Check if new data is present for processing
IF o_pendingFeed.COUNT = 0 THEN
dbms_output.put_line('Feed processing failed. No data found.');
RETURN;
END IF;
SELECT COUNT(*)
INTO ln_totalRecords
FROM feed_details t1
, table(o_pendingFeed) t2 --ERROR: ORA-22905: cannot access rows from a non-nested table item
WHERE t1.feed_log_seq = t2.feed_log_seq;
EXCEPTION
WHEN OTHERS THEN
--TODO: Log Exception
RAISE;
END P_ProcessFeed;
END;
我收到错误 -
PL/SQL: SQL Statement ignored
PL/SQL: ORA-22905: cannot access rows from a non-nested table
item
请注意我想加入收藏表 -
FROM feed_details t1
, table(o_pendingFeed) t2 --ERROR: ORA-22905: cannot access rows from a non-nested table item WHERE t1.feed_log_seq = t2.feed_log_seq;
答案 0 :(得分:6)
在Oracle 12C之前,您只能选择使用CREATE TYPE
在服务器上创建的集合,例如
SQL> CREATE TYPE r_feedLog IS OBJECT (foo NUMBER, bar VARCHAR2(20));
SQL> CREATE TYPE t_feedLog IS TABLE OF r_feedLog;
然后从您的包中删除t_feedLog
的声明。
使用Oracle 12C, 可以从包规范中定义的PL / SQL表中进行选择。
答案 1 :(得分:5)
这里有几个错误。首先,要访问TABLE
转换中的数组,您需要使用SQL数组(好吧,您仍然可以使用PL / SQL表,但这仅适用于流水线函数,因为Oracle将创建SQL类型默默地为你服务;但即使在那种情况下,它仍然更整洁地使用SQL数组)。所以你需要这样做:
SQL> create type r_feedlog is object
2 (
3 feed_log_seq number,
4 processed_dt date,
5 processed_by varchar2(10),
6 create_dt date,
7 created_by varchar2(10)
8 );
9 /
Type created.
SQL> create type t_feedLog as table of r_feedlog;
2 /
Type created.
然后使用它而不是pl / sql索引表。其次
ln_totalRecords t_feedLog;
应该是一个数字而不是一个集合作为您的选择计数(*)。另外:
BULK COLLECT INTO lo_transferFeedDef
应该是
BULK COLLECT INTO lo_feedLog
你当然可以使用流水线功能,例如:
CREATE OR REPLACE PACKAGE L_DemoPkg
as
type r_feedlog is record(feed_log_seq number,
processed_dt date,
processed_by varchar2(10),
create_dt date,
created_by varchar2(10));
type t_feedLog is table of r_feedlog;
function F_GetPendingFeeds return t_feedLog pipelined;
procedure P_ProcessFeed;
end;
/
并在包体内:
FUNCTION F_GetPendingFeeds
RETURN t_feedLog pipelined
IS
lo_feedLog r_feedlog;
BEGIN
for r_row in (SELECT feed_log_seq
, processed_dt
, processed_by
, create_dt
, created_by
FROM feed_log
WHERE status_cd = 0)
loop
lo_feedLog.feed_log_seq := r_row.feed_log_seq;
lo_feedLog.processed_dt := r_row.processed_dt;
lo_feedLog.processed_by := r_row.processed_by;
lo_feedLog.create_dt := r_row.create_dt;
lo_feedLog.created_by := r_row.created_by;
pipe row(lo_feedLog);
end loop;
END F_GetPendingFeeds;
在程序中你可以只是:
SELECT COUNT(*)
INTO ln_totalRecords
FROM feed_details t1
, table(F_GetPendingFeeds()) t2
WHERE t1.feed_log_seq = t2.feed_log_seq;
以上是保持pl / sql数组。如果你有SQL数组,那么函数会更紧凑:
FUNCTION F_GetPendingFeeds
RETURN t_feedLog pipelined
IS
BEGIN
for r_row in (SELECT r_feedlog(feed_log_seq
, processed_dt
, processed_by
, create_dt
, created_by) data
FROM feed_log
WHERE status_cd = 0)
loop
pipe row(r_row.data);
end loop;
END F_GetPendingFeeds;