PL/SQL Associative Arrays
malong 发布于 2021-04-22

PL/SQL关联数组
关联数组,也称为索引表,这些数组包含两列,一个键和另一个值。键可以是任何东西,整数或字符串,但它必须是唯一的,否则编译器将返回错误。密钥不需要是连续的,但是密钥必须是唯一的。关联数组可以同时包含标量和记录,也就是说,我们可以同时使用记录和集合。这些数组是无界的,当添加新元素时大小会增加,当删除元素时大小会减小。

语法
 TYPE type_name AS TABLE OF value_data_type [ NOT NULL ]
 INDEX BY { pls_integer | binary_integer | varchar2( size )} ;
使用关联数组的程序
declare
   type e_list is table of employees.first_name%type index by pls_integer;
   emps e_list;
 begin
   for x in 100 .. 110 loop
     select first_name into emps(x) from employees
        where employee_id = x ;
   end loop;
   for i in emps.first()..emps.last() loop
     dbms_output.put_line(emps(i));
   end loop;
end;

当我们执行上述代码时,编译器将给出输出-

 anonymous block completed
 Steven
 Neena
 Lex
 Alexander
 Bruce
 David
 Valli
 Diana
 Nancy
 Daniel
 John

在这个程序中,我们声明了一个emp_list类型,并使用IS TABLE OF,我们从HR SCHEMA中链接了表employees,并选择数据类型为PLS_INTEGER的索引从主表继承的first name列。我们已经初始化了emps e_list。现在在主块中,我们用一个计数器X声明了一个for循环,在in关键字之后,我们分别指定了lower bound和upper bound的值100和110,并用两个点将它们分开。循环将重复自身,直到X的值保持在数组的100到110个值之间,并且一旦X的值超过110,编译器将移出循环语句。

在循环中,我们使用SELECT命令调用first_name,并从employee的表中将值添加到emps(x)。这将把employee表中的所有first.name添加到employee id为X的变量中。稍后使用另一个for循环I和上限emp.fist和下限emp.last。最后和DBMS output语句和计数器I一起显示声明数组的所有元素。每次程序完成一次旋转,计数器的值就会增加,直到所有元素都被打印出来。

使用带字符串的关联数组的程序
declare
   type e_list is table of employees.first_name%type index by employees.email%type;
   emps e_list;
   idx employees.email%type;
   v_email employees.email%type;
   v_first_name employees.first_name%type;
 begin
     for x in 100 .. 110 loop
     select first_name,email into v_first_name,v_email from employees
        where employee_id = x;
     emps(v_email) := v_first_name;
   end loop;
   idx := emps.first;
   while idx is not null  loop
     dbms_output.put_line('The email of '|| emps(idx) ||' is : '|| idx);
     idx := emps.next(idx);
   end loop;
 end;

当我们执行上述代码时,编译器将给出输出-

 anonymous block completed
 The email of Alexander is: AHUNOLD
 The email of Bruce is: BERNST
 The email of David is: DAUSTIN
 The email of Daniel is: DFAVIET
 The email of Diana is: DLORENTZ
 The email of John is: JCHEN
 The email of Lex is: LDEHAAN
 The email of Nancy is: NGREENBE
 The email of Neena is : NKOCHHAR
 The email of Steven is: SKING
 The email of Valli is: VPATABAL

在这个程序中,我们声明了一个类型e_list,使用IS TABLE OF,我们从HR模式链接了表employees,并选择一个名列,该列的数据类型继承自主表,索引为employees。电子邮件。我们已经初始化了emps e_list。
我们声明了3个变量。数据类型为的Idx员工电子邮件%键入以存储索引。数据类型为的电子邮件员工电子邮件%要在select into子句中使用的类型。
具有数据类型的V_first_name employees.first_name % type 在select into子句中使用的类型。

现在在主块中,我们用一个计数器X声明了一个for循环,在in关键字之后,我们分别指定了lower bound和upper bound的值100和110,并用两个点将它们分开。循环将重复自身,直到X的值保持在数组的100到110个值之间,并且一旦X的值超过110,编译器将移出循环语句。
在循环中,我们使用SELECT命令从employee的表中调用firstname,email,并向声明的变量v first_ name,v_email添加值,其中employee_id为X。

现在我们在数组emp中添加了v_first_name。为了显示数组的元素,我们将IDX指定为emps。首先将指针移动到数组的第一个元素,稍后,使用while循环IDX和DBMS output语句以及计数器IDX来显示声明数组的所有元素。每次程序完成一次旋转,IDX的值就会增加,直到所有元素都打印出来。

使用记录关联数组的程序

declare
   type e_type is record (first_name employees.first_name%type,
                          last_name employees.last_name%type,
                          email employees.email%type);
   type e_list is table of e_type index by employees.email%type;
   emps e_list;
   idx employees.email%type;
 begin
     for x in 100 .. 110 loop
     select first_name,last_name,email into emps(x) from employees
        where employee_id = x;
   end loop;
   idx := emps.first;
   while idx is not null  loop
     dbms_output.put_line('The email of '|| emps(idx).first_name
           ||' '||emps(idx).last_name||' is : '|| emps(idx).email);
     idx := emps.next(idx);
   end loop;
 end;

