在Oracle中使用不同类型的PL / SQL集合的目的

问题描述 投票:4回答:6

在oracle中使用集合的主要目的是什么?

  1. 按表索引
  2. 嵌套表
  3. 可变大小的ARRAY

你能解释一下上述类型的收藏品之间的区别吗?

oracle collections user-defined-types
6个回答
21
投票

让我们从嵌套表开始,它们是最常见的集合形式,因此代表了比较的有用基础。

嵌套表是一个变量,它可以包含多个实例,通常是数据库表中的记录。他们可能会这样声明:

type emp_nt is table of emp%rowtype;
emp_rec_nt emp_nt;

每当我们想要存储我们想要做同样事情的多个数据实例时,它们就很有用。经典示例使用BULK COLLECT存储多个记录:

select * 
bulk collect into emp_rec_nt
from employees;

这为我们提供了循环数据的来源;至关重要的是,我们可以向后和向前导航,甚至跳到结束或开始,这是我们用光标无法做到的事情。嵌套表可以是任何数据类型的集合,包括PL / SQL记录或用户定义类型等组合。

Index By表更好地称为(如文档所示)关联数组。这些是带索引的单个属性的简单集合。嵌套表也有索引,但它们的索引只是行数。对于关联数组,索引可以是有意义的,即源自数据值。因此,它们可用于缓存数据值以供以后使用。索引可以是一个数字,或者(从9iR2开始)一个非常有用的字符串。例如,这是一个工资关联数组,由员工标识符索引。

type emp_sal_aa is table of emp.sql%type
     index by emp.empno%type;
l_emp_sales emp_sal_aa;

请注意,我可以使用INDEX BY BINARY_INTEGER声明该数组,但使用%TYPE语法(自记录代码)更清楚。该数组的元素可以通过索引值标识,在本例中为EMPNO:

l_emp_sals(l_emp_no) := l_emp_sal;

除了缓存参考表或类似的查找值之外,关联数组的用例并不多。

变量数组只是嵌套表,对元素数量有预定义的限制。所以这个名字可能具有误导性:它们实际上是固定数组。我们用VArrays做的很少,我们不能用嵌套表做(除了限制元素的数量,我们很想做到这一点)。它们被声明为:

type emp_va is varray(14) of emp%rowtype;
emp_rec_va emp_va;

我们可以使用批量收集来填充VArray ......

select * 
bulk collect into emp_rec_va
from employees;

但是我们必须确定查询最多将返回VArray声明中指定的元素数。否则SELECT将投掷ORA-22165。

变量数组没有已知的用例。好吧,这有点苛刻,但几乎所有的时候你都会使用嵌套表。 VArrays相对于嵌套表的一大优势是它们保证了元素的顺序。因此,如果您必须按照插入的顺序获取元素,请使用VArray。

PL / SQL文档将整个章节用于集合。 Find out more


5
投票

PL / SQL提供以下集合类型: -

关联数组(也称为索引表)允许您使用任意数字和字符串查找元素以查找下标值。这些类似于其他编程语言中的哈希表。

嵌套表包含任意数量的元素。他们使用序号作为下标。您可以定义等效的SQL类型,允许嵌套表存储在数据库表中并通过SQL进行操作。

Varrays(可变大小数组的缩写)包含固定数量的元素(尽管您可以在运行时更改元素的数量)。他们使用序号作为下标。您可以定义等效的SQL类型,允许将varrays存储在数据库表中。它们可以通过SQL存储和检索,但灵活性低于嵌套表。

1.在嵌套表和关联数组之间选择: -

嵌套表和关联数组(以前称为索引表)使用类似的下标表示法,但在持久性和参数传递的简易性方面它们具有不同的特征。

嵌套表可以存储在数据库列中,但关联数组不能。嵌套表可以简化SQL操作,您通常可以使用更大的表连接单列表。

关联数组适用于相对较小的查找表,其中每次调用过程或初始化包时都可以在内存中构造集合。它们适用于收集预先未知量的信息,因为它们的大小没有固定限制。它们的索引值更灵活,因为关联数组下标可以是负数,可以是非顺序的,并且可以使用字符串值而不是数字。

PL / SQL自动在主机数组和使用数字键值的关联数组之间进行转换。将集合传入和传出数据库服务器的最有效方法是在关联数组中设置数据值,然后将这些关联数组与批量结构一起使用(FORALL语句或BULK COLLECT子句)。

2.在嵌套表和变量之间选择: -

Varrays是一个很好的选择:

元素的数量是预先知道的。

这些元素通常都是按顺序访问的。

存储在数据库中时,varrays会保留其顺序和下标。

每个varray都存储为单个对象,在表的内部(如果varray小于4KB)或表外但仍在同一个表空间(如果varray大于4KB)。您必须同时更新或检索varray的所有元素,这在一次对所有元素执行某些操作时最合适。但是你可能会发现以这种方式存储和检索大量元素是不切实际的。

嵌套表是一个很好的选择:

索引值不是连续的。

没有设定数量的索引值。但是,施加了最大限制。

您需要一次删除或更新某些元素,但不能删除所有元素。

您通常会创建一个单独的查找表,主表的每一行都有多个条目,并通过连接查询访问它。

嵌套表可以是稀疏的:您可以删除任意元素,而不是仅从末尾删除项。

嵌套表数据存储在单独的存储表中,该表是与嵌套表关联的系统生成的数据库表。当您访问嵌套表时,数据库会为您加入表。这使得嵌套表适用于仅影响集合的某些元素的查询和更新。

由于嵌套表存储在数据库中并从数据库中检索,因此不能依赖嵌套表的顺序和下标保持稳定,因为订单和下标不会保留在数据库中。


2
投票

你可以使用链接

What is the difference between nested array and associative array?

或者只是阅读它。

嵌套表只是n个元素的数组。

declare
  type nested_table_of_integer is table of integer;
  v_my_nested_table nested_table_of_integer;
begin
  v_my_nested_table := nested_table_of_integer(); -- initialize
  v_my_nested_table.extend(10); -- add 10 elements
  v_my_nested_table(1) := 100;
  v_my_nested_table(11) := 1000; -- ORA-06533: Subscript beyond count
end;

必须如图所示初始化嵌套表。它最初只有零元素。要添加元素,我们使用EXTEND。这个嵌套表有10个元素。它们的索引为1到10.元素1的值为100.其他值为null。访问不存在的元素,比如第11个元素,会引发错误。

另一方面,关联数组是名称/值对的数组。让我们使用数字(通常是pls_integer)来命名:

declare
      type associative_array_of_integer is table of integer index by pls_integer;
      v_my_associative_array associative_array_of_integer;
    begin
      v_my_associative_array(1) := 100;
      v_my_associative_array(11) := 1000;
      v_my_associative_array(12) := v_my_associative_array(2); -- ORA-01403: no data found

end;

关联数组不需要初始化。它是空的并且被填充。在这里,我们将名为1的元素与值100相关联,将名称为11的元素与值1000相关联。因此,数组中有两个元素。当我们尝试访问不在数组中的名称时,我们得到一个无数据发现异常。

我们也可以使用字符串作为名称:

declare
  type associative_array_of_integer is table of integer index by varchar2(100);
  v_my_associative_array associative_array_of_integer;
begin
  v_my_associative_array('age father') := 39;
  v_my_associative_array('age mother') := 32;
  v_my_associative_array('age daughter') := 11;
end;

您可以使用这两个集合来获取表数据,但是使用它们的方式不同。嵌套表有一个计数,你可以从1循环到count来访问它的元素:

declare
  type nested_table_of_integer is table of integer;
  v_my_nested_table nested_table_of_integer;
begin
  v_my_nested_table := nested_table_of_integer(); -- initialize
  select table_name bulk collect into v_my_nested_table from user_tables;
  for i in 1 .. v_my_nested_table.count loop
    dbms_output.put_line(v_my_nested_table(i));
  end loop;
end;

然而,关联数组必须从使用FIRST和NEXT的下一个和下一个和下一个的第一个索引中读取。

declare
  type associative_array_of_integer is table of integer index by pls_integer;
  v_my_associative_array associative_array_of_integer;
  i integer;
 begin
  select table_name bulk collect into v_my_associative_array from user_tables;
  i := v_my_associative_array.first;
  while i is not null loop
    dbms_output.put_line(v_my_associative_array(i));
    i := v_my_associative_array.next(i);
  end loop;
end;

这里的“名称”恰好是1,2,3等(由批量集合给出),例如你可以访问v_my_associative_array(1)。但是,在程序的后面,在数组中的一些可能的删除操作之后,可能存在间隙,因此您不知道是否存在名为1的元素以及元素4之前的元素是否恰好是元素3.与批量收集一样元素的“名称”没有意义,你不会真正使用它们,而是通过如图所示的链。


0
投票

按表索引是用户定义的数据类型,用于存储多个数据项。基本上这些表是不受约束的表。按表分列有两部分,这些是值字段和键字段。在值字段中,oracle服务器存储实际数据,其中在关键字段oracle服务器存储索引时,这就是为什么索引按表具有“键值”对,并且索引也是默认整数,并且这些索引在负数到正数之间。此索引字段的行为类似于主键,它不接受重复值。通常使用表索引来提高性能或应用程序,因为这些表存储在内存区域中,这就是为什么这些表也称为内存表。通常为了提高应用程序的性能,这些表索引都使用'二进制整数'数据类型,因此我们分两步创建。首先我们创建类型,然后我们只创建该类型的变量。

句法:-

步骤1: - 类型typename是binary_integer的数据类型(大小)索引表;

第2步: - 变量名类型名称;

对于Morinformation >>> PL/SQL Index by tables (or) PL/SQL tables (or) associative arrays


0
投票

集合是一组有序的元素,所有元素都是相同的类型。每个元素由唯一的下标标识,该下标表示其在集合中的位置

PL / SQL提供三种集合类型 -

索引表或关联数组嵌套表可变大小数组或Varray


-1
投票

使用集合的主要目的是提高应用程序性能。通过使用集合,我们可以“缓存”需要经常访问并需要修改的静态数据。这导致对数据库的调用减少。

此外,如果您需要处理类似类型的多个项目,则将这些项目存储在集合中将允许您轻松遍历每个元素,并通过索引引用每个元素。

Refer this article for more detail information about collection

© www.soinside.com 2019 - 2024. All rights reserved.