简体   繁体   English

当我尝试在 oracle sql 中执行我的过程时出现“光标已打开”错误

[英]'Cursor is already open' error when I try to execute my procedure in oracle sql

I wrote a function in oracle sql to fetch the name of an employee whose id in the table matches the input given to the function. I wrote a function in oracle sql to fetch the name of an employee whose id in the table matches the input given to the function.

 create or replace function id_search
    (
    x in number
    )
    return number
    is
    cursor e is select ename from employee where emp_id = x;
    begin
    open e;
   for i in e
   loop
   dbms_output.put_line('name is :'||i.ename);
   end loop;
   close e;
   return 0;
   end;
   /

After this, I called this function in a procedure I had written:在此之后,我在我编写的程序中调用了这个 function:

SQL>     create or replace procedure id_searchP
  2      (
  3      y in number
  4      )
  5      is
  6      t number:= 1;
  7      begin
  8      t := id_search(y);
  9      end;
 10      /

However, when I try to execute my procedure, I am encountering the error:但是,当我尝试执行我的程序时,我遇到了错误:

SQL> exec id_searchP(2);
BEGIN id_searchP(2); END;

          *

ERROR at line 1:
ORA-06511: PL/SQL: cursor already open
ORA-06512: at "tom.ID_SEARCH", line 7
ORA-06512: at "tom.ID_SEARCH", line 10
ORA-06512: at "tom.ID_SEARCHP", line 8
ORA-06512: at line 1

why Am I getting this error?为什么我会收到此错误?

You are opening and closing the cursor two times.您打开和关闭 cursor 两次。 You do not need to open e;你不需要open e; and then again for i in e .然后再次for i in e Do i like this in your function:我喜欢你的 function:

create or replace function id_search(x in number)
return number
is

    cursor e 
    is
    select ename 
    from employee 
    where emp_id = x;

begin

       for i in e loop
          dbms_output.put_line('name is :'||i.ename);
       end loop;

       return 0;
end;

Then the procedure is ok:然后程序就ok了:

create or replace procedure id_searchP(y in number)
is
     t number:= 1;
begin
     t := id_search(y);
end;

And then only one call will be enough:然后只需一个电话就足够了:

BEGIN 
  id_searchP(2); 
END;

Here is the DEMO这是演示

You are encountering this issues because you are explicitly opening cursor e, and then attempting to start a cursor for loop on cursor e.您遇到此问题是因为您明确打开 cursor e,然后尝试在 cursor e 上启动 cursor for 循环。 However, the cursor for loop implicitly attempts to open cursor e, which you already explicitly opened.但是,cursor for 循环会隐式尝试打开您已显式打开的 cursor e。

If you want to use a cursor for loop you will need to remove your explicit open and close statements.如果您想使用 cursor for 循环,则需要删除显式打开和关闭语句。

There are very few times when you need to use an explicitly-declared cursor.很少需要使用明确声明的 cursor。 Get in the habit of using cursor FOR-loops:养成使用 cursor FOR 循环的习惯:

 create or replace function id_search(pinEmployee_ID in number)
    return number
 is
 begin
   for rowEmployee in (select ename
                         from employee
                         where emp_id = pinEmployee_ID)
   loop
     dbms_output.put_line('name is :' || rowEmployee.ename);
   end loop;

   return 0;
 end id_search;

There - shorter, simpler, less error-prone, and easier to understand.那里 - 更短,更简单,更不容易出错,更容易理解。

Please use meaningful names.请使用有意义的名称。 I don't care if it's a school assignment or whatever - use meaningful names.我不在乎这是学校作业还是其他什么——使用有意义的名字。 Don't make people dig into your code to figure out what your parameters mean or are used for.不要让人们深入研究您的代码来弄清楚您的参数的含义或用途。

Further - please take the time to format your code so it's readable.进一步 - 请花时间格式化您的代码,使其可读。 Indent consistently, make sure that code levels are apparent to the naked eye, put whitespace in so your code can be read easily, spell things properly, and spell things out.一致地缩进,确保代码级别对肉眼可见,放入空格以便您的代码可以轻松阅读,正确拼写和拼写出来。 I don't want to see i for a parameter name - if what's being passed in is (supposed to be) an employee ID, then make sure that the name of the parameter makes that apparent.我不想看到i作为参数名称 - 如果传入的是(应该是)员工 ID,那么请确保参数名称使这一点显而易见。 Computer programming is primarily an exercise in communication - between you, the computer, and the poor dumb SOB who in ten years will have to read your code and figure out what it does.计算机编程主要是一种沟通练习——在你、计算机和可怜的愚蠢 SOB 之间,十年后他们将不得不阅读你的代码并弄清楚它的作用。 Don't be the guy that everyone cusses at when they have to maintain your code.当他们必须维护您的代码时,不要成为每个人都诅咒的人。 Develop good habits now.现在养成良好的习惯。

Programming is a craft.编程是一门手艺。 If this is something you really want to do, work on doing it well.如果这是您真正想做的事情,请努力做好。 Every assignment, every script, every day is an opportunity to improve.每一个任务,每一个剧本,每一天都是一个改进的机会。 Or at the very least to show what you know.或者至少展示你所知道的。 Make sure that what you show is your best, always.确保您所展示的始终是您最好的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM