Oracle PL/SQL типове обекти: CREATE TYPE с примери
⚡ Умно обобщение
Обектните типове в PL/SQL предлагат обектно-ориентираното програмиране Oracle, което ви позволява да моделирате реални обекти с атрибути и методи. Те поддържат конструктори, наследяване и сравнение на равенство, така че един тип на ниво схема може да съхранява и обработва структурирани данни.

Какво е тип обект в PL/SQL?
Обектно-ориентираното програмиране е особено подходящо за изграждане на компоненти за многократна употреба и сложни приложения. Програмите са организирани около „обекти“, а не около „действия“; тоест, те са проектирани да работят и да взаимодействат с цял обект, а не с едно-единствено действие. Този подход позволява на програмиста да попълва и манипулира детайли на ниво обект-ентитет.
Картината по-долу показва пример за тип обект, в който банкова сметка се третира като обектна единица. Атрибутите на обекта съдържат стойности – за банкова сметка това са номерът на сметката, банковото салдо и т.н. – докато методите на обекта описват действия като изчисляване на лихвения процент или генериране на банково извлечение, всяко от които изисква завършване на определен процес.
In PL / SQL, обектно-ориентираното програмиране се основава на обектни типове. Обектният тип може да представлява всеки реален обект. Разделите по-долу разглеждат обектните типове, техните компоненти и как да ги създавате и използвате.
Компоненти на типовете обекти
PL/SQL обектният тип съдържа основно два компонента.
- Атрибути
- Членове/Методи
Атрибути
Атрибутите са колоните или полетата, в които се съхраняват данните. Всеки атрибут е съпоставен с типа данни, който определя типа на обработка и съхранение за този атрибут. Атрибутът може да бъде от всякакъв валиден тип. PL/SQL тип данни, или може да бъде от друг тип обект.
Членове/Методи
Членовете или методите са подпрограми дефинирани вътре в обектния тип. Те не се използват за съхраняване на данни; вместо това, те дефинират обработката, извършвана вътре в обектния тип - например, валидиране на данни преди попълване на обекта. Те се декларират в спецификацията на обектния тип и се дефинират в тялото на обектния тип. Тялото е незадължително: ако няма членове, обектният тип няма част от тялото.
Създаване на обект в Oracle
Обектен тип не може да бъде създаден на ниво подпрограма; той може да бъде създаден само на ниво схема. След като обектният тип е дефиниран в схемата, той може да се използва в подпрограми. Обектният тип се създава с помощта на оператора „CREATE TYPE“, а тялото на типа може да бъде създадено само след като неговият обектен тип съществува.
Снимките на екрана по-долу показват синтаксиса на CREATE TYPE за спецификацията на обекта и синтаксиса на CREATE TYPE BODY, който дефинира неговите методи.
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 блок.
DECLARE <variable_name> <object_type_name>; BEGIN . . END; /
Обяснение на синтаксиса:
- Синтаксисът по-горе показва декларацията на a променлив като обектен тип в декларативната секция.
След като променливата бъде декларирана като обектен тип в подпрограма, тя е атомарно null - целият обект е null. Тя трябва да бъде инициализирана със стойности, преди да може да бъде използвана в програмата. Обектите се инициализират с помощта на конструктори.
Конструкторите са имплицитният метод на обект, към който може да се обърнем със същото име като типа на обекта. Снимката на екрана по-долу показва инициализацията на екземпляр на тип обект.
DECLARE <variable_name> <object_type_name>; BEGIN <variable_name>:=<object_type_name>(); END; /
Обяснение на синтаксиса:
- Синтаксисът по-горе показва инициализацията на екземпляра на обектния тип с null стойност.
- Самият обект вече не е null, след като бъде инициализиран, но атрибутите вътре в обекта остават null, докато не им бъдат присвоени стойности.
конструкторите
Конструкторите са имплицитният метод на обект, към който може да се обърнем със същото име като типа на обекта. Всеки път, когато обектът се обърне за първи път, този конструктор се извиква имплицитно.
Можете също да инициализирате обекти, използвайки тези конструктори. Конструктор може да бъде дефиниран изрично чрез дефиниране на член в тялото на обектния тип със същото име като обектния тип.
Пример 1: В следващия пример използваме члена от тип обект, за да вмъкнем записи в emp таблицата със стойностите ('RRR', 1005, 20000, 1000) и ('PPP', 1006, 20000, 1001). След като данните бъдат вмъкнати, ги показваме, използвайки члена от тип обект. Също така използваме експлицитен конструктор, за да попълним идентификатора на мениджъра със стойността по подразбиране 1001 за втория запис.
Изпълняваме го в следните стъпки.
- Стъпка 1: Създайте типа обект и тялото на типа обект.
- Стъпка 2: Създайте анонимен блок, който да извиква типа обект чрез имплицитния конструктор за emp_no 1005.
- Стъпка 3: Създайте анонимен блок, който да извиква типа обект чрез явния конструктор за emp_no 1006.
Стъпка 1) Създайте тип обект и тяло на тип обект.
Екранната снимка по-долу показва как се създава спецификацията на обектния тип 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, което се създава с помощта на явния конструктор и процедурите-членове.
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 чрез имплицитния конструктор.
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“ и стойностите на атрибутите се вмъкват в таблицата. След това блокът записва данните в таблицата. транзакция.
Изход:
Име на служител: RRR
Номер на служител: 1005
Заплата: 20000 XNUMX
Мениджър: 1000
Стъпка 3) Създаване на анонимен блок за извикване на създадения тип обект чрез явния конструктор за emp_no 1006.
Екранната снимка по-долу показва анонимния блок, който извиква emp_object чрез явния конструктор с три аргумента.
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.
Наследяване в тип обект
Свойството наследяване позволява на подобектен тип достъп до всички атрибути и членове на суперобектния тип или родителския обектен тип.
Типът подобект се нарича наследен тип обект, а типът супер обект се нарича тип родителски обект. Синтаксисът по-долу показва как да се създадат родителски и наследени типове обекти. Екранната снимка по-долу показва синтаксиса на родителския (SUPER) тип, маркиран като NOT FINAL.
CREATE TYPE <object_type_name_parent> AS OBJECT ( <attribute_l><datatype>, . . )NOT FINAL; /
Обяснение на синтаксиса:
- Синтаксисът по-горе показва създаването на типа SUPER. Клаузата NOT FINAL позволява наследяването на типа.
Екранната снимка по-долу показва наследения синтаксис на типа (SUB), създаден с ключовата дума UNDER.
CREATE TYPE<object_type_name_sub>UNDER<object_type_name_parent> ( <attribute_l><datatype>, . ); /
Обяснение на синтаксиса:
- Синтаксисът по-горе показва създаването на типа SUB. Той съдържа всички членове и атрибути от родителския тип обект.
Пример 1: В примера по-долу използваме свойството наследяване, за да вмъкнем запис с идентификатор на мениджър „1002“ за записа („RRR“, 1007, 20000). Изпълняваме програмата в следните стъпки.
- Стъпка 1: Създайте типа SUPER.
- Стъпка 2: Създайте типа и тялото SUB.
- Стъпка 3: Създайте анонимен блок, който да извиква типа SUB.
Стъпка 1) Създайте SUPER тип или Parent тип.
Екранната снимка по-долу показва как супертипът 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 под тип SUPER.
Екранната снимка по-долу показва наследения тип sub_emp_object и неговото тяло, което се създава.
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 и вмъква идентификатора на мениджъра по подразбиране.
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, която трябва да бъде включена в тялото на типа за проверката за равенство.
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, която сравнява атрибута заплата.
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, която сравнява атрибута „заплата“ на инстанцията SELF и инстанцията на параметъра. Тя връща отрицателна стойност, ако заплатата на SELF е по-малка, положителна стойност, ако заплатата на SELF е по-голяма, и 0, ако заплатите са равни.
Code Изход:
Типът е създаден
Стъпка 2) Създаване на анонимния блок за сравняване на екземплярите на обектите.
Снимката на екрана по-долу показва анонимния блок, който сравнява два екземпляра на 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.


