当我们执行上述代码时,编译器将给出输出-

anonymous block completed
 The email of Steven King is: SKING
 The email of Neena Kochhar is : NKOCHHAR
 The email of Lex De Haan is : LDEHAAN
 The email of Alexander Hunold is: AHUNOLD
 The email of Bruce Ernst is: BERNST
 The email of David Austin is: DAUSTIN
 The email of Valli Pataballa is : VPATABAL
 The email of Diana Lorentz is: DLORENTZ
 The email of Nancy Greenberg is: NGREENBE
 The email of Daniel Faviet is: DFAVIET
 The email of John Chen is: JCHEN

在这个程序中,我们创建了一个带有变量e_type的记录类型和一个分配变量的记录。First_name 数据类型继承自employees.first_name, Last_name数据类型继承自employees.last_name,email数据类型继承自employees.Email。
我们已经声明了一个类型e_list,并且使用IS TABLE OF,我们已经从HR模式链接了表employees,并选择了一个名列,该列的数据类型是从主表继承的,索引是employees.Email。
以及数据类型为employees.email % type的变量Idx以存储索引。
现在在主块中,我们用一个计数器X声明了一个for循环,在in关键字之后,我们分别指定了lower bound和upper bound的值100和110,并用两个点将它们分开。
循环将重复自身,直到X的值保持在数组的100到110个值之间,并且一旦X的值超过110,编译器将移出循环语句。
在循环中,我们使用SELECT命令从employee的表中调用first_name、email,并向声明的表emps(x)添加值,其中employee_id是x。为了显示数组的元素,我们将IDX指定为emps。首先将指针移动到数组的第一个元素,稍后,使用while循环IDX和DBMS output语句以及计数器IDX来显示声明数组的所有元素。每次程序完成一次旋转,IDX的值就会增加,直到所有元素都打印出来。

使用关联数组在数据库表中插入元素的程序
 create table employees_salary_history as select * from employees where 1=2;
 alter table employees_salary_history add insert_date date;
 select * from employees_salary_history;
 /
 declare
   type e_list is table of employees_salary_history%rowtype index by pls_integer;
   emps e_list;
   idx pls_integer;
 begin
     for x in 100 .. 110 loop
     select e.*,'01-JUN-20' into emps(x) from employees e
        where employee_id = x;
   end loop;
   idx := emps.first;
   while idx is not null loop
     emps(idx).salary := emps(idx).salary + emps(idx).salary*0.2;
     insert into employees_salary_history values emps(idx);
     dbms_output.put_line('The employee '|| emps(idx).first_name
                          ||' is inserted to the history table');
     idx := emps.next(idx);
   end loop;
 end;

当我们执行上述代码时,编译器将给出输出-

anonymous block completed
 The employee Steven is inserted into the history table
 The employee Neena is inserted into the history table
 The employee Lex is inserted into the history table
 The employee Alexander is inserted into the history table
 The employee Bruce is inserted into the history table
 The employee David is inserted into the history table
 The employee Valli is inserted into the history table
 The employee Diana is inserted into the history table
 The employee Nancy is inserted into the history table
 The employee Daniel is inserted into the history table
 The employee John is inserted into the history table

在这个程序中,首先,我们创建了一个表employee_salary_history,用从表employees派生的数据存储员工的薪资记录
现在我们必须使用add insert_date命令编辑employees_salary_history表。
/
既然我们有了自己的桌子,现在我们可以根据自己的需要轻松地操纵它。
/
首先,我们声明了类型e_list,并使用IS TABLE OF,从HR架构链接表employees,然后选择数据类型为First name的列,该列从主表继承,索引为employees_salary_history%rowtype
我们已经初始化了emps e_list。
我们声明了一个数据类型为pls_integer的变量Idx来存储索引。
/
现在在主块中,我们用一个计数器X声明了一个for循环,在in关键字之后,我们分别指定了lower bound和upper bound的值100和110,并用两个点将它们分开。
循环将重复自身,直到X的值保持在数组的100到110个值之间,并且一旦X的值超过110,编译器将移出循环语句。
/
在循环中,我们使用SELECT命令从employee的表中添加日期,并添加我们声明的表emps(x)的值,其中employee_id是x。为了显示数组的元素,我们将IDX指定为emps。首先将指针移动到数组的第一个元素
稍后使用while循环IDX和DBMS输出语句以及计数器IDX和while循环。我们首先将记录插入employees_salary_history,然后显示声明数组的所有元素。每次程序完成一次旋转,IDX的值就会增加,直到所有元素都打印出来。

翻译:https://www.tutorialandexample.com/pl-sql-associative-arrays/

malong
关注 私信
文章
35
关注
0
粉丝
0