ORA-01002:在oracle中提取顺序错误

ORA-01002:在oracle中提取顺序错误,oracle,plsql,Oracle,Plsql,ORA-01002:使用sys\U refcursor时在oracle中取数顺序错误 我希望光标中有员工列表。在我的真实场景中,我需要检查员工的数量,如果数量大于零,我应该使用相同的select语句。我没有多次执行相同的select语句,而是尝试了下面的代码片段。但我在输出游标中发现了“提取顺序错误” 我的桌子: create or replace procedure sp_temp_1 ( var_job in VARCHAR2, cur_custid out sys_refcursor )

ORA-01002:使用sys\U refcursor时在oracle中取数顺序错误

我希望光标中有员工列表。在我的真实场景中,我需要检查员工的数量,如果数量大于零,我应该使用相同的select语句。我没有多次执行相同的select语句,而是尝试了下面的代码片段。但我在输出游标中发现了“提取顺序错误”

我的桌子:

create or replace procedure sp_temp_1  (
var_job in VARCHAR2,
cur_custid out sys_refcursor
) 
AS

  /* Declare Ref Cursor */
  --cur_custid  SYS_REFCURSOR;

  /* Declare Type using Fields from the employees table. */
  TYPE t_custrec IS RECORD (
    firstname    temp_emp.firstname%TYPE,
    lastname     temp_emp.lastname%TYPE
  );

  /* Declare Record based off of Type */
  custrec   t_custrec;

BEGIN

  OPEN cur_custid FOR
    SELECT DISTINCT firstname
                   ,lastname
      FROM temp_emp
     WHERE JOB = var_job; /* Data Analyst does not exist forcing Zero Rows returned */

  LOOP
    FETCH cur_custid
      INTO custrec;
    EXIT WHEN cur_custid%notfound;
    ---looping happens
  END LOOP;

  dbms_output.put_line('Num Rows: ' || cur_custid%rowcount);

  IF cur_custid%rowcount = 0
  THEN
  dbms_output.put_line('Zero Rows Condition Met.  Opening Cursor.');
    OPEN cur_custid FOR
      SELECT '0' AS empid FROM dual;
  END IF;

END;
我需要员工列表,但sys_refcursor在Oracle中提供了提取顺序错误:


当我对你的代码稍作修改时,我不会出错。也许我的工作代码可以帮助你?如果您有任何问题或我是否可以进一步协助,请告诉我

总结

声明引用游标 根据my employees表中的字段数声明类型 根据类型声明记录 打开光标并输入Loop 在循环内,使用光标获取的值填充记录。 使用dbms_输出显示一些输出,以便我们知道它正在工作 最后,如果游标返回零行,则使用不同的SQL再次打开游标。 员工表

代码


我不知道为什么SQL开发者会给出这个错误;试图显示绑定的光标似乎不高兴。不过,错误来自该输出窗口,而不是您的代码

如果手动运行与SQL工作表中的脚本完全相同的测试块,并使用客户机变量将out游标绑定到该测试块,则不会出现错误:

var cur_custid refcursor;

DECLARE
  VAR_JOB VARCHAR2(200);
  CUR_CUSTID sys_refcursor;
BEGIN
  VAR_JOB := 'teach';

  SP_TEMP_1(
    VAR_JOB => VAR_JOB,
    CUR_CUSTID => CUR_CUSTID
  );
  /* Legacy output: 
DBMS_OUTPUT.PUT_LINE('CUR_CUSTID = ' || CUR_CUSTID);
*/ 
  :CUR_CUSTID := CUR_CUSTID; --<-- Cursor
--rollback; 
END;
/

Num Rows: 3


PL/SQL procedure successfully completed.

print cur_custid
很明显,您遇到了cur_custid%notfound,这意味着游标中没有剩余的行。没有自动或手动倒带设备;因此,当调用者重新控制out变量时,游标仍然为空。或者,如果您更愿意这样想,光标指针仍然指向数据的末尾-没有可以使用的行了。同样,为什么程序执行向导会在此时出错还不清楚

你的前提是:

我需要检查员工的数量,如果数量大于零,我应该使用相同的select语句。我没有多次执行相同的select语句,而是尝试了

。。。这是有缺陷的。您可以执行您正在执行的操作,但当您使用光标时,必须重新打开它,这仍然会复制语句:

  IF cur_custid%rowcount = 0
  THEN
  dbms_output.put_line('Zero Rows Condition Met.  Opening Cursor.');
    OPEN cur_custid FOR
      SELECT '0' AS empid FROM dual;
  ELSE
  dbms_output.put_line('Non-zero Rows Condition Met.  Re-opening Cursor.');
    OPEN cur_custid FOR
    SELECT DISTINCT firstname
                   ,lastname
      FROM temp_emp
     WHERE JOB = var_job; /* Data Analyst does not exist forcing Zero Rows returned */
  END IF;
在这种情况下,您实际上只需要在循环中执行一次获取,并立即退出;或者根本不循环,只做一个简单的获取。您只关心零/非零,而不关心实际的非零计数

使用原始代码,一个新版本打开第二个游标,另一个新版本打开一个抓取。稍微修改调用块,通过dbms_输出输出结果

只进行初始计数并决定打开哪个游标可能更简单


顺便说一句,两个可能的游标的列数不同,这很奇怪。想必不管调用它的是什么,都应该在游标中循环,如果它在ID列中看到零,它就知道没有数据了?如果只记下它是否处理了任何行,会更干净。然后,您的过程不需要任何这种逻辑,只要打开一个有意义的游标就可以了——如果您真的需要一个过程来实现这一点的话。您的真实场景可能比您的示例所暗示的要做更多的工作;在这种情况下,计数方法可能更合适。

这是一段经过编辑的代码,显然没有任何东西会导致它抛出ORA-01008。因此,我们很难提出建议。您需要提供表结构和示例数据来说明您的问题。至少我们需要一些实际抛出异常的代码。我在这里附上了我的完整代码。感谢您的回复。我使用了上面相同的代码。但还是会出错。我已经在上面添加了完整的代码、我的表的屏幕截图和错误的屏幕截图。请帮我做这个。或者,如果有任何替代方案可以避免多次使用同一sql语句,则建议也使用该语句
  LOOP
    FETCH cur_custid
      INTO custrec;
    EXIT WHEN cur_custid%notfound;
    ---looping happens
  END LOOP;
  IF cur_custid%rowcount = 0
  THEN
  dbms_output.put_line('Zero Rows Condition Met.  Opening Cursor.');
    OPEN cur_custid FOR
      SELECT '0' AS empid FROM dual;
  ELSE
  dbms_output.put_line('Non-zero Rows Condition Met.  Re-opening Cursor.');
    OPEN cur_custid FOR
    SELECT DISTINCT firstname
                   ,lastname
      FROM temp_emp
     WHERE JOB = var_job; /* Data Analyst does not exist forcing Zero Rows returned */
  END IF;