Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
Шрифт:
Не все просмотры могут быть сделаны изменяемыми путем создания для них триггеров. Например, следующий удобный маленький просмотр только для чтения читает контекстную переменную с сервера, но несмотря ни на какие триггеры, которые вы определите для него, все операции за исключением SELECT не будут выполняться:
CREATE VIEW SYSTRANS
(CURR_TRANSACTION) AS
SELECT CURRENT_TRANSACTION FROM RDB$DATABASE;
Естественно
Просмотр является естественно изменяемым, если выполняются следующие два условия:
* спецификация просмотра является подмножеством одной таблицы или другого изменяемого просмотра;
* все столбцы базовой таблицы, не включенные в определение просмотра, допускают значение NULL.
Следующий оператор создает естественно изменяемый просмотр:
CREATE VIEW EMP_MNGRS (FIRST, LAST, SALARY) AS
SELECT FIRST_NAME, LAST_NAME, SALARY
FROM EMPLOYEE
WHERE JOB_CODE = 'Mngr'
WITH CHECK OPTION;
Поскольку предложение WITH CHECK OPTION включено в эту спецификацию, приложения не смогут изменять значение столбца JOB_CODE, даже если не было нарушения ограничения внешнего ключа для этого столбца в базовой таблице.
Изменение поведения изменяемых просмотров
Альтернативное поведение естественно изменяемых просмотров может быть задано с использованием триггеров. Для конкретной фазы операции (BEFORE/AFTER) триггеры просмотра вызываются до триггеров базовой таблицы. Следовательно, можно бережно и умело использовать просмотры для замены поведения обычного триггера базовой таблицы на планируемое.
Однако также можно создать разрушение при наличии плохо спланированных триггеров просмотров. Проверяйте, проверяйте, проверяйте!
Изменить определение просмотра?
Термины изменяемый и только для чтения относятся к тому, как может осуществляться доступ к данным из базовых таблиц, а не к тому, может ли изменяться определение просмотра. Firebird не предоставляет синтаксис ALTER VIEW.
Для изменения определения просмотра вы должны удалить просмотр, а затем заново его создать.
Удаление просмотра
Оператор DROP VIEW позволяет владельцу просмотра удалять его описание из базы данных. Он не влияет на базовые таблицы, связанные с просмотром.
Синтаксис:
DROP VIEW имя-просмотра;
Операция DROP VIEW не будет выполнена, если вы не соединены как владелец просмотра, или если этот просмотр используется в другом объекте, таком как просмотр, хранимая процедура, триггер для другого просмотра, определение таблицы или ограничение CHECK.
Следующий оператор удаляет определение просмотра:
DROP VIEW SOB_DEPT;
Использование просмотров в SQL
В SQL просмотр ведет себя во многих отношениях как обычная таблица. Вы можете осуществлять выборку из него, используя или нет предложения ORDER BY, GROUP BY или WHERE.
Если просмотр является естественно изменяемым, или он был сделан изменяемым с помощью триггера и существуют соответствующие привилегии SQL, вы можете выполнять для него
позиционированные и поисковые операции изменения, добавления и удаления, которые будут оперировать с базовой таблицей. Вы можете также делать следующее:* создавать просмотры просмотров;
* выполнять выбор из просмотра в модулях PSQL;
* выполнять соединение (JOIN) просмотра с другими просмотрами и таблицами. В некоторых случаях вы можете соединять просмотры с хранимыми процедурами выбора.
Для простой иллюстрации создадим просмотр и хранимую процедуру для таблицы EMPLOYEE и выполним их соединение. Вот просмотр:
CREATE VIEW V_EMP_NAMES
AS
SELECT EMP_NO, LAST_NAME, FIRST_NAME
FROM EMPLOYEE ^
COMMIT ^
А вот хранимая процедура:
CREATE PROCEDURE P_EMP_NAMES
RETURNS (
EMP_NO SMALLINT;
EMP_NAME VARCHAR (35))
AS
BEGIN
FOR SELECT EMP_NO, FIRST_NAME || ' ' || LAST_NAME FROM EMPLOYEE
INTO :EMP_NO, :EMP_NAME
DO
SUSPEND;
END ^
COMMIT ^
Запрос, который их соединяет:
SELECT
V.EMP_NO,
V.LAST_NAME,
V.FI RST_NAME,
P.EMP_NAME
FROM V_EMP_NAMES V
JOIN P_EMPNAMES P
ON V.EMP_NO = P.EMPNO ^
Использование планов запросов для просмотров
Просмотры могут представлять для пользователей некоторые сложности относительно возможности PLAN. В основном пользователи могут трактовать просмотры как обычные таблицы. Однако, если вы захотите определить пользовательский план, вам нужно иметь сведения об индексах и структурах базовых таблиц, участвующих в просмотре.
Оптимизатор трактует ссылку на просмотр так, как если бы базовые таблицы, используемые при создании просмотра, были добавлены в список FROM запроса.
Предположим, просмотр был создан следующим образом:
CREATE VIEW V_PROJ_LEADERS (
PROJ_ID,
PROJ_TITLE,
LEADER_ID,
LEADER_NAME)
AS
SELECT
P.PROJ_ID,
P. PROJ_NAME,
P. TEAM_LEADER,
E.FULL_NAME,
FROM PROJECT P
JOIN EMPLOYEE E
ON P.TEAM_LEADER = E.EMPNO;
Простой запрос к просмотру
SELECT * FROM V_PROJ_LEADERS;
выводит следующий план:
PLAN JOIN (V_PROJ_LEADERS P NATURAL, V_PROJ_LEADERS E INDEX (RDB$PRIMARY7) )
Обратите внимание, что оптимизатор обращается к индексам базовых таблиц (через алиасы р и Е) для лучшего способа поиска в просмотре. Спецификация SELECT в объявлении CREATE VIEW определяет логику выполнения соединения.
Следующий запрос является чуть более сложным. В этот раз просмотр соединяется с таблицей EMPLOYEE PROJECT с помощью первичных ключей таблиц EMPLOYEE и PROJECT. Затем он опять соединяется с таблицей EMPLOYEE для получения ненормализованного списка, который включает имена участников всех проектов, управляемых просмотром: