Раздел 5. Представления

Представление (англ. VIEW), называемое иногда так же виртуальной таблицей, является объектом базы данных, который можно использовать, наряду с таблицами, в запросах как источник данных, и, с рассматриваемыми далее ограничениями, в командах обновления. В отличие от таблицы, представление на содержит записей, и представляет собой, по существу, именованный SELECT-запрос, который “подставляется” в SQL-команды при обращении к этому представлению. Таблицы, которые используются в запросе представления, называются базовыми.

Представления могут быть полезны в следующих случаях. Прежде всего, представления используются для именования или сокрытия сложных, громоздких и часто используемых SQL-выражений. Вернемся снова к следующему запросу:

SELECT "Имя", "Фамилия", "Клиент",

"Дата регистр", "Название", "Количество", "Мера изм", "Дата выполн"

FROM "Клиент", "Товар", "Заказ", "СоставЗак"

WHERE "Клиент"."Код Клиента" = "Заказ"."Клиент" AND "Заказ"."Код заказа"="СоставЗак"."Код заказа" AND "Товар"."Код товара"="СоставЗак"."Код товара"

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

CREATE VIEW "Все заказы" AS

SELECT "Имя", "Фамилия", "Клиент",

"Дата регистр", "Название", "Количество", "Мера изм", "Дата выполн"

FROM "Клиент", "Товар", "Заказ", "СоставЗак"

WHERE "Клиент"."Код Клиента"="Заказ"."Клиент"

AND "Заказ"."Код заказа"="СоставЗак"."Код заказа" AND "Товар"."Код товара"="СоставЗак"."Код товара"

Теперь это представление можно использовать в SELECT-запросах, например:

SELECT * FROM "Все заказы"

При вычислении этого запроса Oracle определит, что объект "Все заказы" является именно представлением, а не таблицей, далее найдет в системном каталоге его определение и выполнит входящий в него SELECT-запрос.

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

SELECT * FROM "Все заказы"

WHERE "Имя" = 'Лена' AND "Фамилия" = 'Шварц'

SELECT "Имя", "Фамилия", COUNT(*)

FROM "Все заказы"

GROUP BY "Имя", "Фамилия"

Другое использование представлений связано с представление данных базовых таблиц в более удобном для пользователя виде; например, с содержательными заголовками на русском языке, и т.д. Типичным примером таких представлений являются представления системного словаря типа ALL_TABLES, USER_TABLES и т.д., извлекающие данные из системной таблицы OBJ$, которая является малоподходящей для непосредственной работы. Читателю рекомендуется для визуального анализа исполнить следующий запрос:

SELECT * FROM SYS.OBJ$

Ниже приведен запрос к представлению ALL_VIEWS из системного каталога, извлекающий определение этого же представления (включая текст SELECT-запроса); читатель может оценить достоинства упрощенного обращения к системному каталогу при помощи представлений.

SELECT OWNER, VIEW_NAME, TEXT

FROM all_views

WHERE VIEW_NAME ='ALL_VIEWS'

OWNER VIEW_NAME TEXT
SYS ALL_VIEWS select u.name, o.name, v.textlength, v.text, t.typetextlength, t.typetext, t.oidtextlength, t.oidtext, t.typeowner, t.typename, decode(bitand(v.property, 134217728), 134217728, (select sv.name from superobj$ h, obj$ sv where h.subobj# = o.obj# and h.superobj# = sv.obj#), null) from sys.obj$ o, sys.view$ v, sys.user$ u, sys.typed_view$ t where o.obj# = v.obj# and o.obj# = t.obj#(+) and o.owner# = u.user# and (o.owner# = userenv('SCHEMAID') or o.obj# in (select oa.obj# from sys.objauth$ oa where oa.grantee# in (select kzsrorol from x$kzsro)) or /* user has system privileges */ exists (select null from v$enabledprivs where priv_number in (-45 /* LOCK ANY TABLE */, -47 /* SELECT ANY TABLE */, -48 /* INSERT ANY TABLE */, -49 /* UPDATE ANY TABLE */, -50 /* DELETE ANY TABLE */)))

Длинное значение по поле text является текстом определения SELECT-запроса для представления ALL_VIEWS.

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

Сначала создадим некоторую базовую таблицу:

CREATE TABLE "Все записи"

(username CHAR(20) DEFAULT USER

NOT NULL UNIQUE,

name CHAR(20),

birth DATE)

Обратите внимание, что поле username содержит присваиваемое по умолчанию значение – название учетной записи пользователя, доступное через системную функцию USER; прочие поля содержат ползовательскую информацию.

Теперь создадим представление со следующим определением:

CREATE OR REPLACE VIEW "Мои записи"

AS SELECT name "Имя", birth "Дата рождения"

FROM "Все записи"

WHERE username = USER

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

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

SELECT * FROM "Мои записи"

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

INSERT INTO "Мои записи" VALUES ('Ада Вонг', NULL)

При добавлении строки в представление, при этом, естественно, запись будет добавлена в базовую таблицу, причем поле username будет инициализирована значеним по умолчанию:

USERNAME NAME BIRTH
CUSTOMER Ада Вонг -

Здесь значение CUSTOMER – имя учетной записи.

Теперь рассмотрим вопрос о модификации данных базовых таблиц через обращение к ним через представления; пример добавления новой записи приведен выше. В целом, добавление новых записей и изменение и удаление существующих возможно, если, говоря неформально, между строками представления и строками базовых таблиц существует прямое соответствие, равно как и между полям представления и таблицы. Такое соответствие присутствует в представлении "Мои записи". Данные нельзя модифицировать, если запрос представления содержит, в том числе, выражения, вычисляемые на основании полей исходный таблицы, опцию DISTINCT, упорядочивание, группировку и вычисление агрегатных функций, операцию UNION, а так же многотабличные запросы с соединением (есть исключения). Модифицировать данные рассматриваемого выше представления "Все заказы", конечно же, нельзя.

Можно явным образом запретить изменение данных любого представления, используя опцию WITH READ ONLY, например:

CREATE OR REPLACE VIEW "Мои записи" AS

SELECT name "Имя", birth "Дата рождения"

FROM "Все записи"

WHERE username = USER

WITH READ ONLY

В завершении рассмотрим еще одну возможность работы с представлениями; изменим несколько определение представления "Мои записи", добавив в список полей новое поле:

CREATE OR REPLACE VIEW "Мои записи" AS

SELECT name "Имя", birth "Дата рождения",

User “Пользователь”

FROM "Все записи"

WHERE username = USER

Для этого представления будет корректно исполняться следующая команда добавления новой строки:

INSERT INTO "Мои записи"

VALUES ('Кристи', NULL, ‘Un Hombre’)

Однако эта запись, естественно, не будет содержаться в значении выборки SELECT * FROM "Мои записи", поскольку не сответствует условию селекции запроса. Чтобы устранить подобные противоречивые ситуации, следует к определению запроса добавить опцию WITH CHECK OPTION, при использовании которой происходит проверка изменений условиям запроса:

CREATE OR REPLACE VIEW "Мои записи" AS

SELECT name "Имя", birth "Дата рождения",

User “Пользователь”

FROM "Все записи"

WHERE username = USER

WITH CHECK OPTION

Команда ALTER VIEW предназначена для изменения наложенных ограничений на представление (в данном пособии не рассматриваемых); для изменения запроса необходимо представление создать заново. Удаление представления при помощи команды DROP VIEW на данные базовых таблиц не влияет.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: