2010-06-14 6 views
1

Sybase 데이터베이스 내에서 삽입 트리거로 작업하고 있습니다. @@ nestlevel에 액세스하여 직접 또는 다른 트리거 또는 프로 시저의 결과로 호출되는지 여부를 확인할 수 있습니다.저장된 proc 또는 트리거 내의 호출자 결정

중첩 수준이 1보다 클 때 누가 트리거를 발생시키는 동작을 수행했는지 확인할 방법이 있습니까?

예를 들어 테이블을 직접 삽입했는지, 다른 트리거에 삽입했는지 등이 있습니다.

답변

1

내가 아는 한, 이것은 불가능합니다. 가장 좋은 방법은 저장 프로 시저 (들)에 대한 매개 변수로 그것을 포함하는 것입니다. 설명한대로 here,이 방법은 사용되는 모든 메서드가 특정 데이터베이스 관련 호출에 의존하기 때문에 코드를 더 이식성있게 만듭니다. 거기 링크는 Sybase가 아닌 SQL Server 2005에 대한 것이었지만, 당신은 거의 같은 배에 있다고 생각합니다.

+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는 역사적인 테이블이며 액세스하는 모든 프로세스에 개별 rown을 한 번만 반환하도록 보장됩니다.

모니터링 테이블에 액세스 할 수있는 권한이 없거나이를 설정하려는 경우이를 @@ 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.

이 문제는 '효과가 없다'는 것입니다. 임시 테이블 설정을 시행해야합니다. #trigger_parent가 없지만 중첩 수준이 1보다 큰 경우를 찾으려면 위와 같이 모니터링 테이블에 유사한 쿼리를 결합하여 업데이트해야 할 후보를 찾습니다.

관련 문제