Поскольку базовым элементом выражения запросов
Поскольку базовым элементом выражения запросов является спецификация запроса, прежде всего нужно понять, какой класс спецификаций запросов является допускающим операции обновления (термин updatable - обновляемый, используемый в стандарте SQL, кажется не слишком удачным в русском варианте). В стандарте SQL/92 спецификация запроса считалась допускающей операции обновления в том и только в том случае, когда выполнялись следующие условия:
- в разделе SELECT спецификации запроса отсутствует ключевое слово DISTINCT (т.е. не требуется удаление строк-дубликатов из результата запроса);
- все элементы списка выборки раздела SELECT являются именами столбцов, и ни одно имя столбца не встречается в этом списке более одного раза;
- в разделе FROM присутствует только одна ссылка на таблицу, и она указывает либо на базовую таблицу, либо на порождаемую таблицу, допускающую операции обновления;
- прямые или косвенные ссылки на базовую таблицу, прямо или косвенно идентифицируемую ссылкой на таблицу в разделе FROM, не встречаются в разделе FROM ни одного подзапроса, участвующего в разделе WHERE спецификации запроса;
- в спецификации запроса отсутствуют разделы GROUP BY и HAVING.
Нетрудно убедиться в том, что эти требования являются достаточными для однозначной интерпретации операций обновления над представлениями. Например, пусть имеется следующая спецификация запроса (пример 17.9):
SELECT EMP_SAL FROM (SELECT EMP_SAL, DEPT_NO FROM EMP WHERE EMP_NAME = (SELECT EMP_NAME FROM EMP WHERE EMP_NO = 4425)) WHERE DEPT_NO <> 630;
Пример 17.9.
(html, txt)
Эту спецификацию можно упростить до эквивалентной формулировки1):
SELECT EMP_SAL FROM EMP WHERE EMP_NAME = (SELECT EMP_NAME FROM EMP WHERE EMP_NO = 4425 ) AND DEPT_NO <> 630;
Предположим, что с данной спецификацией запроса связано представление с именем EMPSAL. Тогда операция
UPDATE EMPSAL SET EMP_SAL = EMP_SAL - 1000.00;
эквивалентна операции
UPDATE EMP SET EMP_SAL = EMP_SAL - 1000.00 WHERE EMP_NAME = (SELECT EMP_NAME FROM EMP WHERE EMP_NO = 4425 ) AND DEPT_NO <> 630;