Oracle内部加入收藏?

Par*_*ram 4 oracle plsql

我想在下面的例子中加入表类型与其他表的集合 -

我有一个函数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;
Run Code Online (Sandbox Code Playgroud)

我收到错误 -

PL/SQL: SQL Statement ignored
PL/SQL: ORA-22905: cannot access rows from a non-nested table
     item
Run Code Online (Sandbox Code Playgroud)

请注意我想加入表 -

  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;
Run Code Online (Sandbox Code Playgroud)

Ton*_*ews 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;
Run Code Online (Sandbox Code Playgroud)

然后t_feedLog从包中删除声明.

与Oracle 12C它可以从包中的规范中定义的PL/SQL表中进行选择.


Daz*_*zaL 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.
Run Code Online (Sandbox Code Playgroud)

然后使用它而不是pl/sql索引表.其次

   ln_totalRecords t_feedLog;
Run Code Online (Sandbox Code Playgroud)

应该是一个数字而不是一个集合作为你的选择计数(*).另外:

  BULK COLLECT INTO lo_transferFeedDef
Run Code Online (Sandbox Code Playgroud)

应该

  BULK COLLECT INTO lo_feedLog 
Run Code Online (Sandbox Code Playgroud)

你当然可以使用流水线功能,例如:

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;
/
Run Code Online (Sandbox Code Playgroud)

并在包体内:

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;
Run Code Online (Sandbox Code Playgroud)

在程序中你可以只是:

SELECT COUNT(*)
INTO ln_totalRecords
FROM  feed_details t1
    , table(F_GetPendingFeeds()) t2
WHERE t1.feed_log_seq = t2.feed_log_seq;
Run Code Online (Sandbox Code Playgroud)

以上是保持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;
Run Code Online (Sandbox Code Playgroud)