Я не уверен , если есть более простой и эффективный способ сделать это, чем то, что я пытаюсь предпринять. Я хотел бы получить некоторые рекомендации / советы, если это возможно
TLDR; нет
Вы должны понимать, что представление - это НЕ данные в базе данных; это сохраненный SQL запрос, который запускается каждый раз, когда вы выбираете в представлении.
Может даже случиться, что SQL Сервер берет ваш запрос и смешивает его с запросом, который предоставляет представление, оптимизирует их и запускает их, поэтому даже не обязательно, что он выполняет запрос представления, получает все миллионы записей, которые представляет представление, а затем просматривает их, ища одного парня по имени Константинополь Эрнхардт - SQL Сервер может посчитать лучшим, чтобы молча и прозрачно переписать запрос, который вы дали, так что он запланирован и работает совершенно иначе, чем вы может подумать - он делает это для каждого запроса, в процессе, называемом оптимизацией.
Ваше мнение:
CREATE VIEW MyView AS
SELECT * FROM Person p JOIN Address a on p.AddressId = a.Id
Вы пишете:
SELECT * FROM MyView WHERE Name = 'Abc' and HouseName = 'def'
Вы можете подумать он делает это (и концептуально, вы правы):
SELECT * FROM
(
SELECT * FROM Person p JOIN Address a on p.AddressId = a.Id
) x WHERE Name = 'Abc' and HouseName = 'def'
Но это, вероятно, переписано так:
SELECT * FROM Person p JOIN Address a on p.AddressId = a.Id WHERE Name = 'Abc' and HouseName = 'def'
Так что теперь это не так, и вы можно увидеть, что представление - это просто запрос поверх таблицы, который запускается каждый раз, когда вы выбираете из него - как удалить данные из запроса?
* 10 28 * Вы не можете, потому что запросы не имеют данных; они извлекают данные из таблиц
Единственный способ «удалить данные из представления» - это удалить данные из таблицы, в которой представление выбирает данные из
. Вы можете только сделать это с помощью DELETE
операторов соответствующих таблиц
Существует средство, в которое можно записать триггер INSTEAD OF
для представления, а затем удалить из представления, и SQL Сервер будет запустить триггер (который удаляет из базовых таблиц). Может показаться, что вы удаляете данные из представления, но на самом деле вы просто вызываете механизм удаления данных из базовых таблиц так же, как представление - это механизм, который вытаскивает данные из этих таблиц.
Вы можете написать хранимую процедуру, которая удаляет данные, но опять же, это всего лишь механизм удаления данных из базовой таблицы
Выберите любой метод, который вам нравится, в соответствии с вашими бизнес-целями и желанием инкапсулирование вашего программного обеспечения определенным образом. Например, в прошлом у меня было программное обеспечение, которое я не мог изменить (потерял исходный код или что-то еще), и оно было жестко привязано к SELECT FROM users
или DELETE FROM users
- мы хотели, чтобы программное обеспечение продолжало работать, даже если Таблица пользователей была переименована в члены. Мы переименовали таблицу, затем создали представление с именем users
, которое только что SELECT * FROM members
- которое позволяет приложению продолжать работать, считывая данные. Затем мы создали INSTEAD OF
триггеры для обновления и удаления данных в таблице членов, когда приложение попыталось выполнить эту операцию в представлении users
(которое приложение все еще считало таблицей)
Итак почему это так сложно? Ну, данные, которые выходят из вашего представления, могут даже не относиться к строке таблицы. Вот простая версия:
CREATE VIEW MyView AS
SELECT MAX(SUBSTR(Name, 4, 999)) MaxFirstName FROM Person GROUP BY Gender
Предположим, что было два человека с именами Mr Lee Smith
и Ms Lee Smith
, вы взяли максимум вывода функции и получили Lee Smith
и теперь хотите удалить Lee Smith
из таблицы Person путем анализа представления и удаления ... что из таблицы Person? Какая запись? Группировка собрала все записи вместе. МАКСИМАЛЬНОЕ имя одного и даты рождения MIN от другого ..
Вот еще один пример, немного более нелепый, но мыслимый:
CREATE VIEW MyView AS
SELECT name as x FROM person
UNION
SELECT street FROM address
Это может легко привести к значению "Penny Lane" - но это человек или дорога? Который должен быть удален, если мы удалим из этого представления, где x = 'Penny Lane'
Не существует пули magi c, в которой вы можете ее запустить, и будет написано "эта таблица использует эти 3 таблицы" так что вы можете удалить из них. Это даже не будет хорошей предпосылкой. Ваше представление может выбрать одну таблицу данных и одну таблицу поиска и удалить тип пола 1 из таблицы поиска только потому, что вы удаляете Дональда Трампа из таблицы пользователей, будет плохим вызовом
Если вы хотите предоставить средства для удаления в представлении, вам нужно что-то кодировать; не существует автоматического решения, которое могло бы определить, какие данные из каких таблиц следует удалить, а какие должны остаться. Только представьте, как трудно было бы проанализировать представление, объединяющее 9 таблиц, со смесью стилей объединения, плюс еще 8 списков ЗНАЧЕНИЙ, 3 вызова функции таблицы с перекрестными приложениями, которая анализирует некоторый json, отбрасывая пару там есть строки, генерирующие рекурсивные CTE, а также опорная точка ...
Абсолютно нет шансов, что кто-нибудь напишет кнопку magi c, чтобы разбить все это на части, "составить список базовых таблиц и какие данные должен быть удален, чтобы удовлетворить DELETE FROM MyView WHERE output_of_parsing_function = 'Hello'