Можно ли изменять данные через view в SQL
Что проверяют
Знаете ли вы, что представление это сохранённый запрос, а не копия данных, и понимаете ли, при каких условиях через него можно писать. Для тестировщика уточнение обычно практическое: что случится со строкой, которая после UPDATE перестала подходить под условие представления.
Как отвечать
Можно, если представление обновляемое. Изменения при этом пишутся в базовую таблицу, своих данных у view нет. Условия похожи во всех СУБД, но детали различаются:
- PostgreSQL: простое представление обновляется автоматически, если в
FROMодна таблица или другое обновляемое view и нетGROUP BY,HAVING,DISTINCT,LIMIT,OFFSET,UNION, агрегатов и оконных функций. Вычисляемые колонки допустимы, но менять можно только обычные; - MySQL: обновляемы и представления с
JOIN, если одинUPDATEтрогает одну таблицу.ALGORITHM=TEMPTABLEделает view необновляемым; - SQL Server и Oracle: изменение должно затрагивать одну базовую таблицу, в Oracle это таблица с сохранённым ключом в join-представлении;
- сложные случаи: для любого view можно написать триггер
INSTEAD OF, который сам разложит изменение по таблицам.
Отдельно назовите WITH CHECK OPTION. Без него через представление с WHERE active = 1 можно вставить строку с active = 0 или обновить строку так, что она исчезнет из выборки, и запрос отработает без ошибки. С опцией база такую запись отклонит.
Материализованное представление в PostgreSQL через INSERT и UPDATE не меняется, оно обновляется только командой REFRESH MATERIALIZED VIEW.
Что проверяет QA: запись через view доходит до нужной таблицы, ограничения и триггеры базовой таблицы срабатывают, строки не «теряются» после изменения, права через view не шире задуманных.
Где спотыкаются
Говорят, что view только для чтения. Это верно для сложных представлений, но не для простых.
Считают правило «одна таблица без JOIN» универсальным. В MySQL и Oracle join-представления частично обновляемы, поведение зависит от СУБД.
Не знают про исчезающие строки. Проверка «обновил и перечитал через то же view» даёт пустой результат, и его принимают за баг записи, хотя без WITH CHECK OPTION это ожидаемое поведение.