有没有办法在不对其进行硬编码的情况下捕获另一个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'
答案 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
中的参数,时间戳,错误原因等存储在该日志表中。