我想将游标中的数据插入对象 table,但我做不到

I want to insert data from a cursor into an object table, but I can't

CREATE OR REPLACE TYPE O_T_emplo AS OBJECT (
L_o_first_name VARCHAR2(30),
L_o_last_name  VARCHAR2(30),
L_o_depar      NUMBER,
CONSTRUCTOR FUNCTION O_T_emplo(
L_o_first_name VARCHAR2(30),
L_o_last_name  VARCHAR2(30),
L_o_depar      NUMBER)
RETURN SELF AS RESULT
);
/
CREATE OR REPLACE TYPE BODY O_T_emplo IS
CONSTRUCTOR FUNCTION O_T_emplo(
L_o_first_name VARCHAR2(30),
L_o_last_name  VARCHAR2(30),
L_o_depar      NUMBER
) RETURN SELF AS RESULT IS
BEGIN
SELF.L_o_first_name := L_o_first_name;
SELF.L_o_last_name  := L_o_last_name;
self.L_o_depar      := L_o_depar;
RETURN;
END;
END;
/
CREATE OR REPLACE TYPE tab_obj AS TABLE OF O_T_emplo;
/

使用 plsql:

DECLARE
  tab_emps tab_obj;
  info_emps O_T_emplo;
  CURSOR C_infos IS 
    SELECT e.first_name, e.last_name, e.department_id 
    FROM employees e;
  infos C_infos%ROWTYPE;
BEGIN
  tab_emps := tab_obj();
  OPEN C_infos;
  LOOP
    FETCH C_infos INTO infos;
    info_emps := O_T_emplo(infos.first_name, infos.last_name, infos.department_id);
    tab_emps.extend();
    tab_emps(tab_emps.LAST) := info_emps;
    EXIT WHEN C_infos%NOTFOUND;
  END LOOP;  
  CLOSE C_infos;
END;
/

谁能帮帮我?

  • 在类型中,从声明和主体中构造函数的签名中删除 VARCHAR2 数据类型的长度。
  • 在 PL/SQL 块中,更改循环中的顺序,使 EXIT 紧跟在 FETCH 之后;如果你反过来做,那么光标的最后一行将被插入两次。
  • 您可以选择删除 info_emps 中间变量。
CREATE OR REPLACE TYPE O_T_emplo AS OBJECT (
  L_o_first_name VARCHAR2(30),
  L_o_last_name  VARCHAR2(30),
  L_o_depar      NUMBER,

  CONSTRUCTOR FUNCTION O_T_emplo(
    L_o_first_name VARCHAR2,
    L_o_last_name  VARCHAR2,
    L_o_depar      NUMBER
  ) RETURN SELF AS RESULT
)
/

CREATE OR REPLACE TYPE BODY O_T_emplo IS
  CONSTRUCTOR FUNCTION O_T_emplo(
    L_o_first_name VARCHAR2,
    L_o_last_name  VARCHAR2,
    L_o_depar      NUMBER
  ) RETURN SELF AS RESULT
  IS
  BEGIN
    SELF.L_o_first_name := L_o_first_name;
    SELF.L_o_last_name  := L_o_last_name;
    self.L_o_depar      := L_o_depar;
    RETURN;
  END;
END;
/
CREATE OR REPLACE TYPE tab_obj AS TABLE OF O_T_emplo;
/

然后:

DECLARE
  tab_emps tab_obj;
  CURSOR C_infos IS SELECT e.first_name, e.last_name, e.department_id FROM employees e;
  infos C_infos%ROWTYPE;
BEGIN
  tab_emps := tab_obj();
  OPEN C_infos;
  LOOP
    FETCH C_infos INTO infos;
    EXIT WHEN C_infos%NOTFOUND;
    tab_emps.extend();
    tab_emps(tab_emps.LAST) := O_T_emplo(
      infos.first_name,
      infos.last_name,
      infos.department_id
    );
  END LOOP;  
  CLOSE C_infos;
  
  FOR i IN 1 .. tab_emps.COUNT LOOP
    DBMS_OUTPUT.PUT_LINE(
      tab_emps(i).l_o_first_name || ', ' ||
      tab_emps(i).l_o_last_name || ', ' ||
      tab_emps(i).l_o_depar
      
    );
  END LOOP;
END;
/

db<>fiddle here