Хобрук: Ваш путь к мастерству в программировании

Триггер SQL Server не вставляет строку

Я работаю с SQL Server 2008 R2.

У меня есть простой триггер

CREATE TRIGGER [dbo].[T_Personne_ITrig] ON [dbo].[Personne] FOR INSERT AS 
BEGIN
SET NOCOUNT ON 

insert into syn_HistoriquePersonne 
     (hpers_Timestamp, Supprime, ID, Nom, Prenom, Champ1, 
      Champ2, Champ3, Champ4 SiteAssocie)
 select  GETDATE(), 0, ID, Nom, Prenom, Champ1, Champ2, Champ3, 
       Champ4,  SiteAssocie
from inserted
END

Он работает правильно. Проблема в том, что я работаю над программой с ужасной базой кода, поэтому мой босс не хочет, чтобы триггер когда-либо вызывал откат для таблицы Personne, даже если он терпит неудачу. Я знаю, что это действительно маловероятно, но он боится тайм-аута в случае огромной активности базы данных... В ЛЮБОМ СЛУЧАЕ

Поэтому я искал информацию о коммитах в триггерах. И изменил триггер на:

CREATE TRIGGER [dbo].[T_Personne_ITrig] ON [dbo].[Personne] FOR INSERT AS 
BEGIN
SET NOCOUNT ON 

COMMIT

insert into syn_HistoriquePersonne 
     (hpers_Timestamp, Supprime, ID, Nom, Prenom, Champ1, 
      Champ2, Champ3, Champ4 SiteAssocie)
select  GETDATE(), 0, ID, Nom, Prenom, Champ1, Champ2, Champ3, 
       Champ4,  SiteAssocie
from inserted
END

Но триггер продолжал стрелять сообщением

Транзакция остановлена ​​в триггере, пакет прерван.

Поэтому я сделал это так:

CREATE TRIGGER [dbo].[T_Personne_ITrig] ON [dbo].[Personne] FOR INSERT AS 
BEGIN
SET NOCOUNT ON 

COMMIT
BEGIN TRAN
insert into syn_HistoriquePersonne 
     (hpers_Timestamp, Supprime, ID, Nom, Prenom, Champ1, 
      Champ2, Champ3, Champ4, SiteAssocie)
 select  GETDATE(), 0, ID, Nom, Prenom, Champ1, Champ2, Champ3, 
       Champ4,  SiteAssocie
 from inserted
 END

Он перестал прерывать пакет, но, похоже, никогда ничего не вставлял в мою историческую таблицу ... Я читал об этом, и я думаю, что это должно сработать. Но это не...

У кого-нибудь уже была такая проблема и как я могу это исправить?

Я делаю простую вставку, чтобы проверить свой триггер.


  • Просто даже не вызывайте ROLLBACK в своем триггере - тогда все будет в порядке. Не запускайте новые транзакции в триггере... триггер всегда должен выполняться в контексте операции, вызвавшей его срабатывание. 16.02.2012
  • Я не буду вызывать откат в своем триггере, но приложение сделает это, если произойдет тайм-аут. Я знаю, что start tran не оптимален, но он останавливает сообщение об ошибке. Но реальный вопрос в том, почему вставка не работает... 16.02.2012
  • Но вы сказали в своем первом фрагменте кода: он работает правильно — так в чем проблема?? Если есть тайм-аут - вы все равно ничего не можете сделать внутри триггера, чтобы справиться с этим..... 16.02.2012
  • Я знаю, что это, вероятно, глупое требование моего босса, но все, чего он хочет, это чтобы в случае возникновения какой-либо ошибки в триггере, т. е. тайм-аута, он хотел, чтобы исходная транзакция на Personne оставалась нетронутой и не откатывалась. Этого еще не произошло, но он хочет быть уверенным... 16.02.2012
  • Триггер происходит как часть вставки, которая запускает триггер. Вы не можете написать код внутри триггера, чтобы изолировать его от внешней транзакции. Извините, но я не знаю, как это выразить по-другому, вы лаете не по тому дереву, это невозможно. Если вы действительно хотите, чтобы две части кода были независимыми, удалите триггер и поместите некоторые из них, чтобы обновить код таблицы истории в sql, вызываемом вашим приложением. Затем вы можете контролировать, где и когда вы размещаете начала и коммиты. Но у вас не может быть части кода внутри транзакции, которая не является частью этой транзакции. 16.02.2012
  • Я просто надеялся, что может быть способ сделать то, что я хотел, даже если это действительно грязно, хе-хе. Но спасибо за ваше время! Я просто оставлю все как есть и объяснить моему боссу, что он хочет, на самом деле невозможно. 16.02.2012

Ответы:


1

К сожалению, вы лаете не на то дерево. Вы не можете играть с транзакциями таким образом.

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

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

Поскольку в вашем случае, похоже, просто ведется исторический журнал, возможно, вариант может быть таким же простым, как удаление всех ограничений из таблицы исторических данных. Все решения немного грязные, но тогда требование от вашего босса кажется немного необычным; ответ должен действительно быть планированием мощности, на мой взгляд.

Я не знаю, соответствует ли это вашему реальному сценарию, но я надеюсь, что это поможет.

16.02.2012
  • Историческая таблица уже не имеет никаких ограничений. Но проблема в том, что даже если у меня нет оператора Begin Tran, если я помещу фиксацию в триггер до того, как вставлю в свою таблицу журнала, вставка никогда не сработает... Это как будто я никогда не вызывал вставку в все, и я не понимаю, почему. 16.02.2012
  • Я отследил с помощью некоторой печати, если код выполняет вставку, и он должен ее выполнить. Но по неизвестной причине ничего не вставляется, и я вообще не получаю сообщения об ошибке. 16.02.2012
  • @AlexJean - Согласно первой строке моего ответа: вы не можете играть с такими транзакциями. BEGIN TRANSACTION и COMMIT TRANSACTION должны находиться в одной области видимости. Если команда SQL приложения начинает транзакцию, команда приложения должна зафиксировать ее. Поскольку у вас нет ограничений и т. Д. На вашем столе, вы не сделаете это быстрее, и это ЕДИНСТВЕННОЕ, что вы могли бы сделать. (Попытка создать отказоустойчивость команды с тайм-аутом в том, к чему вы стремитесь, просто невозможна.) 16.02.2012
  • @Alex Jean Почему вы выполняете COMMIT внутри своего триггера? Демс прав - удали. 16.02.2012
  • Это должно было сделать первоначальную транзакцию в таблице Personne «откатываемой» в случае сбоя вставки в таблицу журнала. 16.02.2012
  • Новые материалы

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

    Как построить любой стол
    Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

    Обзор: Машинное обучение: классификация
    Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

    Разработка расширений Qlik Sense с qExt
    Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..

    React Hooks: основы деструктуризации массива
    Kent C. Dodds написал классный пост о том, как грядущая функция React под названием Hooks работает на капоте. Предстоящий хук React useState основан на деструктурировании массива, давайте..

    Пакеты R, используемые в Tesla
    Добро пожаловать обратно! R — очень популярный язык программирования, используемый множеством компаний, включая Tesla! Итак, давайте взглянем на некоторые пакеты R, которые использует Tesla...

    Сокращение и слияние токенов для эффективных моделей VL: обзор
    Часто в задачах, связанных с компьютерным зрением и НЛП, вычислительно затратная и требующая большого объема памяти обработка становится препятствием для более быстрого логического вывода модели, а..