SQL Удаляет, если строка не затронута ограничениями

sb.deleteCharAt(sb.length() - 1) 
5
задан Community 23 May 2017 в 11:51
поделиться

6 ответов

Если вы повторно используете тот же список для delete, тогда вы можете подумать о том, чтобы вставить ключи для удаления во временную таблицу, а затем использовать это во втором запросе.

SELECT Key, ...
INTO #ToDelete
FROM Table T
WHERE ...

Затем что-то вроде этого

...
LEFT OUTER JOIN #ToDelete D
ON T.Key=D.Key
WHERE D.Key IS NULL

DROP #ToDelete
0
ответ дан 15 December 2019 в 06:33
поделиться

Если вы указали внешний ключ как ограничение при создании таблицы в базе данных, вы можете указать базе данных, что делать в случае удаления, установив правило удаления. Это правило определяет, что произойдет, если пользователь попытается удалить строку с данными, которые связаны с внешним ключом. Параметр «Нет действий» сообщает пользователю, что удаление запрещено, и выполняется откат DELETE. Реализация этого позволит вам не проверять его самостоятельно перед удалением, и, таким образом, может рассматриваться как своего рода попытка. Ну, по крайней мере, в MS SQL так работает. http://msdn.microsoft.com/en-us/library/ms177288.aspx

0
ответ дан 15 December 2019 в 06:33
поделиться

В терминах одной команды, которая проверяет отношения только один раз (а не дважды в вашем примере - один раз для НЕ СУЩЕСТВУЕТ , один раз для DELETE ), то я ожидаю, что ответ будет большим жирным нет, извините.

(неуместная идея): Если это серьезная проблема, вы можете попробовать какую-нибудь реализацию подсчета ссылок, используя триггеры для обновления счетчика - но на самом деле я ожидаю, что это потребует гораздо больше накладных расходов, чем простая проверка ключей, как вы уже делаете.

Вы также можете исследовать NOCHECK во время удаления (поскольку вы проверяете его сами); но вы можете сделать это только на уровне таблицы (так что, вероятно, нормально для сценариев администратора, но не для производственного кода) - то есть:

-- disable
alter table ChildTableName nocheck constraint ForeignKeyName

-- enable
alter table ChildTableName check constraint ForeignKeyName

Быстрый тест показывает, что при его включении выполняется дополнительное сканирование кластерного индекса для внешнего ключа; если он отключен, это опускается.

Вот полный пример; вы можете посмотреть план запроса для двух операций DELETE ... (в идеале изолированно от остального кода):

create table parent (id int  primary key)
create table child (id int  primary key, pid int)
alter table child add constraint fk_parent foreign key (pid)
    references parent (id)

insert parent values (1)
insert parent values (2)
insert child values (1,1)
insert child values (2,1)

-- ******************* THIS ONE CHECKS THE FOREIGN KEY
delete from parent
where not exists (select 1 from child where pid = parent.id)

-- reset
delete from child
delete from parent
insert parent values (1)
insert parent values (2)
insert child values (1,1)
insert child values (2,1)

-- re-run with check disabled
alter table child nocheck constraint fk_parent

-- ******************* THIS ONE DOESN'T CHECK THE FOREIGN KEY    
delete from parent
where not exists (select 1 from child where pid = parent.id)

-- re-enable
alter table child check constraint fk_parent

Опять же - я подчеркиваю, что это следует запускать только из таких вещей, как сценарии администратора .

2
ответ дан 15 December 2019 в 06:33
поделиться

Я нашел одну статью, в которой обсуждается использование внешнего соединения при удалении: http://www.bennadel.com/blog/939-Using-A-SQL-JOIN-In-A-SQL-DELETE-Statement-Thanks-Pinal-Dave-.htm

Надеюсь, это сработает для вас!

0
ответ дан 15 December 2019 в 06:33
поделиться

Вы можете создать индексированное представление выбранного предложения:

SELECT key FROM table WHERE table.key = centretable.key

Индексированное представление - это физическая копия данных, поэтому ее можно будет очень быстро проверить.

У вас есть накладные расходы на обновление представления, поэтому вам нужно будет проверить это в соответствии с вашим шаблоном использования.

1
ответ дан 15 December 2019 в 06:33
поделиться

Краткий ответ на ваш вопрос: нет, не существует стандартного ключевого слова СУБД для удаления главной записи, когда все ссылки на внешние ключи на нее исчезают (и, конечно, ни одна из них будет учитывать внешние ключи в нескольких таблицах).

Ваш наиболее эффективный вариант - это второй запрос, который запускается по мере необходимости для удаления из "центра" на основе серии предложений NOT EXISTS () для каждого из таблицы с внешними ключами.

Это основано на двух утверждениях, которые, как я считаю, верны для вашей ситуации:

  1. Вы удалите больше «связанных» записей, чем «центральных» (родительских) записей. Таким образом, любая операция, которая пытается настроить «центр» каждый раз, когда вы удаляете из одной из других таблиц, приведет к мгновенному обновлению «центра», но потребует много напрасных запросов для удаления «центральной» записи только изредка.

  2. Учитывая, что на звезде есть несколько точек от «центра», любые «потраченные впустую усилия» проверка внешнего ключа в одной из них минимальны по сравнению в целом. Например, если есть четыре внешних ключа, которые нужно проверить перед удалением из «центра», вы можете сэкономить, в лучшем случае, 25% времени.

0
ответ дан 15 December 2019 в 06:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: