Sql 存储过程获取参数列表和当前值

Sql 存储过程获取参数列表和当前值,sql,tsql,sql-server-2005,Sql,Tsql,Sql Server 2005,不知道如何实现,但我需要一种方法来获取存储过程的当前参数列表以及它们传入的值。这段代码将在存储过程本身中执行 我知道我可以使用sys.parameters来获取参数名,但是如何获取实际值呢 我需要做的是制作一个 @param_name1=@value1,@param_name2=@value2,...,@param_namen=@valuen 我曾经尝试过使用动态sql,但没有太多的乐趣 有什么想法吗 编辑: 目前,我正在逐个检查所有参数以构建字符串。但是我想要一个更好的方法,因为有很多参数。

不知道如何实现,但我需要一种方法来获取存储过程的当前参数列表以及它们传入的值。这段代码将在存储过程本身中执行

我知道我可以使用sys.parameters来获取参数名,但是如何获取实际值呢

我需要做的是制作一个

@param_name1=@value1,@param_name2=@value2,...,@param_namen=@valuen
我曾经尝试过使用动态sql,但没有太多的乐趣

有什么想法吗

编辑:

目前,我正在逐个检查所有参数以构建字符串。但是我想要一个更好的方法,因为有很多参数。和incase参数稍后添加,但生成字符串的代码未更新


我尝试使用动态sql,但放弃了,因为sp_executesql sp要求将参数传递给它…

您声明“此代码将在存储过程本身中执行”。因此,假设您在该过程中,您已经知道参数名称,因为在创建过程时必须声明它们。只需选择并将名称放入文本字段中

ALTER PROCEDURE procname
(
     @param1 NVARCHAR(255)
    ,@param2 INT
    ...
)

SELECT [Parameters] = '@param1=' + @param1 
                    + ',@param2=' + CONVERT(NVARCHAR(MAX),@param2)...
CONVERT是非char数据类型的一个示例

使现代化 您需要创建一个指向自身的链接服务器来使用OPENQUERY函数

USE [master]
GO

/****** Object:  LinkedServer [.]    Script Date: 04/03/2013 16:22:13 ******/
EXEC master.dbo.sp_addlinkedserver @server = N'.', @srvproduct=N'', @provider=N'SQLNCLI', @datasrc=N'.', @provstr=N'Integrated Security=SSPI'
 /* For security reasons the linked server remote logins password is changed with ######## */
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'.',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL

GO
现在,您可以执行类似于此游标的操作来获取每个参数名称,然后在OPENQUERY中使用动态sql来获取值:

DECLARE curParms CURSOR FOR
SELECT
    name
FROM sys.parameters
WHERE OBJECT_ID = OBJECT_ID('schema.procedurename')
ORDER BY parameter_id
OPEN curParms
FETCH curParms INTO @parmName
WHILE @@FETCH_STATUS <> -1
BEGIN
    SELECT @parmName + '=' + (SELECT * FROM OPENQUERY('linkedservername','SELECT ' + @parmName))
    FETCH curParms INTO @parmName
END
CLOSE curParms
DEALLOCATE curParms

您声明“此代码将在存储过程本身中执行”。因此,假设您在该过程中,您已经知道参数名称,因为在创建过程时必须声明它们。只需选择并将名称放入文本字段中

ALTER PROCEDURE procname
(
     @param1 NVARCHAR(255)
    ,@param2 INT
    ...
)

SELECT [Parameters] = '@param1=' + @param1 
                    + ',@param2=' + CONVERT(NVARCHAR(MAX),@param2)...
CONVERT是非char数据类型的一个示例

使现代化 您需要创建一个指向自身的链接服务器来使用OPENQUERY函数

USE [master]
GO

/****** Object:  LinkedServer [.]    Script Date: 04/03/2013 16:22:13 ******/
EXEC master.dbo.sp_addlinkedserver @server = N'.', @srvproduct=N'', @provider=N'SQLNCLI', @datasrc=N'.', @provstr=N'Integrated Security=SSPI'
 /* For security reasons the linked server remote logins password is changed with ######## */
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'.',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL

GO
现在,您可以执行类似于此游标的操作来获取每个参数名称,然后在OPENQUERY中使用动态sql来获取值:

DECLARE curParms CURSOR FOR
SELECT
    name
