【问题标题】:ORA-00947 : Not Enough Values while putting values into a type inside a procedureORA-00947: 将值放入过程中的类型时没有足够的值
【发布时间】:2015-06-14 05:18:09
【问题描述】:

我创建了一些 Oracle 类型:

create or replace TYPE "RESULTS_ADMIN" AS OBJECT 
(
  ROWNUMBER NUMBER,
  ASSET_ID VARCHAR2(1000 CHAR),
  BOOK_ID VARCHAR2(10 CHAR),
  asset_name VARCHAR2(50 CHAR) ,
  book_author VARCHAR2(30 CHAR) , 
  asset_location VARCHAR2(30 CHAR), 
  asset_cat VARCHAR2(50 CHAR), 
  asset_type VARCHAR2(10 CHAR), 
  publisher_name VARCHAR2(50 CHAR),
  books_available NUMBER
);

create or replace TYPE "RESULT_ADMIN_TEMP" is table of LMS.results_admin;

这是一个使用它们的过程:

create or replace PROCEDURE "RETRIEVE_ASSET_ADMIN" (
     aid IN asset_details.asset_id%TYPE,
      aname IN asset_details.asset_name%TYPE,
      acat IN asset_details.asset_cat%type,
      atypeid IN asset_details.asset_type_id%type,
      bauthor IN asset_details.book_author%type,
      aloc IN asset_details.asset_location%type,
      pub IN asset_publisher.publisher_name%type,
      pagenumber IN number,
      asset_cur OUT SYS_REFCURSOR    )
is 
    v_fpgnbr number;
    v_pgsize number;
    v_frec number;
    v_lrec number;
    v_totrows number;
    result_admin_temp_table result_admin_temp;
begin
  v_fpgnbr := pagenumber;
  v_pgsize :=10;
  v_frec := (v_fpgnbr - 1 ) * v_pgsize;
  v_lrec := ( v_fpgnbr * v_pgsize + 1 ); 
  select  row_number() over (order by a.asset_id) as rownum,
          a.asset_id, 
          a.book_id, 
          asset_name ,
          book_author , 
          asset_location, 
          asset_cat , 
          l.asset_type, 
          p.publisher_name,
          c.books_available
      bulk collect into result_admin_temp_table
  from asset_details a join asset_count c 
      on a.book_id=c.book_id 
      join asset_lookup_details l 
      on a.asset_type_id=l.asset_type_id 
      join asset_publisher p
      on a.book_id = p.book_id
  where (aid is NULL or a.asset_id = aid ) and 
      (aname is NULL or asset_name like '%'||aname||'%') and 
      (bauthor is NULL or book_author like '%'||bauthor||'%') and 
      (aloc like '%SELECT%' or asset_location like '%'|| aloc ||'%') and 
      (acat like '%SELECT%' or asset_cat like '%'||acat||'%') and 
      (atypeid = 0 or a.asset_type_id = atypeid) and
      (pub is NULL or p.publisher_name like '%'||pub||'%');
  open asset_cur for
  select 
      asset_id, 
      book_id, 
      asset_name ,
      book_author , 
      asset_location, 
      asset_cat , 
      asset_type, 
      publisher_name,
      books_available 
  from table(result_admin_temp_table)
  where 
  rownum > v_frec and rownum < v_lrec
  order by rownum asc;
end RETRIEVE_ASSET_ADMIN;

在编译代码时,我收到了ORA-00947: Not enough values error at the "bulkcollect into result_admin_temp_table" point。我已经尝试了很多在互联网上搜索以找到解决此问题的方法。 你能告诉我哪里出错了吗?

【问题讨论】:

    标签: oracle plsql user-defined-types ora-00947


    【解决方案1】:

    这就是您收到该消息的原因:您正在选择嵌套表。 Oracle 不会为您将结果集转换为类型:您需要自己做。

    select RESULTS_ADMIN(
              row_number() over (order by a.asset_id),
              a.asset_id, 
              a.book_id, 
              asset_name ,
              book_author , 
              asset_location, 
              asset_cat , 
              l.asset_type, 
              p.publisher_name,
              c.books_available )
      bulk collect into result_admin_temp_table
      from asset_details a join asset_count c 
          on a.book_id=c.book_id 
          join asset_lookup_details l 
          on a.asset_type_id=l.asset_type_id 
          join asset_publisher p
          on a.book_id = p.book_id)
    

    一些额外的观察:

    1. 不要使用rownum 作为别名。 ROWNUM 是 an Oracle keyword,因此您的查询不会像您想象的那样工作。
    2. 您正在使用整个结果集填充嵌套表。集合位于会话内存中。如果查询返回许多结果 - 并且考虑到参数的模糊性,我猜有时它会返回 - 集合可能会变得太大并超过 PGA 限制。
    3. 在数据库中运行分页查询是个坏主意。没有人愿意将业务逻辑放入数据库中,但每个人都希望将表示逻辑放在那里。 摇头

    最后,您可以通过简单的内联查询来避免集合的开销:

    open asset_cur for
      select 
          asset_id, 
          book_id, 
          asset_name ,
          book_author , 
          asset_location, 
          asset_cat , 
          asset_type, 
          publisher_name,
          books_available 
      from (  select  row_number() over (order by a.asset_id) as rn,
                  a.asset_id, 
                  a.book_id, 
                  asset_name ,
                  book_author , 
                  asset_location, 
                  asset_cat , 
                  l.asset_type, 
                  p.publisher_name,
                  c.books_available
              bulk collect into result_admin_temp_table
          from asset_details a join asset_count c 
              on a.book_id=c.book_id 
              join asset_lookup_details l 
              on a.asset_type_id=l.asset_type_id 
              join asset_publisher p
              on a.book_id = p.book_id
          where (aid is NULL or a.asset_id = aid ) and 
              (aname is NULL or asset_name like '%'||aname||'%') and 
              (bauthor is NULL or book_author like '%'||bauthor||'%') and 
              (aloc like '%SELECT%' or asset_location like '%'|| aloc ||'%') and 
              (acat like '%SELECT%' or asset_cat like '%'||acat||'%') and 
              (atypeid = 0 or a.asset_type_id = atypeid) and
              (pub is NULL or p.publisher_name like '%'||pub||'%')
              ) t
      where t.rn > v_frec and t.rn < v_lrec
      order by t.rn asc;
    

    【讨论】:

      猜你喜欢
      • 2020-08-16
      • 1970-01-01
      • 2020-01-25
      • 2020-07-25
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多