它如何将 select 语句的结果插入 table 的记录(关联数组)

How it insert result of select statement into table of records (associative array)

我正在做oracle的HR​​方案。我有 table 条记录

   type emp_record is RECORD(emp_first_name employees.first_name%type,
                       emp_last_name  employees.last_name%type,
                       );



    type emp_record_table is table of emp_record
       index by pls_integer;

我想插入下一个 select 语句的 emp_record_table 结果

   select first_name, last_name
   from employees
   where department_id=30;

你能解释一下如何解决这个问题吗?谢谢。

该操作不需要关联数组。嵌套 table 将是完美的选择。只需声明您的 table 类型如下:

type emp_record_table is table of emp_record;

首先,您必须声明 table 您创建的类型。现在您只声明了这些记录中 table 的类型或记录和类型。您还没有 table。您可以在 DECLARE 部分按照以下方式声明它:

l_emp_table emp_record_table;

然后初始化它:

l_emp_table := emp_record_table();

然后创建将从 SELECT 查询中获取数据的游标。如果您不知道如何操作,请阅读游标声明和获取。

下一步将是:对于每个游标行,将其数据插入 table。您编写将执行以下步骤的简单循环:

  1. 扩展您声明的 table l_emp_table.extend()
  2. 保存数据到tablel_emp_table(i).emp_first_name := FETCHED_ROW.first_name等等...

Oracle 设置:

CREATE TABLE employees (
  id         NUMBER(8,0) PRIMARY KEY,
  first_name VARCHAR2(50),
  last_name  VARCHAR2(80)
);

CREATE PACKAGE test_pkg IS
  TYPE emp_record IS RECORD(
    emp_first_name employees.first_name%type,
    emp_last_name  employees.last_name%type
  );

  TYPE emp_record_table IS TABLE OF emp_record INDEX BY pls_integer;
END;
/

INSERT INTO employees( id, first_name, last_name )
  SELECT -1, 'a', 'aaa' FROM DUAL UNION ALL
  SELECT +3, 'b', 'bbb' FROM DUAL;

PL/SQL 块:

DECLARE
  x PLS_INTEGER;
  emps test_pkg.emp_record_table;
BEGIN
  -- Populate the associative array
  FOR row IN ( SELECT * FROM employees ) LOOP
    emps(row.id).emp_first_name := row.first_name;
    emps(row.id).emp_last_name  := row.last_name;
  END LOOP;

  -- Read the associative array
  x := emps.FIRST;
  WHILE x IS NOT NULL LOOP
    DBMS_OUTPUT.PUT_LINE( x || ': ' || emps(x).emp_first_name || ' ' || emps(x).emp_last_name );
    x := emps.NEXT(x);
  END LOOP;
END;
/

输出:

-1: a aaa
3: b bbb

db<>fiddle here

最简单的方法是使用批量收集:

declare

  type emp_record is RECORD(emp_first_name employees.first_name%type,
                            emp_last_name  employees.last_name%type
                       );
  type emp_record_table is table of emp_record
       index by pls_integer;

  l_recs emp_record_table;

begin

  select first_name, last_name
  bulk collect into l_recs
  from employees
  where department_id=30;

  for idx in l_recs.first()..l_recs.last() loop
    dbms_output.put_line(l_recs(idx).emp_first_name ||' '|| l_recs(idx).emp_last_name);
  end loop;

end;       
/

请注意,您实际上并不需要关联数组来处理这样的记录。您可以放弃 index by pls_integer,一切仍然会正常工作。关联数组的价值在于当我们需要维护特定行的访问路径时。例如,我们可能希望使用 employees table 的主键来索引数组。这将创建一个 稀疏数组 ,因为不能保证所选员工 ID 形成连续序列。因此,整理数组的逻辑更加冗长:

declare

  type emp_record is RECORD(emp_first_name employees.first_name%type,
                            emp_last_name  employees.last_name%type
                       );
  type emp_record_table is table of emp_record
       index by pls_integer;

  l_recs emp_record_table;
  idx pls_integer;

begin

  for r in (select emp_id, first_name, last_name
            from employees
            where department_id=30 )
  loop
      l_recs(r.emp_id).emp_first_name := r.first_name;
      l_recs(r.emp_id).emp_last_name  := r.last_name;
  end loop;

  idx := l_recs.first();
  while idx is not null loop
    dbms_output.put_line(l_recs(idx).emp_first_name ||' '|| l_recs(idx).emp_last_name);
    idx := l_recs.next(idx);
  end loop;

end;       
/

这里是a demo on db<>fiddle