它如何将 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。您编写将执行以下步骤的简单循环:
- 扩展您声明的 table
l_emp_table.extend()
- 保存数据到table
l_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;
/
我正在做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。您编写将执行以下步骤的简单循环:
- 扩展您声明的 table
l_emp_table.extend()
- 保存数据到table
l_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;
/