2008-09-29 2 views
16

Ist es möglich, herauszufinden, wer eine Speicherprozedur aufgerufen hat?Finden Sie die aufrufende gespeicherte Prozedur in SQL Server

Zum Beispiel sagen, ich bekomme einen Fehler in proc3. Aus diesem Proc möchte ich wissen, ob es von proc1 oder proc2 aufgerufen wurde.

+6

Sie können den Namen des aktuellen SP kennen, indem Sie 'OBJECT_NAME (@@ PROCID)' erhalten – Gman

Antwort

8

Ich würde einen zusätzlichen Eingangsparameter verwenden, um die Quelle anzugeben, wenn dies für Ihre Logik wichtig ist.

Dies erleichtert auch die Portierung Ihrer Datenbank auf eine andere Plattform, da Sie nicht von einer obskuren plattformabhängigen Funktion abhängig sind.

3

Müssen Sie in Proc3 zur Laufzeit wissen, was den Fehler verursacht hat, oder müssen Sie nur während des Debuggens wissen?

Sie können SQL Server profiler verwenden, wenn Sie es nur während des Debuggens/Überwachens benötigen.

Ansonsten im Jahr 2005 glaube ich nicht, dass Sie die Fähigkeit haben, Spur zu stapeln.

Um es zu umgehen könnten Sie hinzufügen und zusätzliche Parameter zu proc3, @ CallingProc oder so ähnlich.

ODER Sie könnten versuchen, catch-Blöcke proc1 und proc2 hinzufügen.

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

gute Referenz hier: http://searchsqlserver.techtarget.com/tip/1,289483,sid87_gci1189087,00.html

und natürlich immer SQL Server Books Online

SQL Server 2008 hat die Fähigkeit hat, aber durch Verfahren zu debuggen.

2

Sie könnten proc1 und proc2 ihre Namen in proc3 als Parameter übergeben.

Zum Beispiel:

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

Es gibt keine schöne automatische Art und Weise, dies zu tun (leider). Es kommt also wirklich darauf an, wie sehr Sie bereit sind, Ihre Procs neu zu schreiben, um dies zu können.

Wenn Sie über einen Protokollierungsmechanismus verfügen, können Sie möglicherweise das Protokoll lesen und herausfinden, wer Sie angerufen hat.

Zum Beispiel, wenn Sie die Protokollierung implementieren, indem auf eine Tabelle einfügen, zum Beispiel:

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) 

Dies würde nicht für rekursive Aufrufe arbeiten, aber vielleicht kann jemand das Problem beheben?

Verwandte Themen