PLSQL错误:必须声明组件

时间:2017-06-16 10:55:27

标签: oracle plsql

这可能是一个蹩脚的错误,但我找不到它。 在一个程序中我有这个:

PROCEDURE myProcedure(returnCode OUT NUMBER) IS
CURSOR myCursor IS
  SELECT column1, column2, column3, column4 FROM MyTable WHERE columX IS NULL AND columnY = 'PS';

TYPE myType IS RECORD (
  name1 MyTable.Column1%TYPE,
  name2 MyTable.Column2%TYPE,
  name3 MyTable.Column3%TYPE,
  name4 MyTable.Column4%TYPE
);


myVar myType;
myVar2 typeA

BEGIN
   FOR myVar IN myCursor
   LOOP
      myVar2 := myVar.name2;
   END LOOP;
END;

错误:

PLS-00302 component name2 must be declared

有什么问题?

1 个答案:

答案 0 :(得分:1)

myVar游标循环变量与您的myVar记录类型变量无关;它的范围有效地覆盖了类型定义。如果删除该类型,则会收到相同的错误。

From the documentation for cursor for loop

  

cursor FOR LOOP语句隐式声明其循环索引为指定游标返回的行类型的记录变量。

a related section

  

游标FOR LOOP语句隐式声明其循环索引为其游标返回的类型的%ROWTYPE记录变量。该记录是循环的本地记录,仅在循环执行期间存在。

使用此语法,myVar与游标本身隐式地具有相同的行类型,并且具有column2字段而不是name2字段;所以这有效:

BEGIN
   FOR myVar IN myCursor
   LOOP
      myVar2 := myVar.column2;
   END LOOP;
END;

并且myVar变量声明和myType类型声明都是多余的。

要使用您的记录类型,您需要更明确的游标处理:

BEGIN
   OPEN myCursor;
   LOOP
      FETCH myCursor INTO myVar;
      EXIT WHEN myCursor%NOTFOUND;
      myVar2 := myVar.name2;
   END LOOP;
   CLOSE myCursor;
END;

现在myVar仍然是您的myType记录类型变量 - 没有任何内容覆盖 - 所以它具有您指定的字段名称。

你也可以明确地将myVar定义为myCursor%rowType,以避免需要你自己的记录类型,但是它只是编写第一个循环的更长的方式,你就可以了需要返回引用myVar.column2