捕获存储过程的参数和值

时间:2015-01-22 11:47:28

标签: sql sql-server tsql sql-server-2008-r2

有没有办法在不对其进行硬编码的情况下捕获另一个SP中的存储过程的参数和值?

例如:

CREATE PROC sp_testProc
    @Par1 INT,
    @Par2 BIT,
    @Par3 NVARCHAR(100)
AS
BEGIN
    SET NOCOUNT ON
    BEGIN TRY
        /*Some payload*/
        SET @Par1 = @Par1 + 1
        SET @Par2 = 0
        SET @Par3 = 'a'
        /*An Error occurs*/
        /*Some more payload*/
    END TRY
    BEGIN CATCH
        /*Capture the procedure parameters and their values*/
    END CATCH
END

到目前为止,我知道如何获取参数,但不知道如何分配它们的当前值。

我的想法是将@@ SPID作为参数传递给过程,然后使用类似SELECT @var=@var+name+' ,' FROM sys.parameters WHERE object_id = @@SPID

的内容

因此,根据这些信息,我可以构建以下字符串:

EXEC sp_testProc @Par1 = , @Par2 = , @Par3 =

我的目标是构建此字符串:

EXEC sp_testProc @Par1 = 1, @Par2 = 0, @Par3 = 'a'

2 个答案:

答案 0 :(得分:0)

好的,所以我想到了如何做到这一点,我写了以下程序:

IF (OBJECT_ID('TheDropper') IS NOT NULL) DROP PROC TheDropper
GO

CREATE PROC TheDropper
    @ProcName NVARCHAR(500)
AS
BEGIN
    DECLARE @DropScript NVARCHAR(MAX)

    IF EXISTS(SELECT object_id FROM sys.sql_modules WHERE object_id = OBJECT_ID(@ProcName))
    SET @DropScript = 'DECLARE @ParamAndDefinition NVARCHAR(MAX)
SET @ParamAndDefinition = ''
EXEC '+@ProcName+' ''+'+CHAR(10)
    ELSE
    RAISERROR('The procedure you supplied does not exist',16,1)

    SELECT @DropScript = @DropScript +
    CASE WHEN b.name IN ('numeric','smallint','real','money','int','float','decimal','bit','bigint') THEN
        ''''+a.name+ ' = '' + ' + 'COALESCE(CONVERT(NVARCHAR,' + a.name + '),''NULL'')+'', ''+'+CHAR(10)
    ELSE ''''+a.name+ ' = '''''' + ' + 'COALESCE(' + a.name + ',''NULL'')+''''''''+'', ''+'+CHAR(10)
    END
    FROM sys.parameters as a
    INNER JOIN sys.types as b ON a.system_type_id = b.system_type_id and b.name <> 'sysname'
    WHERE OBJECT_ID = OBJECT_ID(@ProcName)
    ORDER BY parameter_id

    SET @DropScript = LEFT(@DropScript,LEN(@DropScript)-7)

    PRINT @DropScript
END
GO

EXEC TheDropper 'sp_testProc'

它是如何运作的:

您提供了一个过程名称,您希望将“exec procedure_name @params”语句作为参数提供给TheDropper。

之后,您将获得一个生成的代码,您可以将其粘贴到过程中的TRY块之上,或者在任何代码之前粘贴。

此代码实际上生成一个变量,其中包含过程中的所有参数变量。

如果出现错误,您可以在CATCH块中使用此变量来存储错误日志表,其中包含所有错误消息以及您感兴趣的内容。

答案 1 :(得分:-1)

您可以创建另一个SP和一个日志表来存储sp_testProc的执行日志 并在sp_testProc CATCH模块中调用该SP。让它将sp_testProc中的参数,时间戳,错误原因等存储在该日志表中。