2010-06-14 2 views
1

Я работаю с триггером вставки в базе данных Sybase. Я знаю, что могу получить доступ к @@ nestlevel, чтобы определить, вызвана ли я непосредственно или в результате другого триггера или процедуры.Определить вызывающего абонента в хранимой процедуре или триггере

Есть ли способ определить, когда уровень гнездования глубже 1, кто выполнил действие, вызывающее срабатывание триггера?

Например, таблица была вставлена ​​непосредственно, была ли она вставлена ​​другим триггером, и если да, то какой.

ответ

1

Насколько я знаю, это невозможно. Лучше всего включить его в качестве параметра в хранимую процедуру (процедуры). Как объясняется here, это также сделает ваш код более переносимым, поскольку любой используемый метод, скорее всего, будет опираться на какой-то конкретный вызов для конкретной базы данных. Ссылка была специально для SQL Server 2005, а не Sybase, но я думаю, что вы в значительной степени находитесь в одной лодке.

+0

Вот чего я боялся. Я посмотрю, какой другой маршрут я могу найти, чтобы сделать это определение. –

0

Я не тестировал это сам, но если предположить, что вы используете Sybase ASE 15.03 или новее, включите свои мониторинговые таблицы monProcessStatement и monSysStatement и соответствующие разрешения, позволяющие им получить доступ с вашего триггера, который вы могли бы попробовать. .

declare @parent_proc_id int 
if @@nestlevel > 1 
begin 

    create table #temp_parent_proc (
    procId int, 
    nestLevel int, 
    contextId int 
    ) 
    insert into #temp_parent_proc 
    select mss.ProcedureID, 
      mss.ProcNestLevel, 
      mss.ContextID 
    from monSysStatement mss 
    join monProcessStatement mps 
     on mss.KPID = mps.KPID 
     and mss.BatchID = mps.BatchID 
     and mss.SPID = mps.SPID 
    where mps.ProcedureID [email protected]@procid 
     and mps.SPID = @@spid 

    select @parent_proc_id = (select tpp.procId 
       from #temp_parent_proc tpp, 
        #temp_parent_proc2 tpp2 
       where tpp.nestLevel = tpp2.nestLevel-1 
        and tpp.contextId < tpp2.contextId 
        and tpp2.procId = @@procid 
        and tpp2.nestLevel = @@nestlevel 
       group by tpp.procId, tpp.contextId 
       having tpp.contextId = max(tpp.contextId)) 

    drop table #temp_parent_proc 
end 

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

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

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

в каждом прок, что может вызвать это ...

create table #trigger_parent (proc_id int) 
insert into #trigger_parent @@procid 

затем в триггер таблицы темп будет доступен ...

if object_id('#trigger_parent') is not null 
    set @parent_proc = select l proc_id from #trigger_parent 

вы будете знать, что было вызвано из другой Proc.

Проблема в том, что это не просто работает. Вы должны обеспечить настройку таблицы temp. Вы можете продолжить проверку, чтобы найти случаи, когда нет #trigger_parent, но уровень вложенности> 1 и объединить аналогичный запрос с таблицами мониторинга, как указано выше, чтобы найти потенциальных кандидатов, которые необходимо будет обновить.

Смежные вопросы