Объявление переменных и констант PL/SQL

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


Оглавление статьи[Показать]


 

Объявление переменной  PL/SQL

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

имя тип_данных [NOT NULL] [ := | DEFAULT значение_по_умолчанию];

Здесь имя — имя переменной или константы, тип_данныхтип или подтип данных PL/SQL, определяющий, какие значения могут присваиваться переменной. При желании можно включить в объявление выражение NOT NULL; если такой переменной не присвоено значение, то база данных инициирует исключение. Секция значение_по_умолчанию инициализирует переменную начальным значением; ее присутствие обязательно только при объявлении констант. Если переменная объявляется с условием NOT NULL, то при объявлении ей должно быть присвоено начальное значение.

Примеры объявления переменных разных типов:

DECLARE

   -- Простое объявление числовой переменной
   l_total_count NUMBER;

   -- Число, округляемое до двух разрядов в дробной части:
   l_dollar_amount NUMBER (10,2);

   -- Дата/время, инициализируемая текущим значением системных часов
   -- сервера базы данных. Не может принимать значение NULL
   l_right_now DATE NOT NULL DEFAULT SYSDATE;

   -- Задание значения по умолчанию с помощью оператора присваивания
   l_favorite_flavor VARCHAR2(100) := 'Вы любите кофе?';

   -- Ассоциативный массив объявляется за два этапа.
   -- Сначала тип таблицы:
   TYPE list_of_books_t IS TABLE OF book%ROWTYPE INDEX BY BINARY_INTEGER;

Конструкция DEFAULT (см. l_right_now в приведенном примере) и конструкция с оператором присваивания (l_favorite_flavor в приведенном примере) эквивалентны и взаимозаменяемы. Какой из двух вариантов использовать? Мы предпочитаем для констант использовать оператор присваивания (:=), а для инициализации переменных — ключевое слово DEFAULT. При объявлении константы задается не значение по умолчанию, а значение, которое не может быть изменено впоследствии, поэтому DEFAULT кажется неуместным.

 

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

Между объявлениями переменных и констант существует два различия: объявление константы содержит ключевое слово CONSTANT, и в нем обязательно задается ее значение, которое не может быть изменено впоследствии:

имя CONSTANT тип_данных [NOT NULL] := | DEFAULT значение_по_умолчанию;

Несколько примеров объявления констант:

DECLARE

   -- Текущий год; в течение сеанса он не будет изменяться.
   l_curr_year CONSTANT PLS_INTEGER :=
      TO_NUMBER (TO_CHAR (SYSDATE, 'YYYY'));

   -- Использование ключевого слова DEFAULT
   l_author CONSTANT VARCHAR2(100) DEFAULT 'Bill Pribyl'

   -- Объявление сложного типа данных как константы.
   -- Константы могут быть не только скалярами!
   l_steven CONSTANT person_ot :=
      person_ot ('HUMAN', 'Steven Feuerstein', 175,
      TO_DATE ('09-23-1958', 'MM-DD-YYYY') ); 

Неименованная константа представляет собой литеральное значение — например, 2 или 'Bobby McGee'. Литерал не обладает именем, но имеет тип данных, который не объявляется, а определяется непосредственно на основании значения.

 

NOT NULL

Если переменной присваивается значение по умолчанию, вы также можете указать, что переменная всегда должна оставаться определенной (отличной от NULL). Для этого в объявление включается выражение NOT NULL. Например, следующее объявление инициализирует переменную company_name и указывает, что переменная всегда должна оставаться отличной от NULL

company_name VARCHAR2(60) NOT NULL DEFAULT 'PCS R US';

При попытке выполнения следующей операции в программе будет инициировано исключение VALUE_ERROR:

company_name := NULL; 

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

company_name VARCHAR2(60) NOT NULL; -- NOT NULL требует исходного значения! 

Как объявить переменную на языке PL/SQL 

Объявления с привязкой

При объявлении переменной тип данных очень часто задается явно:

l_company_name VARCHAR2(100); 

В Oracle также существует другой метод объявления переменных, называемый объявлением с привязкой (anchored declaration). Он особенно удобен в тех случаях, когда значение переменной присваивается из другого источника данных, например из строки таблицы.

Объявляя «привязанную» переменную, вы устанавливаете ее тип данных на основании типа уже определенной структуры данных. Таковой может являться другая переменная PL/SQL, заранее определенный тип или подтип (TYPE или SUBTYPE), таблица базы данных либо конкретный столбец таблицы.

В PL/SQL существует два вида привязки.

  • Скалярная привязка. С помощью атрибута %TYPE переменная определяется на основании типа столбца таблицы или другой скалярной переменной PL/SQL.
  • Привязка к записи. Используя атрибут %ROWTYPE, можно определить переменную на основе таблицы или заранее определенного явного курсора PL/SQL.

Синтаксис объявления переменной с привязкой: 

имя_переменной тип_атрибута %TYPE [необязательное_значение_по_умолчанию];
имя_переменной имя_таблицы | имя_курсора %ROWTYPE [необязательное_значение_по_
умолчанию];

Здесь имя_переменной — это имя объявляемой переменной, тип_атрибута — либо имя ранее объявленной переменной PL/SQL, либо спецификация столбца таблицы в формате таблица.столбец.

Привязка разрешается на стадии компиляции кода и не приводит к увеличению времени выполнения. Кроме того, привязка устанавливает зависимость между программным кодом и привязываемым элементом (таблицей, курсором или пакетом, содержащим переменную). Это означает, что при изменении данного элемента привязанный к нему программный код помечается как недействительный (INVALID). При повторной компиляции привязка выполняется заново, и таким образом код согласуется с измененным элементом.

На рис. 1 показано, как тип данных определяется на основе столбца таблицы базы данных и переменной PL/SQL.

Атрибут TYPE при объявлении с привязкой

Рис. 1. Атрибут TYPE при объявлении с привязкой

Пример привязки переменной к столбцу таблицы: 

l_company_id company.company_id%TYPE;

Аналогичным образом выполняется привязка к переменной PL/SQL; обычно это делается для того, чтобы избежать избыточных объявлений одного и того же жестко закодированного типа данных. В таких случаях в пакете обычно создается переменная, на которую затем ссылаются в программах с помощью атрибута %TYPE. (Также можно создавать в пакете подтипы SUBTYPE; эта тема рассматривается далее в этой главе.) В следующем примере приведен фрагмент кода пакета, упрощающего использование Oracle Advanced Queuing (AQ): 

PACKAGE aq
IS
   /* Стандартные типы данных, используемые в Oracle AQ. */
   v_msgid RAW (16);
   SUBTYPE msgid_type IS v_msgid%TYPE;
   v_name VARCHAR2 (49);
   SUBTYPE name_type IS v_name%TYPE;
   ...
END aq;

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

DECLARE
   my_msg_id aq.msgid_type;
BEGIN

Если Oracle изменит тип данных для идентификаторов сообщений, достаточно изменить определение SUBTYPE в пакете aq, и после перекомпиляции все объявления в программах обновятся автоматически.

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

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

 

Привязка к курсорам и таблицам

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


Допустим, нам нужно выбрать одну строку из таблицы books. Вместо того чтобы с помощью атрибута %TYPE объявлять для каждого столбца таблицы отдельную переменную, можно воспользоваться атрибутом %ROWTYPE:

DECLARE
   l_book book%ROWTYPE;
BEGIN
   SELECT * INTO l_book
    FROM book
    WHERE isbn = '1-56592-335-9';
   process_book (l_book);
END;

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

DECLARE
   CURSOR book_cur IS
      SELECT author, title FROM book
      WHERE isbn = '1-56592-335-9';
   l_book book_cur%ROWTYPE;
BEGIN
   OPEN book_cur;
   FETCH book_cur INTO l_book; 
END;

Наконец, следующий пример демонстрирует неявное использование атрибута %ROWTYPE в объявлении записи book_rec цикла FOR:

BEGIN
   FOR book_rec IN (SELECT * FROM book)
   LOOP
      process_book (book_rec);
   END LOOP;
END; 

 

Преимущества объявлений с привязкой

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

  • Синхронизация со столбцами базы данных. Переменная PL/SQL часто «представляет» информацию из таблицы базы данных. Если явно объявить переменную,  а затем изменить структуру таблицы, это может привести к нарушению работы программы.
  • Нормализация локальных переменных. Допустим, переменная PL/SQL хранит вычисляемые значения, которые используются в разных местах приложения. К каким последствиям может привести повторение (жесткое кодирование) одних и тех же типов данных и ограничений во всех объявлениях?

Вас заинтересует / Intresting for you:

Встроенные методы коллекций PL...
Встроенные методы коллекций PL... 6925 просмотров sepia Tue, 29 Oct 2019, 09:54:01
Управление приложениями PL/SQL...
Управление приложениями PL/SQL... 3070 просмотров Stas Belkov Thu, 16 Jul 2020, 06:20:48
Определение строковых констант...
Определение строковых констант... 2475 просмотров Дэйзи ак-Макарова Wed, 16 May 2018, 17:31:46
Основы языка PL/SQL: использов...
Основы языка PL/SQL: использов... 3002 просмотров Ирина Светлова Tue, 06 Feb 2018, 14:04:03
Войдите чтобы комментировать

OraCool аватар
OraCool ответил в теме #9514 08 окт 2019 05:51
Используйте программные переменные во встроенных статических командах SQL в PL/SQL и переменные привязки в динамических командах SQL , чтобы не пре­пятствовать совместному использованию курсоров.