Шаг 50 - PL/SQL - переменные их типы и кое что еще!

Вот, наконец, мы достаточно много, как мне кажется, успели изучить, а я добрался таки до 50-го Шага! Юбилей! Ну да ладно. Давайте разберемся вот с чем. Наверное, как вы уже знаете основная единица, хранения информации в БД это таблица. При работе с таблицами в PL/SQL, обычно создается множество переменных, разных типов. В них вы храните какие-либо данные, как правило, из полей таблиц. Например, учебная таблица OFFICES, определенная с помощью оператора CREATE TABLE выглядит следующим образом:

CREATE TABLE OFFICES
(
	OFFICE INTEGER PRIMARY KEY,
	CITY VARCHAR2(30) NOT NULL,
	REGION VARCHAR2(30) NOT NULL,
	MGR INTEGER,
	TARGET NUMBER,
	SALES NUMBER NOT NULL
)
/

Допустим, вы будете хранить содержимое поля REGION, в переменной REGION_MY и поле MGR в переменной MGR_MY. Соответственно вы объявите эти переменные примерно следующим образом:

DECLARE	 

	REGION_MY VARCHAR2(30);
	MGR_MY INTEGER;
	.
	.
	.

Но допустим, в какой-то момент, вам нужно переопределить поля таблицы OFFICES, MGR и REGION таким образом:

		
.
.
REGION VARCHAR2(128) NOT NULL,
MGR NUMBER(10,5),
.
.

Следовательно, вы уже не сможете в дальнейшем хранить в этих переменных значения переопределенных полей таблицы OFFICES, так как их типы не совпадают и PL/SQL выдаст сообщение об ошибке! А, если таких переменных объявлено достаточно много, то разобраться и изменить все типы будет достаточно сложно и, как правило, вы наделаете кучу ошибок! Для того, чтобы избежать таких неприятностей в дальнейшем необходимо использовать конструкцию %TYPE, следующим образом:

-------- VARIABLE TABLE.FIELD%TYPE --------------

Или, если более понятно, то вышеуказанные переменные нужно объявить вот так:

DECLARE	 

	REGION_MY OFFICES.REGION%TYPE;
	MGR_MY OFFICES.MGR%TYPE;

	BEGIN
	.
	.
	.

Конструкция получается более громоздкая но, за то точно и надежно! Теперь, если тип поля изменится, то изменится и тип всех переменных связанных с данным полем! Можно привести еще несколько примеров применения конструкции %TYPE:

DECLARE
	
	v_MYCITY OFFICES.CITY%TYPE;
	v_MYSALES OFFICES.SALES%TYPE;
	v_TEMPOLD NUMBER(7,4) NOT NULL;
	v_DOPTEMP v_TEMPOLD%TYPE;

Замечу так же, что для переменной v_TEMPOLD есть ограничение NOT NULL, а вот для переменной v_DOPTEMP это ограничение не переносится, так как применяется конструкция %TYPE, от типа другой переменной! Применение конструкции %TYPE, является хорошим стилем программирования, так как делает код более понятным и проще адаптируемым. Вот собственно, что касается, конструкции %TYPE. В PL/SQL имеется так же возможность объявлять так называемы подтипы (subtype). То есть типы на основе других, стандартных типов. Такое извращение, как правило применяется для того, чтобы получить более понятное описание типа. Ряд типов в PL/SQL, такие например как INTEGER, DECIMAL - являются подтипом, типа NUMBER! Делается это таким образом:

---- SUBTYPE --- новый тип -- IS -- исходный тип -----------------------

В части исходный тип, можно применить любой стандартный тип или конструкцию %TYPE. Например:

 
DECLARE
 	 
	SUBTYPE t_LoopCn IS NUMBER;	-- Определяем новый тип
	v_LpCounter t_LoopCn;	-- Объявляем переменную с эти подтипом

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

DECLARE
 	 
	SUBTYPE t_LoopCn IS NUMBER(4);	-- Error !!!
	v_LpCounter t_LoopCn;		-- Объявляем переменную с эти подтипом

Но данное ограничение можно обойти, применив фиктивную переменную нужного типа (с ограничением) и в определении SUBTYPE воспользоваться конструкцией %TYPE:

DECLARE

	v_NullVar NUMBER(7,3);
	   	 
	SUBTYPE t_LoopCn IS v_NullVar%TYPE;	-- Определяем новый тип
	v_LpCounter t_LoopCn;		-- Объявляем переменную с эти подтипом

При объявлении переменной с неограниченным подтипом ее тип может быть ограничен, вот так:

DECLARE

	SUBTYPE t_NumVar IS NUMBER	-- Определяем неограниченный подтип,
	v_Temp t_NumVar(5);	-- но ограничиваем переменную с этим подтипом!

При этом не забывайте, что подтип принадлежит к тому же семейству типов, что и базовый тип! Это важно! Вот такие тонкости в работе с типами данных, есть в PL/SQL! :) Закрепляйте знания и можете переписать пару блоков, из прошлого шага в свете работы с типами и подтипами данных! :) Удачи!


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Летучий Сергей - 21.10.2003