MSSQL: отключить триггеры для одного INSERT
Этот вопрос очень похож на SQL Server 2005: T-SQL для временного отключения триггера
Однако я не хочу отключать все триггеры и даже не для пакетной команды, а только для одного INSERT.
Мне приходится иметь дело с системой магазинов, где оригинальный автор помещает некоторую логику приложения в триггер (плохая идея!). Эта прикладная логика отлично работает, если вы не пытаетесь вставить данные по-другому, чем исходный "интерфейс администрирования". Моя задача - написать инструмент "импорт из промежуточной системы", поэтому у меня есть все данные. Когда я пытаюсь вставить его, триггер перезаписывает существующий код продукта (а не идентификатор IDENTITY!) С сгенерированным. Чтобы сгенерировать код, он использует автогенерированный идентификатор вставки для другой таблицы, так что я даже не могу работать с @@IDENTITY, чтобы найти только что вставленный столбец и ОБНОВИТЬ вставленную строку с фактическим кодом продукта.
В любом случае, я могу пойти, чтобы избежать крайне неудобного кода (ВСТАВЬТЕ некоторые случайные символы в имя продукта, а затем попытайтесь найти строку со случайными символами для ее обновления).
Итак: есть ли способ отключить триггеры (даже один) для только одного INSERT?
Ответы
Ответ 1
Вы можете отключить триггеры в таблице, используя:
ALTER TABLE MyTable DISABLE TRIGGER ALL
Но это сделало бы это для всех сеансов, а не только для вашего текущего соединения. Это, очевидно, очень плохо: -)
Лучшим способом было бы изменить сам триггер, чтобы он принял решение, если ему нужно выполнить его, будь то флаг "insert type" в таблице или какие-либо другие средства, если вы уже сохраняете тип некоторого сортировки.
Ответ 2
Вы можете счесть это полезным:
Отключение триггера для конкретного заявления или сеанса SQL
Но есть и другая проблема, с которой вы можете столкнуться.
Если я понимаю ситуацию, в которой вы находитесь, ваша система по умолчанию автоматически вставляет код продукта (генерируя значение).
Теперь вам нужно вставить продукт, который был создан какой-то промежуточной системой, и для этого продукта его код продукта был создан системой промежуточного хранения, и вы хотите вручную вставить его в живую систему.
Если вам действительно нужно это сделать, вам нужно убедиться, что коды, созданные вами в прямом эфире в будущем, не будут конфликтовать с кодом, который вы вставили вручную - я предполагаю, что они должны быть уникальными.
Другой подход заключается в том, чтобы позволить системе генерировать новый код и при необходимости перезаписывать любые соответствующие данные.
Ответ 3
Вместо отключения триггеров вы не можете изменить поведение триггера. Добавьте новый столбец с нулевым значением в рассматриваемую таблицу под названием "insertFromImport" .
В триггере измените код так, чтобы бит-бит триггера выполнялся только в строках, где "insertFromImport" имеет значение null. Когда вы вставляете свои записи, установите "insertFromImport" в нечто ненулевое.
Ответ 4
Отключить триггер, вставить, зафиксировать.
SET IDENTITY_INSERT Test ON
GO
BEGIN TRAN
DISABLE TRIGGER trg_Test ON Test
INSERT INTO Test (MyId, MyField)
VALUES (999, 'foo')
ENABLE TRIGGER trg_Test ON Test
COMMIT TRAN
SET IDENTITY_INSERT Test OFF
GO
Ответ 5
Вы можете проверить SUSER_SNAME() и запускать только в контексте интерфейса администратора?
Ответ 6
Я вижу много вещей, которые могут создать проблему. Сначала измените триггер, чтобы рассмотреть несколько импортных записей. Возможно, это может решить вашу проблему. Не выключайте спусковой крючок, поскольку он выключен для всех, а не только для вас. Если вы должны затем поместить базу данных в пользовательский пользовательский режим, прежде чем вы это сделаете, и выполните свою задачу в нерабочее время.
Далее, ни в коем случае не используйте @@identity, чтобы получить только что вставленное значение! Вместо этого используйте значение scope_identity. @@identity вернет неправильное значение, если в таблице есть триггеры, которые также вставляются в другие таблицы с полями идентификации. Если вы используете идентификатор @@прямо сейчас через свою систему (так как мы знаем, что у вашей системы есть триггеры), ваш приоритет должен быть немедленно обнаружен и заменен всеми экземплярами идентификатора @@в вашем коде. У вас могут быть серьезные проблемы с целостностью данных, если вы этого не сделаете. Это проблема "прекратить работу, пока это не будет исправлено".
Что касается получения информации, которую вы только что вернули, подумайте над созданием batchid как части вашего вставки, а затем добавьте столбец с именем batchid (который является нулевым, чтобы он не влиял на другие вставки) в таблицу. Затем вы можете перезвонить, что вы вставили с помощью batchid.
Ответ 7
Если вы вставляете BULK INSERT, вы можете отключить триггеры только для вставки.
Я уверен, что объемная вставка потребует импортировать файл данных в файловой системе, поэтому вы не можете просто использовать T-SQL.
Для использования BULK INSERT вам нужны разрешения INSERT и ADMINISTRATOR BULK OPERATION.
Если вы отключите триггеры или ограничения, вам также понадобится разрешение ALTER TABLE.
Если вы используете проверку подлинности Windows, вашему пользователю Windows потребуется доступ к чтению из файла. при использовании аутентификации в смешанном режиме учетной записи службы SQl Server требуется доступ для чтения из файла.
При импорте с использованием BULK IMPORT триггеры по умолчанию отключены.
Дополнительная информация: http://msdn.microsoft.com/en-us/library/ms188365.aspx