【问题标题】:Oracle plsql error PLS-00642: local collection types not allowed in SQL statementsOracle plsql 错误 PLS-00642:SQL 语句中不允许本地集合类型
【发布时间】:2021-08-16 02:35:12
【问题描述】:

我正在编写和 pl/sql 程序并得到错误为 PLS-00642:SQL 语句中不允许本地集合类型和 PL/SQL: ORA-00947: 没有足够的值

首先我调用了一个游标并迭代游标,然后再次获取记录,错误即将到来。

declare 
  type t1 is record (
    msisdn varchar2(20),
    imsi varchar2(14),
    date_time date,
    mml_cmd varchar2(50),
    cmd_executed varchar2(2500),
    myrank number);
    type t2 is table of t1;
    l_k t2;
    type t3 is table of hlr_agent_logs%rowtype;
    l_tab t3;
     cursor c1 is select * from hlr_agent_logs where date_time>trunc(sysdate-2) and mml_cmd='ADD USER' and cmd_executed like '%Profile=3%' order by date_time;
    
begin
  open c1;
  loop
    fetch c1 bulk collect into l_tab limit 500;
    exit when l_tab.count=0;
    for i in l_tab.first .. l_tab.last loop
    
               begin
               select msisdn, imsi, date_time , mml_cmd,cmd_executed,rank() over (partition by imsi order by date_time asc)  as myrank into l_k from hlr_agent_logs 
                  where substr(msisdn,3)=l_tab(i).msisdn and imsi=l_tab(i).imsi and date_time>=l_tab(i).date_time;
                 for k  in l_k.first..l_k.last loop 
                   dbms_output.put_line(l_k(k).msisdn);
                 end loop;
                 
                 exception when no_data_found then 
                   null;
                 end;
        end loop;
    close c1;
   end loop;
 end;
 /

【问题讨论】:

  • 能否提供表hlr_agent_logs的结构??

标签: oracle plsql


【解决方案1】:

直接从 SQL 中使用 PLSQL 集合可以做什么和不可以做什么因版本而异,但这可能就像您没有 BULK COLLECT 一样简单,因为您正在提取表中

SQL> declare
  2    type rec is record (
  3       c1 int,
  4       c2 int );
  5
  6    type mylist is table of rec;
  7    n mylist;
  8  begin
  9      select 1,2 into n from dual;
 10  end;
 11  /
    select 1,2 into n from dual;
                    *
ERROR at line 9:
ORA-06550: line 9, column 21:
PLS-00642: local collection types not allowed in SQL statements
ORA-06550: line 9, column 23:
PL/SQL: ORA-00947: not enough values
ORA-06550: line 9, column 5:
PL/SQL: SQL Statement ignored


SQL>
SQL> declare
  2    type rec is record (
  3       c1 int,
  4       c2 int );
  5
  6    type mylist is table of rec;
  7    n mylist;
  8  begin
  9      select 1,2 bulk collect into n from dual;
 10  end;
 11  /

PL/SQL procedure successfully completed.

【讨论】:

    【解决方案2】:

    正如@Connor McDonnal 明智地所说,根据版本,您可以或不能在 SQL 上使用 PLSQL 类型,但将它们声明为模式对象。由于您没有说明您使用的是哪个版本的 Oracle,所以让我向您展示一个 Oracle 19c 的示例

    declare 
      type t1 is record (
        msisdn varchar2(20),
        imsi varchar2(14),
        date_time date,
        mml_cmd varchar2(50),
        cmd_executed varchar2(2500),
        myrank number);
        type t2 is table of t1;
        l_k t2;
        type t3 is table of hlr_agent_logs%rowtype;
        l_tab t3;
         cursor c1 is select * from hlr_agent_logs where date_time>trunc(sysdate-2) and mml_cmd='ADD USER' and cmd_executed like '%Profile=3%' order by date_time;
     begin
      open c1;
      loop
        fetch c1 bulk collect into l_tab limit 500;
        exit when l_tab.count=0;
        for i in l_tab.first .. l_tab.last loop
                  begin
                   select msisdn, imsi, date_time , mml_cmd,cmd_executed,rank() over (partition by imsi order by date_time asc)  as myrank bulk collect into l_k 
                   from hlr_agent_logs 
                   where substr(msisdn,3)=l_tab(i).msisdn and imsi=l_tab(i).imsi and date_time>=l_tab(i).date_time;
                     for k  in l_k.first..l_k.last loop 
                       dbms_output.put_line(l_k(k).msisdn);
                     end loop;
                     exception when no_data_found then 
                       null;
                     end;
            end loop;
        close c1;
       end loop;
     end;
     /
    

    输出

    SQL> l
      1  declare
      2    type t1 is record (
      3      msisdn varchar2(20),
      4      imsi varchar2(14),
      5      date_time date,
      6      mml_cmd varchar2(50),
      7      cmd_executed varchar2(2500),
      8      myrank number);
      9      type t2 is table of t1;
     10      l_k t2;
     11      type t3 is table of hlr_agent_logs%rowtype;
     12      l_tab t3;
     13       cursor c1 is select * from hlr_agent_logs where date_time>trunc(sysdate-2) and mml_cmd='ADD USER' and cmd_executed like '%Profile=3%' order by date_time;
     14   begin
     15    open c1;
     16    loop
     17      fetch c1 bulk collect into l_tab limit 500;
     18      exit when l_tab.count=0;
     19      for i in l_tab.first .. l_tab.last loop
     20                begin
     21                 select msisdn, imsi, date_time , mml_cmd,cmd_executed,rank() over (partition by imsi order by date_time asc)  as myrank bulk collect into l_k
     22                        from hlr_agent_logs
     23                 where substr(msisdn,3)=l_tab(i).msisdn and imsi=l_tab(i).imsi and date_time>=l_tab(i).date_time;
     24                   for k  in l_k.first..l_k.last loop
     25                     dbms_output.put_line(l_k(k).msisdn);
     26                   end loop;
     27                   exception when no_data_found then
     28                     null;
     29                   end;
     30          end loop;
     31      close c1;
     32     end loop;
     33*  end;
    SQL> /
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-16
      • 1970-01-01
      • 1970-01-01
      • 2014-12-16
      • 1970-01-01
      • 2012-01-17
      • 2019-09-02
      • 2020-03-07
      相关资源
      最近更新 更多