Отправляет email-рассылки с помощью сервиса Sendsay

Килограмм килобайтов

  Все выпуски  

Килограмм килобайтов


"Килограмм килобайтов"


Выпуск №30 Дата выхода:2008-02-09
Сайт рассылки: Рациональное программирование

Документация
 
Программирование
PHP
Oracle
Операционные системы
FreeBSD
Linux
QNX

Здравствуйте, уважаемые подписчики

Я начинаю серию из трех выпусков об объектно-ориентированном программировании в Oracle PL/SQL. Это мой перевод одной из глав официальной документации Oracle. Перевод я полностью закончил и запустил следующие два выпуска в автоматическом режиме, до 17 февраля Вы их получите.
Надеюсь получить отзывы тех, кто на практике использовал эту интересную возможность СУБД Oracle.
Я намереваюсь переделать структуру таблиц проекта HomeFin, чтобы использовать в нем объектную технологию.

Статья написана на основе официальной документации фирмы Oracle.
Oracle® Database PL/SQL User's Guide and Reference
10g Release 2 (10.2)
Part Number B14261-01

v:1.0 2008.02.09

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

Объявление и инициализация объектов в PL/SQL

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

В настоящий момент Вы не можете описать типы в PL/SQL блоке, подпрограмме или пакедже. Типы можно описать интерактивно в SQL*Plus, используя SQL выражение CREATE TYPE.

Информацию о выражениях CREATE TYPE и CREATE TYPE BODY можно найти в "Oracle Database SQL Reference".

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

В следующем примере демонстрируется создание объектного типа, тела объекта и таблицы объектных типов


Пример 12-1 Работа с объектными типами.
CREATE TYPE address_typ AS OBJECT
( 
  street          VARCHAR2(30),
  city            VARCHAR2(20),
  state           CHAR(2),
  postal_code     VARCHAR2(6) 
);
/
CREATE TYPE employee_typ AS OBJECT 
(
  employee_id       NUMBER(6),
  first_name        VARCHAR2(20),
  last_name         VARCHAR2(25),
  email             VARCHAR2(25),
  phone_number      VARCHAR2(20),
  hire_date         DATE,
  job_id            VARCHAR2(10),
  salary            NUMBER(8,2),
  commission_pct    NUMBER(2,2),
  manager_id        NUMBER(6),
  department_id     NUMBER(4),
  address           address_typ,
  MAP MEMBER FUNCTION get_idno RETURN NUMBER,
  MEMBER PROCEDURE display_address (SELF IN OUT NOCOPY employee_typ) 
);
/
CREATE TYPE BODY employee_typ AS
  MAP MEMBER FUNCTION get_idno RETURN NUMBER IS
  BEGIN
    RETURN employee_id;
  END;
  MEMBER PROCEDURE display_address (SELF IN OUT NOCOPY employee_typ) IS
  BEGIN
    DBMS_OUTPUT.PUT_LINE(first_name || ' '|| last_name);
    DBMS_OUTPUT.PUT_LINE(address.street);
    DBMS_OUTPUT.PUT_LINE(address.city || ', '|| address.state || ' '||address.postal_code);
  END;
END;
/
CREATE TABLE employee_tab OF employee_typ;

Объявление объектов в PL/SQL блоке

Вы можете использовать объектные типы точно так же как и встроенные типы такие как CHAR или NUMBER. В примере 12-2, объявляется объект emp типа employee_typ. Для инициализации объекта вызывается конструктор типа employee_typ.


Пример 12-2 Объявление объектного типа в PL/SQL блоке
DECLARE
  emp employee_typ; -- emp по умолчанию NULL
BEGIN
-- вызов конструктора типа employee_typ
  emp := employee_typ(315, 'Francis', 'Logan', 'FLOGAN',
        '555.777.2222', '01-MAY-04', 'SA_MAN', 11000, .15, 101, 110, 
         address_typ('376 Mission', 'San Francisco', 'CA', '94222'));
  DBMS_OUTPUT.PUT_LINE(emp.first_name || ' ' || emp.last_name); -- display details
  emp.display_address();  -- вызывается метод объекта для вывода данных объекта
END;
/

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

  PROCEDURE open_acct (new_acct IN OUT employee_typ) IS ...

В следующем примере объектный тип employee_typ является типом данных возвращаемого функцией значения:

  FUNCTION get_acct (acct_id IN NUMBER) RETURN employee_typ IS ...

Как обращаться с неинициализированными объектами в PL/SQL

Пока вы ни инициализируете объект, вызвав конструктор соответствующего типа, объект будет null. Объект сам равен Null, но не его атрибуты.

Неинициализированный объект никогда не равен другому объекту. Фактически, сравнение NULL с любым другим объектом всегда вернет NULL. Если вы присваиваете объект NULL другому объекту, то тот объект становится неинициализированным. Выражения и атрибуты неинициализированного объекта равны NULL. Если к неинициализированному объекту или его атрибутам применить выражение сравнения IS NULL, то результат будет TRUE.


Пример 12-3, иллюстрация объектов null и объектов с аргументами null.
DECLARE
  emp employee_typ; -- emp по умолчанию null
BEGIN
  IF emp IS NULL THEN 
    DBMS_OUTPUT.PUT_LINE('emp is NULL #1'); 
  END IF;
  IF emp.employee_id IS NULL THEN 
     DBMS_OUTPUT.PUT_LINE('emp.employee_id is NULL #1');
  END IF;
  emp.employee_id := 330;
  IF emp IS NULL THEN 
    DBMS_OUTPUT.PUT_LINE('emp is NULL #2'); 
  END IF;
  IF emp.employee_id IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('emp.employee_id is NULL #2');
  END IF;
  emp := employee_typ(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
                      address_typ(NULL, NULL, NULL, NULL));
  -- emp := NULL; -- это бы сделало следующее выражение равным TRUE
  IF emp IS NULL THEN 
    DBMS_OUTPUT.PUT_LINE('emp is NULL #3'); 
  END IF;
  IF emp.employee_id IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('emp.employee_id is NULL #3');
  END IF;
EXCEPTION
   WHEN ACCESS_INTO_NULL THEN
     DBMS_OUTPUT.PUT_LINE('Cannot assign value to NULL object');
END;
/

Вывод сообщений:
emp is NULL #1
emp.employee_id is NULL #1
emp is NULL #2
emp.employee_id is NULL #3

Вызов методов неинициализированного объекта вызывает предопределенное исключение NULL_SELF_DISPATCH. Если атрибуты неинициализированного объекта передаются как параметры in, то они считаются равными null. Если такие атрибуты передаются как параметры OUT или IN OUT, то генерируется исключение при попытке присвоить им значение.

Продолжение следует...


* * *

Ведущий рассылки: Петрелевич Сергей

У Вас есть вопрос? Спрашивайте
Напишите, что Вы хотите видеть в рассылке. Мне важно знать Ваше мнение.


В избранное