找出SQL Server中的调用存储过程

时间:2020-03-06 14:52:01  来源:igfitidea点击:

是否可以找出谁调用了存储过程?

例如,假设我在" proc3"中遇到错误。从该proc中,我想知道它是由proc1还是proc2调用的。

解决方案

如果这对逻辑很重要,我将使用一个额外的输入参数来指定源。

这也将使我们更容易将数据库移植到另一个平台,因为我们不依赖于某些晦涩的平台相关功能。

我们是否需要在运行时在proc3中知道导致错误的原因,还是只需要在调试时知道?

如果仅在调试/监视过程中需要使用SQL Server Profiler,则可以使用它。

否则,在2005年,我不相信我们具有堆栈跟踪的功能。

要解决此问题,我们可以在proc3,@ CallingProc或者类似的东西中添加额外的参数。

或者,我们可以将尝试捕获块添加到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联机丛书

SQL Server 2008确实具有通过过程进行调试的能力。

我们可以让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

没有很好的自动方法来执行此操作(alas)。因此,这实际上取决于我们准备(重新)编写proc程序的数量,以便能够执行此操作。

如果我们有日志记录机制,则可以读取日志并确定谁打了我们。

例如,如果通过插入表来实现日志记录,例如:

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 )

这不适用于递归调用,但是也许有人可以解决此问题?