При вставке из ХП отключить триггер

на некой таблице висит триггер для протоколирования всех операций. Как сделать так что при изменении данных из конкретной ХП этот триггер не срабатывал?
10 ответов

Или переписывать триггер, или отключать его, тогда он, отключенный, не будет работать ни для какой хп.З.Ы. Раз триггер для протоколирования, то зачем его отлючать?


Можно вставить в триггер проверку анализ результатов dbcc inputbuffer, но это ненадежно, потому что не сработает, если ваша процедура будет вызвана не напрямую, а из другой процедуры, к примеру.Есть также вариант, что ваша процедура будет вызывать ALTER table DISABLE TRIGGER, но он плох тем, что данное отключение произойдет для всех коннектов, а не только для текущего (если в транзакцию не обернете).Самое надежное - добавить некоторый признак, который триггер сможет зачитать и не выполнять ничего. Таким признаком может быть значение в таблице, только не забудьте подумать, как это будет работать в многопользовательской среде, и как оно будет себя вести при неожиданном обрыве коннекта.Или таким признаком может быть наличие _временной_ таблицы с заранее определенным именем. Ваша "конкретная" процедура создает такую таблицу и вызывает код, от которого срабатывает триггер. В триггере проверка на существование таблицы. Способ хорош тем, что нет проблем в многопользовательской среде и тем, что при обрыве коннекта нет проблем с очисткой "повисших" признаков.


В начало хранимой процедуры добавить код отключения тригерав конце, код включения.Совет чисто теоретический, не опробованыйИз побочных эффектов: тригера будут отключены для всех соединений


добавть код включения/отключения.... а как это скажется на других сессиях? я думаю не очень хорошо.


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


Имхо, признак (см. мой предыдущий пост) - самое милое дело. Другие коннекты не задевает, прост в имплементации, надежен.


не хотелось бы обламывать пользователей блокировкой. Мы это решали в лоб, используя зарезервированное поле, но тут намечается новая система, где такого поля может не быть. Суть такая - есть 2 банковские системы, их нужно синхронизировать, для этого надо вести список изменений. Для этого был написан триггер. Когда в 1-й системе меняют документы, это по триггеру ложится в таблицу изменений. После чего они похватываются программой переноса записей. По каждой записи вызывается ХП во 2-й системе для принятия изменений. Так вот, если вызвать в лоб Insert в этой ХП, то он поймается триггером и отошлется в 1 систему -> будем таскать записи по кругу. Видимо надо будет делать с доп. таблицей, где будет указано что данная запись не подлежит протоколированию


В триггере проверка на существование таблицы - если паралельно будет её дергать из разных потоков выйдет конфуз. Надо жесткое имя идля таблицы и запись туда полей первичного ключа (что-то типа такого


а блокировка не обламывает пользователей которые нолок тягают - риад ункомитед - важно выбрать уровни блоки ровки не допускающие запись в триггерную таблицу


CREATE TABLE [db_TriggerControl] (
	[SPID] [smallint] NOT NULL CONSTRAINT [DF_db_TriggerControl_SPID] DEFAULT (@@spid),
	[ObjID] [int] NOT NULL ,
[DF_db_TriggerControl_rec_sessionID] DEFAULT ([dbo].[db_User_SessionID](null)),
	CONSTRAINT [PK_db_TriggerControl] PRIMARY KEY CLUSTERED 
	(
		[SPID],
		[ObjID]
	) ON [PRIMARY] 
) ON [PRIMARY]
GO

CREATE PROCEDURE db_Trigger_Control
(@TriggerName varchar(<b>256</b>), @Off bit =<b>0</b>)
AS
SET NOCOUNT ON
if @Off=<b>1</b>
	insert dbo.db_TriggerControl(ObjID) Values(OBJECT_ID(@TriggerName))
else
	delete dbo.db_TriggerControl WHERE SPID=@@SPID AND ObjID=OBJECT_ID(@TriggerName)

RETURN 


CREATE TRIGGER dbo.[Cards_Logger]
ON dbo.Cards FOR UPDATE, DELETE
AS

if exists(select * FROM dbo.db_TriggerControl WHERE SPID=@@SPID AND ObjID=@@PROCID) RETURN
....


CREATE PROCEDURE X
AS
SET NOCOUNT ON 
SET XACT_ABORT ON


begin transaction

exec dbo.db_Trigger_Control 'Numbers_Trigger_CheckClosedDrawing', <b>1</b>
exec dbo.db_Trigger_Control 'Numbers_Trigger_CheckLockedIssue', <b>1</b>

....
exec dbo.db_Trigger_Control 'Numbers_Trigger_CheckClosedDrawing'
exec dbo.db_Trigger_Control 'Numbers_Trigger_CheckLockedIssue'


commit transaction

RETURN <b>0</b>