如何传递从多个表创建的 PL/SQL 游标记录?

How can I pass a PL/SQL cursor record created from multiple tables?

这是 12c 数据库中的PL/SQL。

我需要能够将游标记录传递给函数。问题是光标来自三个不同的 table,其中一个必须使用 * 到 select table.[=32= 中的所有(数百个)字段] 如果我 select 不同的字段(来自较小的测试 table)它会工作,如果我使用来自一个 table 的 select * 而没有其他字段(没有其他 tables 涉及),但是当 select 从三个 tables(示例仅显示两个)并使用 *(到 select 所有字段)来自 table 之一。

我试过使用预定义游标的 FETCH INTO 和 SELECT INTO。我试过使用带有 FOR myRecord IN (SELECT a.*, ...) 的游标记录和 创建匹配对象(因为无法在架构级别创建记录)

这些作品

myVarA a%ROWTYPE;
SELECT a.* INTO myVarA  
  FROM a;

SELECT a.myAfield, b.myBfield INTO myVarA, myVarB
  FROM a, b;

但我需要这个才能工作:

myVarA a%ROWTYPE;
SELECT a.*, b.myBfield  INTO myVarA, myVarB  
  FROM a, b;

使用游标记录

myRecord        myObjectTypeWithAllFields;      -- ojbect, not record as record can't be declared at schema level

FOR myRecord IN (SELECT a.*, b.myBfield FROM a, b); 
newVar  := myFunction(myRecord);        -- this won't work

使用 PLS-00306 调用函数失败:调用 myFunction 时参数的数量或类型错误;

该函数会做很多包中类似的繁重工作,但也有大量独特的工作 在每个包中,所以我不能只处理函数中的整个游标循环。我真的需要一次将一行传递给函数。

有办法吗?

您可以在包中定义游标 - 无论您是否实际使用它 - 使用相同的 select 列表:

create package p as
cursor c is select a.*, b.myBField
from a, b; -- but use proper join syntax
end;
/

然后使用光标的 %rowtype:

定义函数参数
create function myFunction(p_record p.c%rowtype) return ... as ...

那么你的块将起作用:

FOR myRecord IN (SELECT a.*, b.myBfield FROM a, b) LOOP
  newVar  := myFunction(myRecord);
END LOOP;

db<>fiddle demo

如果您愿意,循环游标可以使用包中定义的游标。


顺便说一句,在您的对象版本中,变量声明:

myRecord        myObjectTypeWithAllFields;

是多余的; FOR myRecord... 中的 myRecord 是完全独立的。所以它甚至不尝试使用对象类型。

您使用的是 %rowtype 锚点,所以我假设是精确提取。 Oracle 不允许在“into”子句中使用多个记录。但是我们可以有一个解决方法。

DECLARE

  emprec EMPLOYEES%ROWTYPE;
  deptname DEPARTMENTS.department_name%type;
BEGIN

  select a.* into emprec
    from EMPLOYEES a
    WHERE EMPLOYEE_ID = 100;

  SELECT DEPARTMENT_NAME into deptname
    from DEPARTMENTS where DEPARTMENT_ID = emprec.DEPARTMENT_ID;
END;

此示例展示了如何获取记录中的 a.* 并与另一个 table 进行内部联接并将 b.myBfield 放入另一个记录中。 再一次,这些是记录,所以我假设这是一个精确的提取。 如果这不是你想要的,请在评论中告诉我。