FROM sys.parameters
WHERE OBJECT_ID = OBJECT_ID('schema.procedurename')
ORDER BY parameter_id
OPEN curParms
FETCH curParms INTO @parmName
WHILE @@FETCH_STATUS <> -1
BEGIN
    SELECT @parmName + '=' + (SELECT * FROM OPENQUERY('linkedservername','SELECT ' + @parmName))
    FETCH curParms INTO @parmName
END
CLOSE curParms
DEALLOCATE curParms

自SQL Server 2014以来,我们拥有sys.dm_exec_input_buffer,它是一个表值函数,具有一个输出列event_info,提供包含参数的完整执行语句

我们可以解析sys.dm_exec_input_buffer中的参数值,从sys.parameters中获取参数名称,并将它们连接在一起以获得所需的字符串

例如:

create procedure [dbo].[get_proc_params_demo]
(
    @number1 int,
    @string1 varchar(50),
    @calendar datetime,
    @number2 int,
    @string2 nvarchar(max)
)
as
begin

-- get the full execution statement
declare @statement nvarchar(max)
select  @statement = event_info
from    sys.dm_exec_input_buffer(@@spid, current_request_id())

-- parse param values from the statement
declare @proc_name varchar(128) = object_name(@@procid)
declare @param_idx int = charindex(@proc_name, @statement) + len(@proc_name)
declare @param_len int = len(@statement) - @param_idx 
declare @params nvarchar(max) = right(@statement, @param_len)

-- create param values table
select  value, row_number() over (order by current_timestamp) seq
into    #params
from    string_split(@params, ',')

-- get final string
declare @final nvarchar(max)
select  @final = isnull(@final + ',','') + p1.name + '=' + ltrim(p2.value)
from    sys.parameters p1
        left join #params p2 on p2.seq = parameter_id
where   object_id = @@procid

select  @final params
end
要测试它,请执行以下操作:

exec get_proc_params_demo 42, 'is the answer', '2019-06-19', 123456789, 'another string'
返回所需的字符串:

@number1=42,@string1='is the answer',@calendar='2019-06-19',@number2=123456789,@string2='another string'

我有一些类似的东西包装成UDF。我使用它来记录捕获块中的错误。

自SQL Server 2014以来,我们有sys.dm_exec_input_buffer,它是一个表值函数,具有一个输出列事件信息,提供包括参数在内的完整执行语句

我们可以解析sys.dm_exec_input_buffer中的参数值,从sys.parameters中获取参数名称,并将它们连接在一起以获得所需的字符串

例如:

create procedure [dbo].[get_proc_params_demo]
(
    @number1 int,
    @string1 varchar(50),
    @calendar datetime,
    @number2 int,
    @string2 nvarchar(max)
)
as
begin

-- get the full execution statement
declare @statement nvarchar(max)
select  @statement = event_info
from    sys.dm_exec_input_buffer(@@spid, current_request_id())

-- parse param values from the statement
declare @proc_name varchar(128) = object_name(@@procid)
declare @param_idx int = charindex(@proc_name, @statement) + len(@proc_name)
declare @param_len int = len(@statement) - @param_idx 
declare @params nvarchar(max) = right(@statement, @param_len)

-- create param values table
select  value, row_number() over (order by current_timestamp) seq
into    #params
from    string_split(@params, ',')

-- get final string
declare @final nvarchar(max)
select  @final = isnull(@final + ',','') + p1.name + '=' + ltrim(p2.value)
from    sys.parameters p1
        left join #params p2 on p2.seq = parameter_id
where   object_id = @@procid

select  @final params
end
要测试它,请执行以下操作:

exec get_proc_params_demo 42, 'is the answer', '2019-06-19', 123456789, 'another string'
返回所需的字符串:

@number1=42,@string1='is the answer',@calendar='2019-06-19',@number2=123456789,@string2='another string'

我有一些类似的东西包装成UDF。我使用它来记录捕获块中的错误。

有趣但奇怪的要求。您能告诉我们您尝试了什么吗?如果您想在存储过程中记录来自catch块的完整错误数据,请不要这么奇怪。这是一个有趣但奇怪的要求。您能告诉我们您尝试了什么吗?如果您想在存储过程中记录捕获块中的完整错误数据,请不要这么奇怪。对不起。我忘了添加一些东西,我已经在使用手动检查参数的方法。但是sp有很多参数,所以我想用一种不那么痛苦的方式来做。对不起。我忘了添加一些东西,我已经在使用手动检查参数的方法。但是sp有很多参数,所以我想要一种不那么痛苦的方法。