Oracle RECORDS 和 table 记录类型

Oracle RECORDS and table of records type

我有一个定义了两个字段的记录类型。

TYPE record is RECORD (
 a NUMBER,
  b VARCHAR2(20)
);

并且我已经定义了一个类型,它是上述提到的记录类型的 table。

TYPE recordTable is TABLE of record;

我在脚本中声明了一个变量

recordVar recordTable;

在 plsql 脚本中,我成功地用一些值填充了上面声明的变量 recordVar

Post 我想加入 recordVar 与现有 table 之一。

我该如何实现?

如果我做一个select * from recordVar。我收到一条错误消息,提示 table 或视图不存在。

你不能,RECORD 是 PL/SQL 数据类型,不能在 SQL 语句中使用。

DECLARE
  TYPE recordType is RECORD ( a NUMBER, b VARCHAR2(20) );
  TYPE recordTable is TABLE of recordType;
  
  v_recs recordTable;
BEGIN
  v_recs.EXTEND(2);
  v_recs(1).a := 23;
  v_recs(1).b := 'ABC';
  v_recs(2).a := 42;
  v_recs(2).b := 'DEF';
  
  FOR i IN (SELECT * FROM TABLE(v_recs))
  LOOP
    DBMS_OUTPUT.PUT_LINE(i.a || ', ' || i.b);
  END LOOP;
END;
/

输出错误:

ORA-06550: line 13, column 33:
PLS-00642: local collection types not allowed in SQL statements
ORA-06550: line 13, column 27:
PL/SQL: ORA-22905: cannot access rows from a non-nested table item
ORA-06550: line 13, column 13:
PL/SQL: SQL Statement ignored

如果您想做类似的事情,请在 SQL 范围内将其声明为 OBJECT

CREATE TYPE objectType is OBJECT( a NUMBER, b VARCHAR2(20) );
CREATE TYPE objectTable is TABLE of objectType;

然后您可以通过 table 集合表达式在 PL/SQL 和 SQL 中使用它:

DECLARE
  v_objs objectTable := objectTable();
BEGIN
  v_objs.EXTEND(2);
  v_objs(1) := objectType(23, 'ABC');
  v_objs(2) := objectType(42, 'DEF');

  FOR i IN (SELECT * FROM TABLE(v_objs))
  LOOP
    DBMS_OUTPUT.PUT_LINE(i.a || ', ' || i.b);
  END LOOP;
END;
/

输出:

23, ABC
42, DEF

然后,如果你想加入另一个table你可以这样做:

CREATE TABLE table_name (id, value) AS
SELECT 23, 'UVW' FROM DUAL UNION ALL
SELECT 42, 'XYZ' FROM DUAL;
DECLARE
  v_objs objectTable := objectTable();
BEGIN
  v_objs.EXTEND(2);
  v_objs(1) := objectType(23, 'ABC');
  v_objs(2) := objectType(42, 'DEF');

  FOR i IN (SELECT o.a, o.b, t.value
            FROM   TABLE(v_objs) o
                   INNER JOIN table_name t
                   ON o.a = t.id)
  LOOP
    DBMS_OUTPUT.PUT_LINE(i.a || ', ' || i.b || ', ' || i.value);
  END LOOP;
END;
/

输出:

23, ABC, UVW
42, DEF, XYZ

db<>fiddle here