SQL Developer游标返回1行时应该返回多行

时间:2018-05-21 14:37:17

标签: oracle plsql cursor

procedure new_cust (p_practiceid varchar2)is


  custid varchar2(255);
  l_error_stack varchar2(4000);
  l_error_code integer;

cursor c1 is select id
from customers
where joining_date = to_char(sysdate,'YYYY-MM');


begin

OPEN c1;
loop
FETCH c1  INTO custid;
EXIT WHEN c1%NOTFOUND;

begin 

execute immediate 'drop table new_clients';
execute immediate 'create table new_clients as  select * from client_names where custid= '''||custid||'''';

exception when others then
  l_error_stack := substr(dbms_utility.format_error_backtrace,1,2500)||chr(10)||substr(dbms_utility.format_error_stack,1,500) ;
  l_error_code := sqlcode;
  daily_check_log.logger(systimestamp, inPracticeId, 'error', 'new_cust', l_error_code, l_error_stack);
end;


END LOOP;
CLOSE c1;

end;

我正在使用游标来确定本月加入的新客户端。应该至少有10条新记录,但光标只返回1行。我哪里错了?

2 个答案:

答案 0 :(得分:1)

您不必为此简单任务创建游标,此代码应该可以满足您的要求

procedure new_cust (p_practiceid varchar2) is

begin

  execute immediate 'drop table new_clients';
  execute immediate 'create table new_clients as  
                       select cn.* 
                         from client_names cn 
                         join customers c 
                           on c.id = cn.custid
                        where c.joining_date = to_char(sysdate,''YYYY-MM'')';
end;

并且不要忘记将异常处理放入其中:)

答案 1 :(得分:0)

在我看来,整个概念都是错误的。在Oracle中,您不能动态创建表,实际上,真正罕见的情况证明了这一点。您的代码完全是静态,没有什么需要动态SQL。

考虑创建一次表 - 并根据需要重用它。它可能涉及从中删除行。

具有 false 条件的CTAS将创建一个空表:

create table new_clients as select * from client_names where 1 = 2;

每月将数据插入其中(就像您的代码所暗示的那样):

insert into new_clients 
  select * 
  from client_names 
  where custid in (select id 
                   from customers 
                   where joining_date between trunc(sysdate, 'mm')
                                          and trunc(last_day(sysdate))
                  );

我认为JOINING_DATE并非YYYY-MM,而是 true 日期。如果有一个索引,它仍然可以工作,因为BETWEEN子句获取整个当月(但是,它可能需要进一步调整,具体取决于您拥有的数据)。

另外,如果你指定INSERT语句中涉及的列名称会更好(如果有很多这些名称并不重要 - 将它们命名为all,all,逐个)。 <{1}}可以正常工作,直到某些内容发生变化,然后才能正常工作。

如果需要,可以轻松地将select *移动到程序中。说到:IN参数用于什么?你声明了它,但它从未使用过。