Oracle Типы объектов PL/SQL: CREATE TYPE с примерами

⚡ Умное резюме

Объектные типы в PL/SQL позволяют использовать объектно-ориентированное программирование. OracleОни позволяют моделировать реальные сущности с помощью атрибутов и методов. Они поддерживают конструкторы, наследование и сравнение на равенство, поэтому один тип на уровне схемы может хранить и обрабатывать структурированные данные.

  • 🧱 Компоненты типов объектов: Тип объекта объединяет атрибуты, хранящие данные, и члены, или методы, определяющие логику его обработки.
  • ???? ️ Создать объект: Типы объектов создаются на уровне схемы с помощью команды CREATE TYPE, а их методы определяются в отдельном теле команды CREATE TYPE BODY.
  • 🔧 Конструкторы: Каждый тип объекта имеет неявный конструктор, названный в честь типа, и вы можете определить явный конструктор для установки значений по умолчанию.
  • 🧬 Наследование: Родительский тип NOT FINAL расширяется с помощью UNDER, поэтому подтип наследует все атрибуты и члены родительского типа.
  • Равенство: Функция-член класса ORDER сравнивает два экземпляра объекта и возвращает отрицательное, нулевое или положительное число.
  • 🤖 Помощь ИИ: Искусственный интеллект, например, GitHub Copilot, создает определения типов CREATE, конструкторы и методы ORDER на основе комментариев.

Oracle Типы объектов PL/SQL, отображающие команду CREATE TYPE с атрибутами и методами.

Что такое тип объекта в PL/SQL?

Объектно-ориентированное программирование особенно хорошо подходит для создания многократно используемых компонентов и сложных приложений. Программы организуются вокруг «объектов», а не «действий»; то есть они предназначены для работы и взаимодействия со всем объектом целиком, а не с отдельным действием. Такой подход позволяет программисту заполнять и изменять детали на уровне объекта и сущности.

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

Банковский счет представлен в виде объектного типа с атрибутами и методами на языке PL/SQL.

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

Компоненты типов объектов

Объектный тип PL/SQL состоит в основном из двух компонентов.

  1. Атрибуты
  2. Члены/Методы

Атрибуты

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

Члены/Методы

Члены, или методы, — это подпрограммы Они определяются внутри типа объекта. Они не используются для хранения данных; вместо этого они определяют обработку, выполняемую внутри типа объекта — например, проверку данных перед заполнением объекта. Они объявляются в спецификации типа объекта и определяются в теле типа объекта. Тело является необязательным: если члены отсутствуют, тип объекта не имеет части тела.

Создать объект в Oracle

Тип объекта нельзя создать на уровне подпрограммы; его можно создать только на уровне схемы. После определения типа объекта в схеме его можно использовать в подпрограммах. Тип объекта создается с помощью оператора «CREATE TYPE», а тело типа может быть создано только после того, как будет создан сам тип объекта.

На скриншотах ниже показан синтаксис CREATE TYPE для описания объекта и синтаксис CREATE TYPE BODY, определяющий его методы.

Синтаксис CREATE TYPE, определяющий спецификацию объекта с атрибутами в Oracle Синтаксис CREATE TYPE BODY, определяющий методы объектного типа PL/SQL.

CREATE TYPE<object_type_name> AS OBJECT
(
<attribute_l><datatype>,
.
.
);
/
CREATE TYPE BODY<object_type_name> AS OBJECT
(
MEMBER[PROCEDURE|FUNCTION]<member_name> 
IS
<declarative section>
BEGIN
<execution part>
END;
.
.
);
/

Объяснение синтаксиса:

  • Приведённый выше синтаксис демонстрирует создание объекта с атрибутами и тела объекта с методами.
  • Методы также можно перегрузить в теле объекта.

Инициализация объявления типа объекта

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

При объявлении переменной как объекта, во время выполнения создается новый экземпляр этого объекта, и на этот вновь созданный экземпляр ссылаются по имени переменной. Таким образом, один объект может хранить несколько значений в разных экземплярах.

На скриншоте ниже показано объявление переменной как объекта внутри Блок PL / SQL.

Объявление переменной объектного типа в декларативной секции блока PL/SQL.

DECLARE
<variable_name> <object_type_name>;
BEGIN
.
.
END;
/

Объяснение синтаксиса:

  • Приведённый выше синтаксис показывает объявление переменная в качестве типа объекта в декларативном разделе.

После объявления переменной как объекта в подпрограмме она атомарно равна null — весь объект сам по себе равен null. Перед использованием в программе её необходимо инициализировать значениями. Инициализация объектов осуществляется с помощью конструкторов.

Конструкторы — это неявные методы объекта, на которые можно ссылаться по тому же имени, что и у типа объекта. На скриншоте ниже показана инициализация экземпляра типа объекта.

Инициализация экземпляра типа объекта значением null с помощью его конструктора.

DECLARE
<variable_name> <object_type_name>; 
BEGIN
<variable_name>:=<object_type_name>();
END;
/

Объяснение синтаксиса:

  • Приведённый выше синтаксис демонстрирует инициализацию экземпляра типа объекта значением null.
  • После инициализации сам объект перестаёт быть нулевым, но атрибуты внутри объекта остаются нулевыми до тех пор, пока им не будут присвоены значения.

Конструкторы

Конструкторы — это неявные методы объекта, на которые можно ссылаться по тому же имени, что и тип объекта. При первом обращении к объекту этот конструктор вызывается неявно.

Вы также можете инициализировать объекты, используя эти конструкторы. Конструктор может быть определен явно путем определения члена в теле типа объекта с тем же именем, что и тип объекта.

Пример 1: В следующем примере мы используем член типа объекта для вставки записей в таблицу emp со значениями ('RRR', 1005, 20000, 1000) и ('PPP', 1006, 20000, 1001). После вставки данных мы отображаем их, используя член типа объекта. Мы также используем явный конструктор для заполнения идентификатора менеджера значением по умолчанию 1001 для второй записи.

Мы выполняем это в несколько этапов.

  • Шаг 1: Создайте тип объекта и тело типа объекта.
  • Шаг 2: Создайте анонимный блок для вызова типа объекта через неявный конструктор для emp_no 1005.
  • Шаг 3: Создайте анонимный блок для вызова типа объекта через явный конструктор для emp_no 1006.

Шаг 1) Создайте тип объекта и тело типа объекта.

На скриншоте ниже показано создание спецификации типа объекта emp_object с указанием его атрибутов и элементов.

Создание спецификации типа объекта emp_object с атрибутами и членами.

CREATE TYPE emp_object AS OBJECT(
emp_no NUMBER,
emp_name VARCHAR2(50),
salary NUMBER,
manager NUMBER,
CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER, p_emp_name VARCHAR2,
p_salary NUMBER) RETURN SELF AS RESULT),
MEMBER PROCEDURE insert_records,
MEMBER PROCEDURE display_records);
/

На скриншоте ниже показано создание тела объекта типа emp_object с явным указанием конструктора и процедур-членов.

Определение тела типа emp_object с явным конструктором и процедурными членами.

CREATE OR REPLACE TYPE BODY emp_object AS
CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER,p_emp_name VARCHAR2,
p_salary NUMBER)
RETURN SELF AS RESULT
IS
BEGIN
Dbms_output.put_line('Constructor fired..');
SELF.emp_no:=p_emp_no;
SELF.emp_name:=p_emp_name;
SELF.salary:=p_salary;
SELF.manager:=1001;
RETURN;
END;
MEMBER PROCEDURE insert_records
IS
BEGIN
INSERT INTO emp VALUES(emp_no,emp_name,salary,manager);
END;
MEMBER PROCEDURE display_records
IS
BEGIN
Dbms_output.put_line('Employee Name:'||emp_name);
Dbms_output.put_line('Employee Number:'||emp_no);
Dbms_output.put_line('Salary:'||salary);
Dbms_output.put_line('Manager:'||manager);
END;
END;
/

Code объяснение

  • Code строки 1-9: Создание объекта типа 'emp_object' с 4 атрибутами и 3 членами. Он содержит определение конструктора всего с 3 параметрами. (Фактический неявный конструктор содержит количество параметров, равное количеству атрибутов, присутствующих в объекте типа.)
  • Code строка 10: Создание основного текста.
  • Code строки 11-21: Определение явного конструктора. Присвоение значений параметров атрибутам и присвоение атрибуту 'manager' значения по умолчанию '1001'.
  • Code строки 22-26: Определение элемента 'insert_records', в который вставляются значения атрибутов в таблицу 'emp'.
  • Code строки 27-34: Определение элемента 'display_records', который отображает значения атрибутов типа объекта.

Выход:

Тип создан

Тип созданного тела

Шаг 2) Создание анонимного блока для вызова созданного типа объекта через неявный конструктор для emp_no 1005.

На скриншоте ниже показан анонимный блок, который вызывает emp_object через неявный конструктор.

Анонимный блок, вызывающий emp_object через неявный конструктор для emp_no 1005

DECLARE
guru_emp_det emp_object;
BEGIN
guru_emp_det:=emp_object(1005,'RRR',20000,1000);
guru_emp_det.display_records;
guru_emp_det.insert_records;
COMMIT;
END;

Code объяснение

  • Code строки 37-45: Вставка записей осуществляется с помощью неявного конструктора. Вызов конструктора содержит фактическое количество значений атрибутов.
  • Code строка 38: Объявляет 'guru_emp_det' как объект типа 'emp_object'.
  • Code строка 41: Оператор 'guru_emp_det.display_records' вызывает член 'display_records', и значения атрибутов отображаются.
  • Code строка 42: Оператор 'guru_emp_det.insert_records' вызывает член 'insert_records', и значения атрибутов вставляются в таблицу. Затем блок фиксирует изменения. сделка.

Выход:

Имя сотрудника: РРР

Номер сотрудника: 1005

Зарплата: 20000

Менеджер: 1000

Шаг 3) Создание анонимного блока для вызова созданного типа объекта через явный конструктор для emp_no 1006.

На скриншоте ниже показан анонимный блок, который вызывает функцию emp_object через явный конструктор с тремя аргументами.

Анонимный блок, вызывающий emp_object через явный конструктор для emp_no 1006

DECLARE
guru_emp_det emp_object;
BEGIN
guru_emp_det:=emp_object(1006,'PPP',20000);
guru_emp_det.display_records;
guru_emp_det.insert_records;
COMMIT;
END;
/

Результат

Employee Name:PPP 
Employee Number:1006 
Salary:20000 
Manager:1001

Code Объяснение:

  • Code строки 46-53: Вставка записи с использованием явного конструктора.
  • Code строка 46: Объявляет 'guru_emp_det' как объект типа 'emp_object'.
  • Code строка 50: Оператор 'guru_emp_det.display_records' вызывает член 'display_records', и значения атрибутов отображаются.
  • Code строка 51: Оператор `guru_emp_det.insert_records` вызывает член `insert_records`, и значения атрибутов вставляются в таблицу. Поскольку передаются только три аргумента, явный конструктор устанавливает идентификатор менеджера на его значение по умолчанию 1001.

Наследование в типе объекта

Свойство наследования позволяет дочернему типу объекта получать доступ ко всем атрибутам и членам родительского типа объекта.

Вспомогательный тип объекта называется наследуемым типом объекта, а супертип объекта — родительским типом объекта. Приведенный ниже синтаксис показывает, как создавать родительские и наследуемые типы объектов. На скриншоте ниже показан синтаксис родительского (СУПЕР) типа, помеченный как NOT FINAL.

Синтаксис CREATE TYPE для родительского типа объекта NOT FINAL, используемого в наследовании.

CREATE TYPE <object_type_name_parent> AS OBJECT
(
<attribute_l><datatype>,
.
.
)NOT FINAL;
/

Объяснение синтаксиса:

  • Приведённый выше синтаксис демонстрирует создание типа SUPER. Предложение NOT FINAL позволяет наследовать этот тип.

На скриншоте ниже показан синтаксис унаследованного типа (SUB), созданного с помощью ключевого слова UNDER.

Синтаксис CREATE TYPE UNDER предназначен для подобъектного типа, наследующего от родительского типа.

CREATE TYPE<object_type_name_sub>UNDER<object_type_name_parent>
(
<attribute_l><datatype>,
.
);
/

Объяснение синтаксиса:

  • Приведённый выше синтаксис демонстрирует создание подтипа. Он содержит все члены и атрибуты родительского типа объекта.

Пример 1: В приведенном ниже примере мы используем свойство наследования для вставки записи с идентификатором менеджера '1002' в запись ('RRR', 1007, 20000). Выполнение программы осуществляется в следующих шагах.

  • Шаг 1: Создайте тип SUPER.
  • Шаг 2: Создайте подтип и тело.
  • Шаг 3: Создайте анонимный блок для вызова типа SUB.

Шаг 1) Создайте тип SUPER или родительский тип.

На скриншоте ниже показано создание супертипа emp_object с использованием предложения NOT FINAL.

Создание супертипа emp_object NOT FINAL для примера наследования

CREATE TYPE emp_object AS OBJECT(
emp_no NUMBER,
emp_name VARCHAR2(50),
salary NUMBER,
manager NUMBER,
CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER,p_emp_name VARCHAR2(50),
p_salary NUMBER)RETURN SELF AS RESULT),
MEMBER PROCEDURE insert_records,
MEMBER PROCEDURE display_records)NOT FINAL;
/

Code Объяснение:

  • Code строки 1-9: Создается объект типа 'emp_object' с 4 атрибутами и 3 членами. Он содержит определение конструктора всего с 3 параметрами. Он объявлен как 'NOT FINAL', поэтому является родительским типом.

Шаг 2) Создайте подтип внутри супертипа.

На скриншоте ниже показано создание унаследованного типа sub_emp_object и его тела.

Создание унаследованного типа sub_emp_object и его тела с помощью insert_default_mgr

CREATE OR REPLACE TYPE sub_emp_object 
UNDER emp_object
(default_manager NUMBER,MEMBER PROCEDURE insert_default_mgr);
/


CREATE OR REPLACE TYPE BODY sub_emp_object 
AS
MEMBER PROCEDURE insert_default_mgr 
IS
BEGIN
INSERT INTO emp
VALUES(emp_no,emp_name,salary,manager);
END;
END;
/

Code Объяснение:

  • Code строки 10-13: Создание типа наследования 'sub_emp_object' с одним дополнительным атрибутом 'default_manager' и объявлением процедуры-члена.
  • Code строка 14: Создание тела для унаследованного типа объекта.
  • Code строки 16-21: Определяется процедура-член, которая вставляет записи в таблицу 'emp' со значениями из объекта типа SUPER, за исключением значения manager. Для значения manager используется значение 'default_manager' из типа SUB.

Шаг 3) Создание анонимного блока для вызова типа SUB.

На скриншоте ниже показан анонимный блок, который вызывает тип SUB и вставляет идентификатор менеджера по умолчанию.

Анонимный блок, вызывающий тип sub_emp_object для вставки идентификатора менеджера по умолчанию.

DECLARE
guru_emp_det sub_emp_object;
BEGIN
guru_emp_det:= sub_emp_object(1007,'RRR',20000,1000,1002);
guru_emp_det.insert_default_mgr;
COMMIT;
END;
/

Code Объяснение:

  • Code строка 25: Объявление типа 'guru_emp_det' как 'sub_emp_object'.
  • Code строка 27: Инициализация объекта с помощью неявного конструктора. Конструктор имеет 5 параметров (4 атрибута типа PARENT и 1 атрибут типа SUB). Последний параметр (1002) определяет значение атрибута default_manager.
  • Code строка 28: Вызов метода 'insert_default_mgr' для вставки записи с идентификатором менеджера по умолчанию, переданным в конструкторе.

Равенство объектов PL/SQL

Экземпляры объектов, принадлежащие к одному и тому же типу, могут сравниваться на равенство. Для этого типу объекта необходим специальный метод, называемый методом ORDER.

Метод ORDER должен быть функцией, возвращающей числовой тип. Он принимает два входных параметра (первый параметр: идентификатор экземпляра объекта self; второй параметр: идентификатор другого экземпляра объекта).

Идентификаторы двух экземпляров объекта сравниваются, и результат возвращается в виде числа.

  • Положительное значение указывает на то, что экземпляр объекта SELF больше, чем другой экземпляр.
  • Отрицательное значение указывает на то, что экземпляр объекта SELF меньше, чем другой экземпляр.
  • Ноль указывает на то, что экземпляр объекта SELF равен другому экземпляру.
  • Если хотя бы один из экземпляров равен null, функция возвращает null.

На скриншоте ниже показан синтаксис функции-члена ORDER, которую необходимо включить в тело типа для проверки на равенство.

Синтаксис функции-члена ORDER используется для сравнения экземпляров объектов на равенство.

CREATE TYPE BODY<object_type_name_ 1>AS OBJECT
(
  ORDER MEMBER FUNCTION match(<parameter> object_type_name_ 1)
  RETURN INTEGER IS
  BEGIN
    IF <attribute_name>parameter <attribute_name>THEN
      RETURN -1; --any negative number will do
    ELSIF id>c.id THEN
      RETURN 1; --any positive number will do
    ELSE
      RETURN 0;
    END IF;
  END;
  .
  .
);
/

Объяснение синтаксиса:

  • Приведённый выше синтаксис показывает функцию ORDER, которую необходимо включить в тело типа для проверки на равенство.
  • Параметр этой функции должен быть экземпляром того же типа объекта.
  • Функцию можно вызвать как “obj_instance_1.match(obj_instance_2)”, и это выражение вернет указанное числовое значение, где obj_instance_1 и obj_instance_2 являются экземплярами объекта данного типа.

Пример 1: В следующем примере мы сравниваем два объекта. Мы создаём два экземпляра и сравниваем между ними атрибут «зарплата». Мы делаем это в два этапа.

  • Шаг 1: Создайте тип объекта и его тело.
  • Шаг 2: Создайте анонимный блок для сравнения экземпляров объектов.

Шаг 1) Создание типа объекта и его содержимого.

На скриншотах ниже показана спецификация emp_object_equality и ее тело, определяющее функцию ORDER, которая сравнивает атрибут salary.

Создание спецификации типа объекта emp_object_equality с помощью функции ORDER. Определение типа тела функции emp_object_equality, которая сравнивает атрибут salary.

CREATE TYPE emp_object_equality AS OBJECT(
salary NUMBER,
ORDER MEMBER FUNCTION equals(c emp_object_equality)RETURN INTEGER);
/
CREATE TYPE BODY emp_object_equality AS
ORDER MEMBER FUNCTION equals(c emp_object_equality)RETURN INTEGER 
IS
BEGIN
IF salary<c.salary
THEN RETURN -1;
ELSIF salary>c.salary
THEN RETURN 1;
ELSE
RETURN 0;
END IF;
END;
END;
/

Code Объяснение:

  • Code строки 1-4: Создание объекта типа 'emp_object_equality' с 1 атрибутом и 1 членом.
  • Code строки 6-16: Определение функции ORDER, которая сравнивает атрибут 'salary' экземпляра SELF и экземпляра параметра. Она возвращает отрицательное значение, если зарплата SELF меньше, положительное значение, если зарплата SELF больше, и 0, если зарплаты равны.

