I’m preparing template for procedures with different number of arguments that process data. Long story short I’d like to return a HTML table as an output for TRY CATCH block.
Very simplified template:
CREATE PROCEDURE [dbo].[_Test]
@VALUE1 nvarchar(10),
@VALUE2 nvarchar(30),
--...
@VALUEN nvarchar(MAX)
AS
DECLARE @DATAINPUT NVARCHAR(MAX) = ''
/* Code */
SELECT @DATAINPUT
Expected value from running _Test '123', '246', 'NN'
:
@DATAINPUT = '<tr><td>@VALUE1</td><td>123</td></tr>
<tr><td>@VALUE2</td><td>246</td></tr>
<tr><td>@VALUEN</td><td>NN</td></tr>'
Screen: https://ibb.co/2vVTXt9
What I tried:
Creating a table manually in each procedure - it works for now with 5 procedures, but it will be difficult to maintain in 40+ when other people will work with it
SELECT * FROM sys.parameters INNER JOIN sys.procedures ON parameters.object_id = procedures.object_id WHERE procedures.name = OBJECT_NAME(@@PROCID)
- returns list of argument names, but I don't how to retrieve its values
select * from sys.dm_exec_input_buffer(@@spid, current_request_id())
gives me raw data dump, but it is difficult to format
Is there something like Pyhonian argv?
Answering my own question:
-- 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 @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)
DECLARE @Table table(value varchar(max), seq int)
INSERT INTO @Table select value, row_number() OVER (order by current_timestamp) seq from string_split(@params, ',')
UPDATE @Table SET value = REPLACE(value, '''', '')
DECLARE @Output nvarchar(max)
SELECT @Output = isnull(@Output + '','') + IIF(p2.seq % 2 = 1, '<tr class="odd">', '<tr>')+'<td>' + p1.name + '</td><td>'+convert(varchar(512),ISNULL(ltrim(p2.value) , 'NULL')) + '</td></tr>'
FROM sys.parameters p1 left join @Table p2 on p2.seq = parameter_id where object_id = @@procid
Disclaimer: This is partially code from another user's answer that I'd like to give recognition, but I can't find the thread. Anyway - thank You anonymous coder.