如何在 SP 执行中系统地获取存储过程 (SP) 参数名称及其值

How to systematically get stored procedure (SP) parameter names and their values INSIDE the SP execution

提问人:Hugo 提问时间:2/7/2023 最后编辑:Hugo 更新时间:2/7/2023 访问量:75

问:

如标题中所述,我正在尝试在执行正确的存储过程时系统地获取存储过程参数计名称及其相应的值。

第一点,即获取存储过程参数名称,使用表 [sys] 很容易。[all_parameters] 和存储过程名称。但是,获取这些参数的实际值是困难的部分,特别是当您不允许使用表 [sys] 时。[dm_exec_input_buffer](作为开发人员,我不被允许阅读此表,因为它是系统管理员表)。

这是我目前拥有的代码,我相信它可以作为模板:

CREATE PROCEDURE [dbo].[get_proc_params_demo]
(
    @number1 int,
    @string1 varchar(50),
    @calendar datetime,
    @number2 int,
    @string2 nvarchar(max)
)
AS
BEGIN
    DECLARE @sql NVARCHAR(MAX);
    DECLARE @ParameterNames NVARCHAR(MAX) = ( SELECT STRING_AGG([Name], ',') FROM [sys].[all_parameters] WHERE OBJECT_ID = OBJECT_ID('[dbo].[get_proc_params_demo]') )
    SET @sql = N'SELECT ' + @ParameterNames;

    DECLARE GetParameterValues CURSOR FOR 
        SELECT DISTINCT [Name] FROM [sys].[all_parameters] WHERE OBJECT_ID = OBJECT_ID('[dbo].[get_proc_params_demo]'); 
        OPEN GetParameterValues;

            DECLARE @param_values NVARCHAR(MAX) = NULL

            DECLARE @StoredProcedureParameter NVARCHAR(MAX)
            FETCH NEXT FROM GetParameterValues INTO @StoredProcedureParameter;

            WHILE @@FETCH_STATUS = 0
            BEGIN
                SET @param_values = 'ISNULL('+@param_values+','')'+@StoredProcedureParameter+','
                EXEC(@param_values)
                FETCH NEXT FROM GetParameterValues INTO @StoredProcedureParameter; 
            END;
        CLOSE GetParameterValues; 
    DEALLOCATE GetParameterValues;

    SET @param_values = LEFT(@param_values, LEN(@param_values) - 1)

    EXEC sp_executesql @sql,@ParameterNames,@param_values;

END


EXEC [dbo].[get_proc_params_demo]
    @number1=42, 
    @string1='is the answer', 
    @calendar='2019-06-19',
    @number2=123456789,
    @string2='another string'

这是我尝试动态获取光标内参数实际值的方法,但它不起作用,到目前为止我一无所知。我知道这是非常初级的,我很高兴听到其他方法。公平地说,我不知道这个问题是否可以在没有系统表的情况下解决,但它会很棒。

编辑:这是获取适用于任何存储过程的泛型代码的尝试。您不想对任何参数名称进行硬编码。您拥有的唯一输入是通过OBJECT_NAME(@@PROCID)

sql-server t-sql 存储过程 参数传递

评论

2赞 Thom A 2/7/2023
这闻起来像一个 XY 问题;你为什么想要/需要这样做?由于参数必须在过程定义中严格定义,因此您已经知道参数的名称是什么,那么为什么需要“动态”地执行此操作呢?
0赞 Hugo 2/7/2023
因为我没有得到参数名称,而是参数传递的值,或者至少这是我的意图:)
1赞 Thom A 2/7/2023
SELECT N'@Number1' AS ParameterName, @Number1 AS ParameterValue;
1赞 Thom A 2/7/2023
“但是,如果以后您确实有另一个您不知道其参数名称的 SP”,您必须在定义过程时命名参数。如果你不知道参数的名称是什么,你只需看一下子句,它们就在那里。ALTER
1赞 Thom A 2/7/2023
所以我回到我最初的评论:“这闻起来像一个 XY 问题;你为什么要/需要这样做?

答: 暂无答案