Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 try без возврата сообщения об ошибке  [new]
Arl
Member

Откуда:
Сообщений: 90
Добрый день всем!

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

Решил сделать так: данные скидываются в таблицу 1 "как есть", без ключей.
Создал таблицу 2(HISTORY), с ключами, в которой будут храниться уникальные упорядоченные записи из таб.1

В таблице 1 сделал триггер на вставку:
	BEGIN TRY
		INSERT INTO dbo.history ([Номер],.......) SELECT [Номер],........ FROM INSERTED
	END TRY

	BEGIN CATCH  
		IF ERROR_NUMBER() = 2627 GOTO FIN
	END CATCH 

	FIN:

Проблема в том, что при попытке вставить существующую запись в таблицу HISTORY, из БД в приложение приходит сообщение:
(При этом приложение, из которого экспортируются данные, виснет напрочь)
[Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Произошла ошибка при выполнении триггера.
Выполнение пакета аварийно завершено, и произведен откат пользовательской транзакции, если она существует.
SQLSTATE=37000
Код ошибки=3616

Как сделать так:
Если попытка вставить запись в HISTORY привела к нарушению первичного ключа, то БД без сообщений завершает транзакцию?

Или как можно проверить наличие записи в таб.HISTORY, чтобы даже не пытаться вставить повторяющуюся запись?
2 ноя 16, 13:19    [19850536]     Ответить | Цитировать Сообщить модератору
 Re: try без возврата сообщения об ошибке  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
Arl,
автор
Если попытка вставить запись в HISTORY привела к нарушению первичного ключа, то БД без сообщений завершает транзакцию?

SET XACT_ABORT OFF
автор
Или как можно проверить наличие записи в таб.HISTORY, чтобы даже не пытаться вставить повторяющуюся запись?

всё же в insrted проверяйте наличие...
2 ноя 16, 13:40    [19850695]     Ответить | Цитировать Сообщить модератору
 Re: try без возврата сообщения об ошибке  [new]
invm
Member

Откуда: Москва
Сообщений: 9400
Arl
Или как можно проверить наличие записи в таб.HISTORY, чтобы даже не пытаться вставить повторяющуюся запись?
Можно. См. инструкцию merge. Плюс в select ... from inserted тоже отсеять дубликаты.
2 ноя 16, 13:44    [19850729]     Ответить | Цитировать Сообщить модератору
 Re: try без возврата сообщения об ошибке  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
И чтобы дополнить феерию неадекватности в целом можно добавить в ПК IGNORE_DUP_KEY = ON.
2 ноя 16, 13:47    [19850768]     Ответить | Цитировать Сообщить модератору
 Re: try без возврата сообщения об ошибке  [new]
invm
Member

Откуда: Москва
Сообщений: 9400
Arl,

Либо можете сразу на основной таблице сделать ключ с опцией ignore_dup_key = on
Правда в этом случае, при попытке вставки дубликата будет выдаваться предупреждение, которое клиент тоже не сможет прожевать.
2 ноя 16, 13:48    [19850778]     Ответить | Цитировать Сообщить модератору
 Re: try без возврата сообщения об ошибке  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
Руслан Дамирович
И чтобы дополнить феерию неадекватности в целом можно добавить в ПК IGNORE_DUP_KEY = ON.

а в чём там неадекватность, напомните? многие находят это нормальным решением
2 ноя 16, 13:50    [19850786]     Ответить | Цитировать Сообщить модератору
 Re: try без возврата сообщения об ошибке  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
У автора триггер "после", а не "вместо". Черт сидит в деталях ;)
2 ноя 16, 14:24    [19851015]     Ответить | Цитировать Сообщить модератору
 Re: try без возврата сообщения об ошибке  [new]
Arl
Member

Откуда:
Сообщений: 90
Всем спасибо большое за ответы!
Буду читать, разбираться.

Не понял, что имеется ввиду:
TaPaK
всё же в insrted проверяйте наличие...

Попытка вставки записей из inserted в таблицу hist и есть проверка на наличие записи..??
2 ноя 16, 17:11    [19852050]     Ответить | Цитировать Сообщить модератору
 Re: try без возврата сообщения об ошибке  [new]
Arl
Member

Откуда:
Сообщений: 90
Всем еще раз спасибо за ответы.
Все-таки я думаю, что правильно будет использовать инструкцию merge, а не отключать ошибки.
Вопрос только в скорости обработки. Читал, что наиболее быстрый способ - попытка вставки в таблицу и отлов ошибки нарушения ПК.
Как в этом плане merge будет на рабочей базе - вопрос.
На тестовой попробовал - сильных отличий не заметил.
3 ноя 16, 08:11    [19853346]     Ответить | Цитировать Сообщить модератору
 Re: try без возврата сообщения об ошибке  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
TaPaK
Руслан Дамирович
И чтобы дополнить феерию неадекватности в целом можно добавить в ПК IGNORE_DUP_KEY = ON.

а в чём там неадекватность, напомните? многие находят это нормальным решением

Очень часто встречал в интернете рекомендацию не использовать IGNORE_DUP_KEY в том же ключе, что и не использовать DISTINCT для группировки - bad code.

P.S. ИМХО, в контексте задачи ТС достаточно сделать простой MERGE с OUTPUT.
3 ноя 16, 17:14    [19856672]     Ответить | Цитировать Сообщить модератору
 Re: try без возврата сообщения об ошибке  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
Руслан Дамирович
TaPaK
пропущено...

а в чём там неадекватность, напомните? многие находят это нормальным решением

Очень часто встречал в интернете рекомендацию не использовать IGNORE_DUP_KEY в том же ключе, что и не использовать DISTINCT для группировки - bad code.

P.S. ИМХО, в контексте задачи ТС достаточно сделать простой MERGE с OUTPUT.

мы вообщем-то не используем, лично мне не нравится такой подход, но единственная проблема которая мне известна это
Locking in Microsoft SQL Server (Part 20) – Range lock (RangeS-U) deadlock due to IGNORE_DUP_KEY index option
3 ноя 16, 17:23    [19856720]     Ответить | Цитировать Сообщить модератору
 Re: try без возврата сообщения об ошибке  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
TaPaK
мы вообщем-то не используем, лично мне не нравится такой подход, но единственная проблема которая мне известна это
Locking in Microsoft SQL Server (Part 20) – Range lock (RangeS-U) deadlock due to IGNORE_DUP_KEY index option

Спасибо, буду знать. У меня была задача исключения дубликатов вставки, где я "успешно" применял IGNORE_DUP_KEY, но никогда не было в контексте параллельной работы с таблицами. Видимо поэтому эти грабли остались нетронутыми.
7 ноя 16, 17:40    [19866850]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить