Oracle Навчальний посібник із типів об’єктів PL/SQL із ПРИКЛАДАМИ

Що таке тип об’єкта в PL/SQL?

Об’єктно-орієнтоване програмування особливо підходить для створення повторно використовуваних компонентів і складних програм. Вони організовані навколо «об’єктів», а не «дій», тобто програми розроблені для роботи та взаємодії з усім об’єктом, а не окремою дією. Ця концепція дозволяє програмісту заповнювати та маніпулювати деталями на рівні об’єктів.

На малюнку нижче зображено приклад типу об’єкта, у якому банківський рахунок вважається об’єктною сутністю. Атрибути об’єктів включають речі, які містять певні значення атрибутів, наприклад, у банківському рахунку; це номер рахунку, банківський баланс тощо, тоді як об’єктні методи описують такі речі, як розрахунок процентної ставки, створення банківської виписки тощо, що вимагає виконання певного процесу.

Типи об’єктів у PL/SQL

У PL/SQL об’єктно-орієнтоване програмування базується на типах об’єктів.

Тип об’єкта може представляти будь-яку сутність реального світу. У цьому розділі ми збираємося обговорити інші типи об’єктів.

Компоненти типів об'єктів

PL / SQL Тип об'єкта містить в основному два компоненти.

  1. Attributes
  2. Члени/Методи

Attributes

Атрибути – це стовпець або поле, у якому зберігаються дані. Кожен атрибут буде зіставлено з типом даних, який визначає тип обробки та зберігання для цього атрибута. Атрибут може бути будь-яким дійсним Тип даних PL/SQL, або це може бути об’єкт іншого типу.

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

Члени або методи — це підпрограми, визначені в типі об’єкта. Вони не використовуються для зберігання будь-яких даних. Вони в основному використовуються для визначення процесу всередині типу об'єкта. Для прикладів перевірки даних перед заповненням типу об’єкта. Вони оголошені в розділі типу об’єкта та визначені в розділі тіла типу об’єкта типу об’єкта. Розділ тіла в типі об’єкта є необов’язковою частиною. Якщо членів немає, тип об’єкта не міститиме частини тіла.

Створити об'єкт у Oracle

Тип об’єкта не можна створити на рівні підпрограми, їх можна створити лише на рівні схеми. Коли тип об’єкта визначено в схемі, його можна використовувати в підпрограмах. Тип об’єкта можна створити за допомогою «CREATE TYPE». Тіло типу можна створити лише після створення його типу об’єкта.

Створити об'єкт у OracleСтворити об'єкт у Oracle

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;‭
.
.	‬
);
/

Пояснення синтаксису:

  • Наведений вище синтаксис показує створення «OBJECT» з атрибутами та «OBJECT-BODY» з методами.
  • Методи також можуть бути перевантажені в тілі об’єкта.

Ініціалізація оголошення типу об’єкта

Як і інші компоненти PL/SQL, типи об’єктів також необхідно оголосити перед використанням у програмі.

Після створення типу об’єкта його можна використовувати в розділі декларації підпрограми для оголошення змінної цього типу об’єкта.

Кожного разу, коли будь-яка змінна оголошується в підпрограмі як тип об’єкта, під час виконання буде створено новий екземпляр типу об’єкта, і цей щойно створений екземпляр можна посилатися на ім’я змінної. Таким чином, один тип об’єкта може зберігати кілька значень у різних екземплярах.

Ініціалізація оголошення типу об’єкта

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

Пояснення синтаксису:

  • Наведений вище синтаксис показує оголошення змінної як типу об’єкта в розділі декларації.

Як тільки змінну оголошено як тип об’єкта в підпрограмі, вона буде атомарно нульовою, тобто весь об’єкт сам по собі буде нульовим. Його потрібно ініціалізувати значеннями, щоб використовувати їх у програмі. Їх можна ініціалізувати за допомогою конструкторів.

Конструктори — це неявний метод об’єкта, на який можна посилатися з тим самим іменем, що й тип об’єкта. Наведений нижче синтаксис показує ініціалізацію типу об’єкта.

Ініціалізація оголошення типу об’єкта

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

Пояснення синтаксису:

  • Наведений вище синтаксис показує ініціалізацію екземпляра типу об’єкта нульовим значенням.
  • Тепер сам об’єкт не є нульовим, оскільки він був ініціалізований, але атрибути всередині об’єкта будуть нульовими, оскільки ми не призначили жодних значень цим атрибутам.

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

Конструктори — це неявний метод об’єкта, на який можна посилатися з тим самим іменем, що й тип об’єкта. Кожного разу, коли об’єкт посилається вперше, цей конструктор буде викликатися неявно.

Ми також можемо ініціалізувати об’єкти за допомогою цього конструктора. Конструктор може бути визначений явно шляхом визначення члена в тілі типу об’єкта з таким же ім’ям типу об’єкта.

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

Ми збираємося виконати це за наведеними нижче кроками.

  • Step1:
  • Створення типу об'єкта
  • Тіло типу об'єкта
  • Крок 2: Створення анонімного блоку для виклику створеного типу об’єкта через неявний конструктор для emp_no 1005.
  • Крок 3: Створення анонімного блоку для виклику створеного типу об’єкта через явний конструктор для emp_no 1006.

Крок 1) Створення типу об’єкта та тіла типу об’єкта

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

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);
/

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

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.managerial:=1001;
RETURN;
END:
MEMBER PROCEDURE insert_records
IS
BEGIN
INSERT INTO emp VALUES(emp_noemp_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:
/

Пояснення коду

  • Рядок коду 1-9: Створення типу об’єкта «emp_object» із 4 атрибутами та 3 членами. Він містить визначення конструкторів лише з 3 параметрами. (Фактичний неявний конструктор міститиме кількість параметрів, рівну кількості атрибутів, присутніх у типі об’єкта)
  • Рядок коду 10: Створення тіла типу.
  • Рядок коду 11-21: Визначення явного конструктора. Призначення значення параметра атрибутам і призначення значення атрибуту «manager» зі значенням за замовчуванням «1001».
  • Рядок коду 22-26: визначення елемента «insert_records», у якому значення атрибутів вставляються в таблицю «emp».
  • Рядок коду 27-34: визначення члена 'display_records', у якому відображаються значення атрибутів типу об'єкта.

Вихід

Тип створений

Тіло типу створено

Крок 2) Створення анонімного блоку для виклику створеного типу об’єкта через неявний конструктор для 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;

Пояснення коду

  • Рядок коду 37-45: вставлення записів за допомогою неявного конструктора. Виклик конструктора містить фактичну кількість значень атрибутів.
  • Рядок коду 38: Оголошує guru_emp_det як тип об’єкта «emp_object».
  • Рядок коду 41: оператор 'guru_emp_det.display_records' викликає функцію-член 'diplay_records' і відображає значення атрибутів
  • Рядок коду 42: оператор 'guru_emp_det.insert_records' викликає функцію-член 'insert_records', а значення атрибутів вставляються в таблицю.

Вихід

Ім'я працівника: RRR

Кількість працівників: 1005

Зарплата: 20000

Менеджер: 1000

Крок 3) Створення анонімного блоку для виклику створеного типу об’єкта через явний конструктор для 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

Пояснення коду:

  • Рядок коду 46-53: вставлення записів за допомогою явного конструктора.
  • Рядок коду 46: Оголошує guru_emp_det як тип об’єкта «emp_object».
  • Рядок коду 50: оператор 'guru_emp_det.display_records' викликає функцію-член 'display_records' і відображає значення атрибутів
  • Рядок коду 51: оператор 'guru_emp_det.insert_records' викликає функцію-член 'insert_records', а значення атрибутів вставляються в таблицю.

Успадкування типу об’єкта

Властивість успадкування дозволяє типу підоб’єкта отримувати доступ до всіх атрибутів і членів типу супероб’єкта або типу батьківського об’єкта.

Тип підоб’єкта називається типом успадкованого об’єкта, а тип надоб’єкта – типом батьківського об’єкта. Наведений нижче синтаксис показує, як створити батьківський і успадкований тип об’єкта.

Успадкування типу об’єкта

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

Пояснення синтаксису:

  • Наведений вище синтаксис показує створення типу SUPER.

Успадкування типу об’єкта

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

Пояснення синтаксису:

  • Наведений вище синтаксис показує створення типу SUB. Він містить усі члени та атрибути з типу батьківського об’єкта.

Example1: У наведеному нижче прикладі ми збираємося використати властивість успадкування, щоб вставити запис із ідентифікатором менеджера «1002» для наступного запису («RRR», 1007, 20000).

Ми збираємося виконати наведену вище програму наступними кроками

  • Крок 1: Створіть тип SUPER.
  • Крок 2: Створіть тип і тіло SUB.
  • Крок 3: Створення анонімного блоку для виклику типу SUB.

Крок 1) Створіть тип SUPER або тип Parent.

Успадкування типу об’єкта

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;
/

Пояснення коду:

  • Рядок коду 1-9: Створення типу об’єкта «emp_object» із 4 атрибутами та 3 членами. Він містить визначення конструкторів лише з 3 параметрами. Він був оголошений як "НЕОСТАТОЧНИЙ", тому він є батьківським типом.

Крок 2) Створіть тип SUB під типом SUPER.

Успадкування типу об’єкта

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;
/

Пояснення коду:

  • Рядок коду 10-13: Створення sub_emp_object як успадкованого типу з додатковим одним атрибутом 'default_manager' і оголошенням процедури-члена.
  • Рядок коду 14: Створення тіла для успадкованого типу об’єкта.
  • Рядок коду 16-21: визначення процедури-учасника, яка вставляє записи в таблицю «emp» зі значеннями з типу об’єкта «SUPER», за винятком значення менеджера. Для значення менеджера використовується «default_manager» із типу «SUB».

Крок 3) Створення анонімного блоку для виклику типу SUB

Успадкування типу об’єкта

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;
/

Пояснення коду:

  • Рядок коду 25: оголошення 'guru_emp_det' як типу 'sub_emp_object'.
  • Рядок коду 27: Ініціалізація об’єкта за допомогою неявного конструктора. Конструктор має 5 параметрів (4 атрибути з типу PARENT і 2 атрибути з типу SUB). Останній параметр (1002) визначає значення атрибута default_manager
  • Рядок коду 28: виклик члена 'insert_default_mgr' для вставлення записів із ідентифікатором менеджера за замовчуванням, переданим у конструкторі.

Рівність об'єктів PL/SQL

Екземпляр об’єкта, який належить до тих самих об’єктів, можна порівняти на рівність. Для цього нам потрібен спеціальний метод у типі об’єкта під назвою «ORDER».

Цей метод ORDER має бути функцією, яка повертає числовий тип. Він приймає два параметри як вхідні дані (перший параметр: ідентифікатор екземпляра власного об’єкта, другий параметр: ідентифікатор іншого екземпляра об’єкта).

Ідентифікатор двох примірників об’єкта порівнюється, і результат повертається в числовому вигляді.

  • Позитивне значення означає, що екземпляр об’єкта SELF більший за інший екземпляр.
  • Від’ємне значення означає, що екземпляр об’єкта SELF є меншим за інший екземпляр.
  • Нуль означає, що екземпляр об’єкта SELF дорівнює іншому екземпляру.
  • Якщо будь-який з екземплярів має значення null, ця функція поверне значення null.

Рівність об'єктів PL/SQL

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 є екземпляром object_type_name.

Приклад1: у наступному прикладі ми побачимо, як порівняти два об’єкти. Ми збираємося створити два екземпляри та порівнювати атрибут 'salary' між ними. Ми зробимо два кроки.

  • Крок 1: Створення типу та тіла об’єкта.
  • Крок 2: Створення анонімного блоку для виклику порівняння екземпляра об’єкта.

Крок 1) Створення типу та тіла об’єкта.

Рівність об'єктів PL/SQL

Рівність об'єктів PL/SQL

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;
/

Пояснення коду:

  • Рядок коду 1-4: Створення типу об’єкта «emp_object_equality» з 1 атрибутом і 1 членом.
  • Рядок коду 6-16: визначення функції ORDER, яка порівнює атрибут 'salary' екземпляра SELF і тип екземпляра параметра. Він повертає негативне значення, якщо зарплата SELF менша, або додатне значення, якщо зарплата SELF більша, і 0, якщо зарплати рівні.

Вихід коду:

Тип створений

Крок 2) Створення анонімного блоку для виклику порівняння екземпляра об’єкта.

Рівність об'єктів PL/SQL

DECLARE
l_obj_l emp_object_equality;
l_obj_2 emp_object_equality;
BEGIN
l_obj_l:=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_l.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

Пояснення коду:

  • Рядок коду 20: Оголошення l_obj_1 типу emp_object_equality.
  • Рядок коду 21: Оголошення l_obj_2 типу emp_object_equality.
  • Рядок коду 23: Ініціалізація l_obj_1 зі значенням зарплати «15000»
  • Рядок коду 24: Ініціалізація l_obj_1 зі значенням зарплати «17000»
  • Рядок коду 25-33: надрукувати повідомлення на основі номера повернення з функції ORDER.

Підсумки

У цьому розділі ми розглянули тип об’єкта та його властивості. Ми також обговорювали конструктори, члени, атрибути, успадкування та рівність в об’єктах PL/SQL.