Учебники

PL / SQL — Коллекции

В этой главе мы обсудим Коллекции в PL / SQL. Коллекция — это упорядоченная группа элементов, имеющих один и тот же тип данных. Каждый элемент идентифицируется уникальным индексом, который представляет его позицию в коллекции.

PL / SQL предоставляет три типа коллекций —

  • Индексные таблицы или ассоциативный массив
  • Вложенный стол
  • Массив переменного размера или Varray

Документация Oracle содержит следующие характеристики для каждого типа коллекций:

Тип коллекции Количество элементов Тип нижнего индекса Плотный или разреженный Где создано Может быть атрибутом типа объекта
Ассоциативный массив (или индексированная таблица) неограниченный Строка или целое число Или Только в блоке PL / SQL нет
Вложенный стол неограниченный целое число Начинается плотно, может стать разреженным Либо в блоке PL / SQL, либо на уровне схемы да
Массив переменных размеров (Varray) ограниченный целое число Всегда плотный Либо в блоке PL / SQL, либо на уровне схемы да

Мы уже обсуждали varray в главе «Массивы PL / SQL» . В этой главе мы обсудим таблицы PL / SQL.

Оба типа таблиц PL / SQL, т. Е. Таблицы index-by и вложенные таблицы, имеют одинаковую структуру, и доступ к их строкам осуществляется с использованием индексной записи. Однако эти два типа таблиц отличаются в одном аспекте; вложенные таблицы могут храниться в столбце базы данных, а таблицы индекса по — нет.

Индекс по таблице

Таблица index-by (также называемая ассоциативным массивом ) — это набор пар ключ-значение . Каждый ключ уникален и используется для поиска соответствующего значения. Ключ может быть целым числом или строкой.

Индексная таблица создается с использованием следующего синтаксиса. Здесь мы создаем таблицу index-by с именем table_name , ключи которой будут иметь тип subscript_type, а связанные значения будут иметь тип element_type.

TYPE type_name IS TABLE OF element_type [NOT NULL] INDEX BY subscript_type; 
 
table_name type_name;

пример

В следующем примере показано, как создать таблицу для хранения целочисленных значений вместе с именами, а затем распечатывает тот же список имен.

DECLARE 
   TYPE salary IS TABLE OF NUMBER INDEX BY VARCHAR2(20); 
   salary_list salary; 
   name   VARCHAR2(20); 
BEGIN 
   -- adding elements to the table 
   salary_list('Rajnish') := 62000; 
   salary_list('Minakshi') := 75000; 
   salary_list('Martin') := 100000; 
   salary_list('James') := 78000;  
   
   -- printing the table 
   name := salary_list.FIRST; 
   WHILE name IS NOT null LOOP 
      dbms_output.put_line 
      ('Salary of ' || name || ' is ' || TO_CHAR(salary_list(name))); 
      name := salary_list.NEXT(name); 
   END LOOP; 
END; 
/

Когда приведенный выше код выполняется в командной строке SQL, он дает следующий результат —

Salary of James is 78000 
Salary of Martin is 100000 
Salary of Minakshi is 75000 
Salary of Rajnish is 62000  

PL/SQL procedure successfully completed.

пример

Элементами таблицы index-by также может быть % ROWTYPE любой таблицы базы данных или % TYPE любого поля таблицы базы данных. Следующий пример иллюстрирует концепцию. Мы будем использовать таблицу CUSTOMERS, хранящуюся в нашей базе данных, как —

Select * from customers;  

+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 | 
|  2 | Khilan   |  25 | Delhi     |  1500.00 | 
|  3 | kaushik  |  23 | Kota      |  2000.00 | 
|  4 | Chaitali |  25 | Mumbai    |  6500.00 | 
|  5 | Hardik   |  27 | Bhopal    |  8500.00 | 
|  6 | Komal    |  22 | MP        |  4500.00 | 
+----+----------+-----+-----------+----------+  

DECLARE 
   CURSOR c_customers is 
      select name from customers; 

   TYPE c_list IS TABLE of customers.Name%type INDEX BY binary_integer; 
   name_list c_list; 
   counter integer :=0; 
BEGIN 
   FOR n IN c_customers LOOP 
      counter := counter +1; 
      name_list(counter) := n.name; 
      dbms_output.put_line('Customer('||counter||'):'||name_lis t(counter)); 
   END LOOP; 
END; 
/ 

Когда приведенный выше код выполняется в командной строке SQL, он дает следующий результат —

Customer(1): Ramesh  
Customer(2): Khilan  
Customer(3): kaushik     
Customer(4): Chaitali  
Customer(5): Hardik  
Customer(6): Komal  

PL/SQL procedure successfully completed

Вложенные таблицы

Вложенная таблица похожа на одномерный массив с произвольным числом элементов. Однако вложенная таблица отличается от массива в следующих аспектах:

  • Массив имеет объявленное количество элементов, а вложенная таблица — нет. Размер вложенной таблицы может динамически увеличиваться.

  • Массив всегда плотный, т. Е. Всегда имеет последовательные индексы. Первоначально вложенный массив является плотным, но при удалении элементов из него он может стать разреженным.

Массив имеет объявленное количество элементов, а вложенная таблица — нет. Размер вложенной таблицы может динамически увеличиваться.

Массив всегда плотный, т. Е. Всегда имеет последовательные индексы. Первоначально вложенный массив является плотным, но при удалении элементов из него он может стать разреженным.

Вложенная таблица создается с использованием следующего синтаксиса —

TYPE type_name IS TABLE OF element_type [NOT NULL]; 
 
table_name type_name; 

Это объявление аналогично объявлению таблицы index-by , но в ней нет предложения INDEX BY .

Вложенная таблица может храниться в столбце базы данных. Кроме того, его можно использовать для упрощения операций SQL, когда вы объединяете таблицу с одним столбцом и таблицу большего размера. Ассоциативный массив не может быть сохранен в базе данных.

пример

Следующие примеры иллюстрируют использование вложенной таблицы —

DECLARE 
   TYPE names_table IS TABLE OF VARCHAR2(10); 
   TYPE grades IS TABLE OF INTEGER;  
   names names_table; 
   marks grades; 
   total integer; 
BEGIN 
   names := names_table('Kavita', 'Pritam', 'Ayan', 'Rishav', 'Aziz'); 
   marks:= grades(98, 97, 78, 87, 92); 
   total := names.count; 
   dbms_output.put_line('Total '|| total || ' Students'); 
   FOR i IN 1 .. total LOOP 
      dbms_output.put_line('Student:'||names(i)||', Marks:' || marks(i)); 
   end loop; 
END; 
/  

Когда приведенный выше код выполняется в командной строке SQL, он дает следующий результат —

Total 5 Students 
Student:Kavita, Marks:98 
Student:Pritam, Marks:97 
Student:Ayan, Marks:78 
Student:Rishav, Marks:87 
Student:Aziz, Marks:92  

PL/SQL procedure successfully completed. 

пример

Элементы вложенной таблицы также могут быть % ROWTYPE любой таблицы базы данных или% TYPE любого поля таблицы базы данных. Следующий пример иллюстрирует концепцию. Мы будем использовать таблицу CUSTOMERS, хранящуюся в нашей базе данных, как —

Select * from customers;  

+----+----------+-----+-----------+----------+ 
| ID | NAME     | AGE | ADDRESS   | SALARY   | 
+----+----------+-----+-----------+----------+ 
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 | 
|  2 | Khilan   |  25 | Delhi     |  1500.00 | 
|  3 | kaushik  |  23 | Kota      |  2000.00 | 
|  4 | Chaitali |  25 | Mumbai    |  6500.00 | 
|  5 | Hardik   |  27 | Bhopal    |  8500.00 | 
|  6 | Komal    |  22 | MP        |  4500.00 | 
+----+----------+-----+-----------+----------+ 

DECLARE 
   CURSOR c_customers is  
      SELECT  name FROM customers;  
   TYPE c_list IS TABLE of customerS.No.ame%type; 
   name_list c_list := c_list(); 
   counter integer :=0; 
BEGIN 
   FOR n IN c_customers LOOP 
      counter := counter +1; 
      name_list.extend; 
      name_list(counter)  := n.name; 
      dbms_output.put_line('Customer('||counter||'):'||name_list(counter)); 
   END LOOP; 
END; 
/ 

Когда приведенный выше код выполняется в командной строке SQL, он дает следующий результат —

Customer(1): Ramesh  
Customer(2): Khilan  
Customer(3): kaushik     
Customer(4): Chaitali  
Customer(5): Hardik  
Customer(6): Komal  

PL/SQL procedure successfully completed. 

Методы сбора

PL / SQL предоставляет встроенные методы сбора, которые облегчают использование коллекций. В следующей таблице перечислены методы и их назначение.

S.No Название метода и цель
1

EXISTS (п)

Возвращает TRUE, если n-й элемент в коллекции существует; в противном случае возвращает FALSE.

2

COUNT

Возвращает количество элементов, которые в данный момент содержит коллекция.

3

ПРЕДЕЛ

Проверяет максимальный размер коллекции.

4

ПЕРВЫЙ

Возвращает первые (самые маленькие) индексные числа в коллекции, которая использует целочисленные индексы.

5

ПРОШЛОЙ

Возвращает последние (самые большие) индексы в коллекции, которая использует целочисленные индексы.

6

Предшествующий уровень (п)

Возвращает номер индекса, который предшествует индексу n в коллекции.

7

NEXT (п)

Возвращает номер индекса, который следует за индексом n.

8

ПРОДЛИТЕ

Добавляет один нулевой элемент в коллекцию.

9

ПРОДЛИТЕ (п)

Добавляет в коллекцию n пустых элементов.

10

ПРОДЛИТЕ (п, я)

Добавляет n копий i- го элемента в коллекцию.

11

ОТДЕЛКА

Удаляет один элемент из конца коллекции.

12

TRIM (п)

Удаляет n элементов из конца коллекции.

13

УДАЛЯТЬ

Удаляет все элементы из коллекции, устанавливая COUNT в 0.

14

DELETE (п)

Удаляет n- й элемент из ассоциативного массива с числовым ключом или вложенной таблицей. Если ассоциативный массив имеет строковый ключ, элемент, соответствующий значению ключа, удаляется. Если n равно нулю, DELETE (n) ничего не делает.

15

DELETE (т, п)

Удаляет все элементы в диапазоне m..n из ассоциативного массива или вложенной таблицы. Если m больше чем n или если m или n равно нулю, DELETE (m, n) ничего не делает.

EXISTS (п)

Возвращает TRUE, если n-й элемент в коллекции существует; в противном случае возвращает FALSE.

COUNT

Возвращает количество элементов, которые в данный момент содержит коллекция.

ПРЕДЕЛ

Проверяет максимальный размер коллекции.

ПЕРВЫЙ

Возвращает первые (самые маленькие) индексные числа в коллекции, которая использует целочисленные индексы.

ПРОШЛОЙ

Возвращает последние (самые большие) индексы в коллекции, которая использует целочисленные индексы.

Предшествующий уровень (п)

Возвращает номер индекса, который предшествует индексу n в коллекции.

NEXT (п)

Возвращает номер индекса, который следует за индексом n.

ПРОДЛИТЕ

Добавляет один нулевой элемент в коллекцию.

ПРОДЛИТЕ (п)

Добавляет в коллекцию n пустых элементов.

ПРОДЛИТЕ (п, я)

Добавляет n копий i- го элемента в коллекцию.

ОТДЕЛКА

Удаляет один элемент из конца коллекции.

TRIM (п)

Удаляет n элементов из конца коллекции.

УДАЛЯТЬ

Удаляет все элементы из коллекции, устанавливая COUNT в 0.

DELETE (п)

Удаляет n- й элемент из ассоциативного массива с числовым ключом или вложенной таблицей. Если ассоциативный массив имеет строковый ключ, элемент, соответствующий значению ключа, удаляется. Если n равно нулю, DELETE (n) ничего не делает.

DELETE (т, п)

Удаляет все элементы в диапазоне m..n из ассоциативного массива или вложенной таблицы. Если m больше чем n или если m или n равно нулю, DELETE (m, n) ничего не делает.

Коллекция исключений

В следующей таблице приведены исключения коллекций, а также когда они возникают —