Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
Шрифт:
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 для получения ненормализованного списка, который включает имена участников всех проектов, управляемых просмотром:
SELECT
PL.*,
EMP.LAST_NAME
FROM V_PROJ_LEADERS PL
JOIN EKPLOYEE_PROJECT EP
ON PL.PROJ_ID = EP.PROJ_ID
JOIN EMPLOYEE EMP
ON EP.EMP_NO = EMP.EMP_NO;
PLAN JOIN (EMP NATURAL, EP INDEX (RDB$FOREIGN15) , PL P INDEX (RDB$PRIMARY12) ,
PL E INDEX (RDB$PRIMARY?) )
В этот раз индекс внешнего ключа для столбца EMP_NO таблицы EMPLOYEE_PROJECT (с алиасом EP) используется для выбора имен участников проекта из второго "элемента" - EMPLOYEE. Как и в предыдущем случае, соединение внутри просмотра использует первичный ключ таблицы EMPLOYEE для поиска соответствия в TEAM_LEADER.