2008-09-29 71 views
16

是否有可能找出誰調用存儲過程?找出SQL Server中的調用存儲過程

例如,假設我在proc3中遇到錯誤。從那個proc中我想知道它是否被proc1proc2調用。

+6

您可以通過獲取`OBJECT_NAME'(@@ PROCID)來知道當前SP的名稱` – Gman 2010-05-08 15:39:11

回答

8

我會使用額外的輸入參數來指定源,如果這對您的邏輯很重要。

由於不依賴於某些不太依賴平臺的函數,因此這也將使您更輕鬆地將數據庫移植到另一個平臺。

3

您是否需要在運行時知道proc3中導致錯誤的原因,還是隻需要在調試的時候知道?

如果您只需在調試/監控期間執行此操作,則可以使用SQL Server profiler

否則在2005年我不相信你有能力堆棧跟蹤。

要解決它,你可以添加和額外的參數proc3,@CallingProc或類似的東西。

或者你可以添加try catch塊到proc1和proc2。

BEGIN TRY 
EXEC Proc3 
END TRY 
BEGIN CATCH 
SELECT 'Error Caught' 
SELECT 
    ERROR_PROCEDURE() 
END CATCH 

很好的參考這裏:http://searchsqlserver.techtarget.com/tip/1,289483,sid87_gci1189087,00.html

當然,總是SQL Server Books Online

SQL Server 2008中確實有通過但程序調試的能力。

2

您可以將proc1和proc2作爲參數傳入proc3。

例如:

CREATE PROCEDURE proc3 
    @Caller nvarchar(128) -- Name of calling proc. 
    AS 
    BEGIN 
    -- Produce error message that includes caller's name. 
    RAISERROR ('Caller was %s.', 16,10, @Caller); 
    END 
    GO 

    CREATE PROCEDURE proc1 
    AS 
    BEGIN 
    -- Get the name of this proc. 
    DECLARE @ProcName nvarchar(128); 
    SET @ProcName = OBJECT_NAME(@@PROCID); 
    -- Pass it to proc3. 
    EXEC proc3 @ProcName 
    END 
    GO 

    CREATE PROCEDURE proc2 
    AS 
    BEGIN 
    -- Get the name of this proc. 
    DECLARE @ProcName nvarchar(128); 
    SET @ProcName = OBJECT_NAME(@@PROCID); 
    -- Pass it to proc3. 
    EXEC proc3 @ProcName 
    END 
    GO 
3

沒有很好的自動方式做到這一點(唉)。所以這取決於你準備好多少(重新)編寫你的過程以便能夠做到這一點。

如果您有一個日誌記錄機制,您可能能夠讀取日誌並計算出誰叫你。

例如,如果您通過插入到表,例如實現日誌記錄:

CREATE TABLE Log 
(timestamp dattime, 
spid  int, 
procname varchar(255), 
message varchar(255)) 

... text of proc ... 
INSERT INTO Log 
SELECT get_date(), @@spid, @currentproc, 'doing something' 
-- you have to define @currentproc in each proc 

-- get name of caller 
SELECT @caller = procname 
FROM Log 
WHERE spid = @@spid 
AND timestamp = (SELECT max(timestamp) 
        FROM Log 
        WHERE timestamp < get_date() 
        AND procname != @currentproc) 

這不是遞歸調用工作,但也許有人能解決這個問題?