Code Выход:

Тип создан

Шаг 2) Создание анонимного блока для сравнения экземпляров объектов.

На скриншоте ниже показан анонимный блок, сравнивающий два экземпляра emp_object_equality по уровню заработной платы.

Анонимный блок, сравнивающий два экземпляра emp_object_equality по зарплате.

DECLARE
l_obj_1 emp_object_equality;
l_obj_2 emp_object_equality;
BEGIN
l_obj_1:=emp_object_equality(15000); 
l_obj_2:=emp_object_equality(17000);
IF l_obj_1.equals(l_obj_2)>0
THEN
Dbms_output.put_line('Salary of first instance is greater');
ELSIF l_obj_1.equals(l_obj_2)<0
THEN
Dbms_output.put_line('Salary of second instance is greater'); 
ELSE
Dbms_output.put_line('Salaries are equal');
END IF;
END;
/

Результат

Salary of second instance is greater

Code Объяснение:

  • Code строка 20: Объявление объекта 'l_obj_1' типа 'emp_object_equality'.
  • Code строка 21: Объявление объекта 'l_obj_2' типа 'emp_object_equality'.
  • Code строка 23: Инициализация переменной 'l_obj_1' значением зарплаты '15000'.
  • Code строка 24: Инициализация переменной 'l_obj_2' значением зарплаты '17000'.
  • Code строки 25-33: Вывод сообщения на основе числа, возвращаемого функцией ORDER.

Часто задаваемые вопросы (FAQ)

Тип объекта моделирует отдельную сущность реального мира с атрибутами и методами. лыжных шлемов — Вложенный массив (VARRAY), вложенная таблица или ассоциативный массив — хранит множество элементов одного типа данных. Объектные типы описывают структуру и поведение, а коллекции хранят несколько значений.

Оба метода сравнивают экземпляры объектов. Метод MAP возвращает одно скалярное значение, которое Oracle Метод `ORDER` используется для сортировки или сравнения объектов, в то время как метод `ORDER` сравнивает два экземпляра напрямую и возвращает отрицательное, нулевое или положительное число. Тип может определять либо один, либо другой тип, но не оба одновременно.

Да. Вы можете создать объектную таблицу, где каждая строка представляет собой экземпляр объекта, или использовать объектный тип в качестве типа данных для столбца таблицы. Это позволяет Oracle Сохранение структурированных объектов непосредственно в базе данных, а не только в памяти.

Тип NOT INSTANTIABLE не может создавать объекты напрямую; он действует как абстракция.tracБазовый тип, расширяемый другими типами. В сочетании с NOT FINAL он определяет супертип, подтипы которого обеспечивают конкретную реализацию объявленных им методов.

Используйте ALTER TYPE для добавления или удаления атрибутов и методов, CASCADE для обновления зависимых объектов, а DROP TYPE — для удаления типа. Тип, который все еще используется таблицами или другими типами, нельзя удалить, пока не будут обработаны эти зависимые объекты.

Запросите представления словаря данных USER_TYPES и ALL_TYPES для получения имен типов, а также USER_TYPE_ATTRS и USER_TYPE_METHODS для получения их атрибутов и методов. Эти представления позволяют проводить аудит существующей объектной модели без чтения исходного кода.

Да. Второй пилот GitHub Создает черновики спецификаций CREATE TYPE, методов TYPE BODY, конструкторов и функций ORDER на основе комментария. RevПеред развертыванием сгенерированного типа ознакомьтесь с типами данных атрибутов, параметрами конструктора и условиями наследования.

Искусственный интеллект-помощник анализирует ваши таблицы и предлагает типы объектов, карты атрибутов.pingи иерархии наследования. Этот анализ с использованием машинного обучения выявляет избыточные атрибуты, отсутствующие конструкторы и слишком глубокое наследование до того, как объектная модель попадет в производство, что повышает удобство сопровождения.

Подведем итог этой публикации следующим образом: