Выбрать главу

DROP VIEW viewname;

Примеры представлений

Вот пример простого представления:

CREATE VIEW MyView AS

SELECT NAME, PRICE_1

FROM Table_example;

В этом примере мы создаем представление на основе запроса к таблице Table_example, которую мы рассматривали в главе "Таблицы. Первичные ключи и генераторы". В данном случае представление будет состоять из двух полей - NAME и PRICE_1, которые будут выбираться из таблицы Table_example без всяких условий, т. е. число записей в представлении MyView будет равно числу записей в Table_example.

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

Чтобы подробнее рассмотреть использование этого применения представлений, давайте создадим две таблицы, связанные отношением один-ко-многим (часто такое отношение называют мастер-деталью или master-detail). Вот DDL-скрипт для создания этих таблиц:

/* Table: WISEMEN */

CREATE TABLE WISEMEN (

ID_WISEMAN INTEGER NOT NULL,

WISEMAN_NAME VARCHAR(80));

/* Primary keys definition */

ALTER TABLE WISEMEN ADD CONSTRAINT PK_WISEMEN PRIMARY KEY

(ID_WISEMAN);

/* Table: WISEBOOK */

CREATE TABLE WISEBOOK (

ID_BOOK INTEGER NOT NULL,

ID_WISEMAN INTEGER,

BOOK VARCHAR (80) ) ;

/* Primary keys definition */

ALTER TABLE WISEBOOK ADD CONSTRAINT PK_WISEBOOK PRIMARY KEY

(ID_BOOK);

/* Foreign keys definition */

ALTER TABLE WISEBOOK ADD CONSTRAINT FK_WISEBOOK FOREIGN KEY

(ID_WISEMAN) REFERENCES WISEMEN (ID_WISEMAN);

Итак, мы создали две таблицы - WISEMEN и WISEBOOK, которые связали между собой отношением master-detail с помощью ограничения внешнего ключа - FOREIGN KEY. Предположим, что эти таблицы будут хранить информацию о великих китайских мудрецах и их произведениях. Теперь мы можем создать несколько представлений на основе этих таблиц. Например, создадим представление, которое показывает, сколько произведений есть у каждого мудреца:

CREATE VIEW WiseBookCount (WISEMAN,

HOW_WISEBOOKS) AS SELECT M.WISEMAN_NAME, COUNT(B.BOOK)

FROM WISEMEN M, WISEBOOK В

WHERE (M.ID_WISEMAN = В.ID_WISEMAN)

GROUP BY M.WISEMAN_NAME

Обратите внимание, что при использовании любых вычисляемых выражений вроде агрегатных функций COUNTQ, SUMQ, МАХ() и т. д., необходимо использовать явное именование полей представления, т. е. давать имена всем полям, возвращаемым запросом. Как видно из этого примера, эти имена не обязательно должны совпадать с именами полей запроса, но их количество должно совпадать с количеством полей, возвращаемых запросом. Установление того, какое поле, возвращаемое запросом, соответствует какому полю представления, осуществляется по порядковому номеру — первое поле запроса отобразится в первое поле представления, второе - во второе и т. д.

А если мы захотим узнать, какой же из мудрецов написал больше всего книг? И попытаемся добавить в запрос, лежащий в основе представления, выражение для сортировки - ORDER BY. Однако эта попытка будет неудачной: использование сортировки ORDER BY в представлениях не допускается и при попытке создать представление с запросом, содержащим ORDER BY, возникнет ошибка. Если мы желаем отсортировать результаты, возвращаемые представлением, то придется это сделать на стороне клиента:

SELECT * FROM WiseBookCount ORDER BY HOW_WISEBOOKS

Выполнение этого SQL-запроса приведет к желаемому результату.

Помимо ограничения на использование выражения ORDER BY в представлениях, шк/ке нсмьзя использовать в качес!ве источника данных набор данных, получаемых в результате выполнения хранимых процедур (см. чуть ниже главу "Хранимые процедуры").

Пожалуй, стоит привести еще один пример, иллюстрирующий применение представлений. Предположим, нам необходимо вывести список мудрецов, чье имя начинается с буквы "К". В этом случае нам поможет представление с условиями:

CREATE VIEW WiseMen2

(WISEMAN) AS

SELECT M.WISEMAN_NAME

FROM WISEMEN M

WHERE M.WISEMAN_NAME LIKE 'K%'

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

Модифицируемые представления

Выше мы упомянули о том, чт. е. возможность создавать изменяемые представления данных. Это действительно так - существует возможность не только читать данные из представления, но и изменять их!

Есть два способа сделать представление модифицируемым. Первый способ применим, когда представление создается на основе единственной 1аблицы (или другого модифицируемого представления), причем все столбцы данной таблицы должны позволять наличие NULL. При этом запрос, на котором основано представление, не может содержать подзапросов, агрегатных функций. UDF, хранимых процедур, предложений DISTINCT и HAVING. Если выполняются все эти условия, то представление автоматически становится модифицируемым, т. е. для него можно выполнять запросы DELETE, INSERT и UPDATE, которые будут изменять данные в таблице-источнике.

Список условий довольно внушительный и сильно ограничивает применение таких модифицируемых представлений, поэтому они ИСПОЛЬЗУЮТСЯ относительно редко.

Чтобы сделать модифицируемым представление, которое нарушает любое из вышеперечисленных условий, применяется механизм триггеров. Подробнее о том. что такое триггер, рассказывается в главе "Триггеры" (ч 1). а сейчас мы лишь рассмотрим общие принципы организации изменения данных во VIEW.

Для реализации обновляемого представления с помощью триггеров необходимо сделать следующее.

Создать 3 триггера для данного представления на события: BEFORE DELETE, BEFORE UPDATE и BEFORE INSERT. В этих триггерах описать, что должно происходить с данными при удалении, изменении и вставке.

Затем следует использовать данное представление в запросах на модификацию - DELETE, INSERT или UPDATE. Когда InterBase примет этот запрос, то проверит, существуют ли для данного представления соответствующие триггеры, т. е. BEFORE DELETE/INSERT/UPDATE. Если триггер для выполняемого действия существует, то InterBase вызовет его для модификации реальных данных в таблицах, лежащих в основе представления (хотя это могут быть и другие данные - каких-либо ограничений на текст этих триггеров нет), а затем перечитает строку (или строки), над которой производилась модификация

Таким образом, есть возможность реализовать сложные цепочки обновлений данных в представлениях.

В описании синтаксиса создания представления упоминалась опция WITH CHECK OPTION. Если при создании модифицируемого представления будет указана эта опция, то каждая строка данных, вставляемая или изменяемая в этом представлении, будет проверена на условие "попадания" в представление. Это можно объяснить так: если новая запись, вставляемая пользователем или получившаяся в результате обновления существующей записи, не удовлетворяет условиям запроса, который является поставщиком данных для VIEW, то вставка этой записи будет отменена и возникнет ошибка.

Заключение

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