Selecting with quotes with ISNULL - sql

I am trying to build a dynamic query in sybase like:
SELECT #v_query = #v_query + " tech= "+ ISNULL(''''+#stat+'''',"tech")
When I pass #stat as NULL, I get '' as output but expected output is tech which is wrong
If I pass#stat as NACK, it should return 'NACK' which works as expected
Thanks for any suggestions on how to achieve this

To be honest, you probably want this:
SELECT #v_query = #v_query +
(CASE WHEN #stat IS NULL THEN '1=1'
ELSE 'tech = ''' + #stat + ''''
END)
Don't use tech = tech as a no-op (it doesn't work for NULLs). Instead, just remove the comparison.

remove the '' and retry
declare #SQL_TXT varchar(100)
declare #stat varchar(100)
begin
select #stat= null
SELECT #SQL_TXT=#SQL_TXT + ' tech =' + ISNULL(#stat,'tech')
print #SQL_TXT
end
print tech =tech
edit you can do it like this
declare #SQL_TXT varchar(100)
declare #stat varchar(100)
begin
select #stat= null
SELECT #SQL_TXT=#SQL_TXT + ' tech = ''' + ISNULL(#stat,'tech') +''''
print #SQL_TXT
end
it seems adding quotes in null function give null value , can you add quotes originally to the variable as alternative ?
declare #SQL_TXT varchar(100)
declare #stat varchar(100)
begin
select #stat= 'SAMPLE'
select #stat= ''''+#stat+''''
SELECT #SQL_TXT=#SQL_TXT + ' tech = ' + ISNULL(#stat,'tech')
print #SQL_TXT
end

Related

procedure with multi where statement

have the following table
table TableAB(
ColumnA int,
ColumnB nvarchar(50)
)
i need to create a procedure which returns ColumnA, ColumnB and takes two parameters (in real life count of parameters more then 20). All searches should work with wildcard "%".
procedure has input parameters
#ColumnA int,
#ColumnB nvarchar(50)
i have two approaches
1.
select ColumnA,ColumnB from TableAB
where
ColumnA like
case #ColumnA
when #ColumnA NULL then ColumnA
else '%' + CONVERT(varchar(10),#ColumnA)+'%'
end
and
ColumnB like
case #ColumnB
when #ColumnB NULL then ColumnB
else '%' + ColumnB +'%'
end
2.
DECLARE #TabWhereConditions TABLE(Id INT IDENTITY(1,1), Condition VARCHAR(MAX))
...
SET #ParamDefenition = '#pColumnA int, #pColumnB nvarchar(50)'
IF(NOT #ColumnA IS NULL)
BEGIN
INSERT INTO #TabWhereConditions(Condition)
VALUES('ColumnA like ' + '''%' + CONVERT(varchar(10),#ColumnA) + '%''')
END
IF(NOT #ColumnB IS NULL)
BEGIN
INSERT INTO #TabWhereConditions(Condition)
VALUES('ColumnA like ' + '''%' + #ColumnB + '%''')
END
DECLARE CondCursor CURSOR FOR
SELECT Condition FROM #TabWhereConditions
OPEN CondCursor
SET #WhereString = ''
FETCH NEXT FROM CondCursor INTO #WhereCondition
WHILE ##FETCH_STATUS = 0
BEGIN
SET #WhereString = #WhereString + #WhereCondition + ' AND '
FETCH NEXT FROM CondCursor INTO #WhereCondition
END
CLOSE CondCursor
DEALLOCATE CondCursor
SET #WhereString = SUBSTRING(#WhereString,1, LEN(#WhereString)-4)
SET #SqlCommand = '
SELECT
ColumnA,
ColumnB
FROM TableAB
WHERE ' + #WhereString
EXECUTE sp_executesql #SqlCommand, #ParamDefenition,
#pColumnA = #ColumnA,
#pColumnB = #ColumnB,
Which approach is better ? first or second , or your suggestion
Note: i need solution for situation when procedure can take from 1 up to 20 parameters, each call can get different number of parameters
I believe you want to use something along these lines
select ColumnA,ColumnB from TableAB
where (#columnA is null or ColumnA like '%'+CONVERT(varchar(10),#ColumnA)+'%' and
(#columnB is null or ColumnB like '%'+CONVERT(varchar(10),#ColumnB)+'%'
As noted in this Aaron Bertrand blog post, it is a good idea to make it dynamic T-SQL. Therefore, you may use sys.sp_executesql to run the above statement.
You can create execute stored procedure or query as shown below in case of multiple where condition.
CREATE PROCEDURE [dbo].[SearchUserPermission]
#UserId bigint,
#ParentModuleId Bigint
AS
BEGIN
SET NOCOUNT ON
Declare #strSQLQuery AS VARCHAR(3000) =null;
Declare #strCriteria AS VARCHAR(1000)=null;
BEGIN
SET #strCriteria = ' WHERE 1=1'
IF(#UserId > 0)
BEGIN
SET #strCriteria=#strCriteria + ' AND UserId =' + CONVERT(VARCHAR,#UserId)
END
IF( #ParentModuleId > 0)
BEGIN
SET #strCriteria=#strCriteria + ' AND ParentModuleId=' + Convert(varchar,#ParentModuleId)
END
SET #strSQLQuery ='Select * From (
SELECT
*
FROM Module_Mst
LEFT outer join UserPermissions_Mst
on UserPermissions_Mst.ModuleId=Module_Mst.moduleId AND Module_Mst.IsVisible=1
' +#strCriteria + ' ) AS TempUserPermission'
if (LEN(#strCriteria) > 0 )
BEGIN
SET #strSQLQuery = #strSQLQuery + ' ORDER By OrderNo '
END
END
--Print(#strSQLQuery)
EXEC (#strSQLQuery)
END
Hope this will help you.

How to set dynamic query value to a variable in SQL Server stored procedure with parameters?

I want to set a variable to the value generated using the dynamic query outside the query.
I tried the sp_executesql concept, but this does not help me because I am using the parameter value in the dynamic query.
Are there any possibilities to fix this issue?
CREATE PROCEDURE [dbo].[SP_test_proc]
#id int = null,
#deptId int = null
As
BEGIN
DECLARE #Condition VARCHAR(MAX),#Query NVARCHAR(MAX)
SET #Condition= 'Where Id = '#id + case when #deptid is null then '' else #deptid End
SET #Query = 'Declare #Name varchar(100)
Set #Name = Select name from student '+ #Condition
SELECT *
FROM personal
WHERE name = #Name
END
Use output parameter in dynamic sql as shown here
Also see this
Try this :
DECLARE #Condition VARCHAR(MAX),#Query NVARCHAR(MAX)
SET #Condition= 'Where Id = '#id + case when #deptid is null then '' else #deptid End
Declare #Name varchar(100),#nameval varchar(100),#paramdef varchar(100)
SET #Query = '
Select #Name = name from student '+ #Condition
set #paramdef=N'#Name varhcar(20) OUTPUT'
execute sp_executesql #Query,#paramdef,#Name=#nameval Output
SELECT *
FROM personal
WHERE name = #nameval
Hope this code will work for you.
CREATE PROCEDURE [dbo].[SP_test_proc]
#id int = null,
#deptId int = null
As
BEGIN
DECLARE #Condition VARCHAR(MAX),#Query NVARCHAR(MAX)
SET #Condition= 'Where Id = ' + #id + ' And [Deptid] = ' + ISNULL(#deptid,'')
SET #Query = 'SELECT * FROM personal WHERE name IN ( SELECT name FROM student ' + #Condition + ')'
EXEC #Query
END
[Deptid] is not sure I don't know column name

Dynamically selecting and grouping by specified parameters in SQL Server

I am trying to create optional parameters in a stored process in which I group by the parameters under certain conditions.
For example:
SELECT
TP.ProductID,
case
when #passangers='Y' then (TP.Passangersgroup)
when #fareclass='Y' then (TP.Fareclass)
when #ispriorbooking='Y' then (TP.IsPriorBooking)
end
INTO ##B
FROM ##A TP
GROUP BY
TP.ProductID,
case
when #passangers='Y' then (TP.Passangersgroup)
when #fareclass='Y' then (TP.Fareclass)
when #ispriorbooking='Y' then (TP.IsPriorBooking)
end
In this case, I would be able to select 'Y' for any of the 3 parameters, and I would want to add them to select statement and group by.
Any ideas?
You need to do this with dynamic SQL; something like:
declare #sql varchar(max) = 'SELECT
TP.ProductID, ' +
case when #passangers='Y' then 'TP.Passangersgroup'
when #fareclass='Y' then 'TP.Fareclass'
when #ispriorbooking='Y' then 'TP.IsPriorBooking'
else ''
end
+ ' INTO ##B
FROM ##A TP'
--ETC
Exec(#sql)
If you want to add up to all three columns, you need three case statements:
declare #sql varchar(max) = 'SELECT
TP.ProductID, ' +
case when #passangers='Y' then 'TP.Passangersgroup' else '' end
+ case when #fareclass='Y' then 'TP.Fareclass' else '' end
--ETC.
+ ' INTO ##B
FROM ##A TP'
Dynamic SQL will be the best bet, but I would figure out the column you want and then pass in the one column as a variable. Less likely to suffer SQL injection and more readable.
DECLARE #passangers CHAR(1), #fareclass CHAR(1), #ispriorbooking CHAR(1)
SET #passangers='Y'
DECLARE #SQLCMD NVARCHAR(MAX), #YValue NVARCHAR(1000)
--set the select and group by field
SELECT #YValue=
case
when #passangers='Y' then N'TP.Passangersgroup'
when #fareclass='Y' then N'TP.Fareclass'
when #ispriorbooking='Y' then N'TP.IsPriorBooking'
else NULL
end
IF #YValue IS NOT NULL
BEGIN
SET #SQLCMD=N'
SELECT
TP.ProductID,'+#YValue+'
INTO ##B
FROM ##A TP
GROUP BY
TP.ProductID, '+#YValue
PRINT #SQLCMD
--EXEC sp_executesql #SQLCMD
END
ELSE
PRINT 'INVALID PARAMETER PASSED IN'
You have to use dynamic sql but case statement mentioned in Steve Mangiameli code will not work in case when more than one column is selected as 'Y'. The below code will be working fine for multiple columns selected as 'Y'-
create procedure proc1
#passangers varchar(100) = null,
#fareclass varchar(100) = null,
#ispriorbooking varchar(100) = null
as
begin
declare #sql nvarchar(100)
declare #var varchar(100)
if #passangers = 'y'
set #var = tp.Passangersgroup + ', '
if #fareclass = 'y'
set #var = #var + TP.Fareclass + ', '
if #ispriorbooking = 'y'
set #var = #var + TP.IsPriorBooking
set #sql = 'select ' + #var + ' into ##b from ##a as TP group by ' + #var + 'option(recomplile)'
exec sp_executesql #sql
end

Trailing spaces not being removed even after using appropriate functions

I am simply trying to remove trailing space from string variable.
Below is the sample code:
Set #Tree_ID='1.23 '
Set #Tree_ID = LTRIM(RTRIM(#Tree_ID))
But to my surprise , leading space is not getting removed. I did same separately and it worked fine. But somehow it is not trimming space inside my stored procedure.
Below is my stored procedure
ALTER procedure [dbo].[SP_Web_Calculate_Interest] -- 23,1,'2014-04-01','2015-03-19','','kiran.divate','COMP7',1
#FGRPNo int,
#Company_No int,
#From_Date datetime,
#To_Date datetime,
#CC_TID varchar(200),
#UserName varChar(100),
#HostName varChar(100),
#DispMode int=1
As
Begin
Declare #Tree_ID char(30)
Declare #TempTable Table(Group_No smallint,Company_No smallint,Group_Name char(50),Tree_ID varchar(30),Is_Fixed char(1))
If #FGRPNo > 0
Begin
if #DispMode =1
Begin
Insert into #TempTable(Group_No ,Company_No,Group_Name ,Tree_ID ,Is_Fixed )
select distinct g.Group_No,g.Company_No, g.group_name,g.Tree_ID,g.Is_Fixed
from account_group G inner join Account a
on a.Tree_ID like '%.' + ltrim(rtrim(CAST(g.Group_No as varchar(10)))) + '.%'
where (a.company_no=#Company_No and a.account_no
in ( select Account_No
from Interest_Percent
where Company_No=#Company_No and Int_Rate >0 and effective_Date between #From_Date and #To_Date)
and g.group_no=#FGRPNo
and (g.company_no = 0 or g.company_no=#Company_No))
order by g.group_no
End
Else
Begin
Insert into #TempTable(Group_No ,Company_No,Group_Name ,Tree_ID ,Is_Fixed )
select distinct g.Group_No,g.Company_No, g.group_name,g.Tree_ID,g.Is_Fixed
from account_group G inner join Account a
on a.Tree_ID like '%.' + ltrim(rtrim(CAST(g.Group_No as varchar(10)))) + '.%'
where (a.company_no=#Company_No and a.account_no
in ( select Account_No
from Interest_Percent
where Company_No=#Company_No and Int_Rate >0 and effective_Date between #From_Date and #To_Date)
and g.Parent_group_no= #FGRPNo
and (g.company_no = 0 or g.company_no=#Company_No))
order by g.group_no
End
End
Else
Begin
Insert into #TempTable(Group_No ,Company_No,Group_Name ,Tree_ID ,Is_Fixed )
select distinct g.Group_No,g.Company_No, g.group_name,g.Tree_ID,g.Is_Fixed
from account_group G inner join Account a
on a.Tree_ID like '%.' + ltrim(rtrim(CAST(g.Group_No as varchar(10)))) + '.%'
where (a.company_no=#Company_No and a.account_no
in ( select Account_No
from Interest_Percent
where Company_No=#Company_No and Int_Rate >0 and effective_Date between #From_Date and #To_Date)
and (g.company_no = 0 or g.company_no=#Company_No))
order by g.group_no
End
Declare #CompNo int
Declare cur_temp SCROLL CURSOR FOR
Select Group_No ,Tree_ID,Company_No from #TempTable
FOR READ ONLY
OPEN cur_temp
FETCH first FROM cur_temp into #FGRPNo ,#Tree_ID,#CompNo
WHILE (##fetch_status <> -1)
Begin
if #CompNo =0
Begin
Set #Tree_ID = Convert(varchar(10),#Company_No) + '.' + #Tree_ID
end
Set #Tree_ID = REPLACE(#Tree_ID, ' ', '')
Exec SP_Calculate_Interest #FGRPNo,#Company_No,#Tree_ID,#From_Date,#To_Date,#CC_TID,#UserName,#HostName
End
Close cur_Temp
deallocate cur_Temp
--Exec SP_Web_GetAccountInterest #FGRPNo,#Tree_ID ,#UserName ,#HostName ,#Company_no ,'G',#CC_TID ,#BalanceAmount output ,#InterestAmount output
--Select #BalanceAmount
--Select #InterestAmount
if #DispMode >1
Begin
Declare #TempTable2 Table(Account_No int,Account_Name char(50),Tree_ID char(30),parent_group_no smallint)
Insert into #TempTable2(Account_No ,Account_Name,Tree_ID ,parent_group_no )
select Distinct A.Account_No, A.Account_Name, A.Tree_ID, A.parent_group_no
from account A Where A.parent_group_no = #FGRPNo and A.company_no=#Company_No and a.account_no
in (select Account_No from Interest_Percent
where Company_No=#Company_No and Int_Rate >0
and effective_Date between #From_Date and #To_Date) order by A.Account_No
Declare #Acc_No int
Declare cur_temp2 SCROLL CURSOR FOR
Select Account_No ,Tree_ID from #TempTable2
FOR READ ONLY
OPEN cur_temp2
FETCH first FROM cur_temp2 into #Acc_No ,#Tree_ID
WHILE (##fetch_status <> -1)
Begin
Set #Tree_ID = REPLACE(#Tree_ID, ' ', '')
Exec SP_Calculate_Interest #Acc_No,#Company_No,#Tree_ID,#From_Date,#To_Date,#CC_TID,#UserName,#HostName
End
Close cur_Temp2
deallocate cur_Temp2
End
End
Below part of code :
if #CompNo =0
Begin
Set #Tree_ID = Convert(varchar(10),#Company_No) + '.' + #Tree_ID
end
Set #Tree_ID = REPLACE(#Tree_ID, ' ', '')
Value of #Tree_ID at Set #Tree_ID = Convert(varchar(10),#Company_No) + '.' + #Tree_ID is 1.23 with trailing spaces, so should it not remove space right after if statement ends when I do Set #Tree_ID = REPLACE(#Tree_ID, ' ', '')
But when I added watch in debugger, it is still same!!
#Tree_ID is a char(30). So always 30 characters no matter how you trim or replace spaces.
You could try a varchar instead. Declare #Tree_ID varchar(30)
EDIT: The problem is that #Tree_ID is using datatype CHAR(30)!
CHAR always fills with enough space to use its full length. If you don't want trailing spaces you need to use VARCHAR.
declare #Tree_ID varchar(100)
Set #Tree_ID='1.23 '
Set #Tree_ID = LTRIM(RTRIM(#Tree_ID))
print '|'+#Tree_ID+'|'
Result : |1.23|
It works just fine, but as a advice. Be carefull for tab spaces or enter spaces ( for example when the text was taken from a Memo )
See this ex with TAB space :
declare #Tree_ID varchar(100)
Set #Tree_ID='1.23 '
Set #Tree_ID = LTRIM(RTRIM(#Tree_ID))
print '|'+#Tree_ID+'|'
You can use REPLACE.
SELECT REPLACE(#Tree_ID, ' ', '')
Try to use this:
LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(#Tree_ID, CHAR(10), ''), CHAR(13), ''), CHAR(9), '')))
CREATE FUNCTION RemovewhiteSpaces
(
#InputStr varchar(8000)
)
RETURNS varchar(8000)
AS
BEGIN
declare #ResultStr varchar(8000)
set #ResultStr = #InputStr
while charindex(' ', #ResultStr) > 0
set #ResultStr = replace(#InputStr, ' ', '')
return #ResultStr
END
select dbo.RemoveAllSpaces('1.23 1 ')
RESULT
1.231
and apply in your store procedure ...MAY BE IT WORKS FINE
Guys I replaced below code :
Declare #Tree_ID char(30)
With :
Declare #Tree_ID varchar(30)
And it worked fine for me. So, it means there was no problem with either of LTRIM,RTRIM or Replace functions which were not working on static allocation (char) and when I changed it to varchar it worked fine

SQL create xml of Parameters dynamically

Is there a way to query the parameters passed into a stored procedure and return them as XML without creating a string of the parameters and then casting that as xml? I'm looking for something generic, that will work for most SPs without having to physicially code it each time?
I have a bunch of stored procedures that access and modify verify specific information. At the end of the SPs I want to insert into a logging table the name of the SP, and the parameters (in xml) that were used to invoke the SP. I know how to get the name of the SP, and I know how to get a list of the parameters for the SP. What I want is a way to mash it all into XML along the actual values of the parameters that were passed.
I'm looking for something that does this, without the manual coding of each parameter:
DECLARE #L_Data varchar(1500)
SET #L_Data = '<parms>' +
CASE WHEN #ParamRegStationID IS NULL THEN ''
ELSE ',#ParamRegStationID=''' + Convert(varchar, #ParamRegStationID) + '''' END +
CASE WHEN #ParamScheduleID IS NULL THEN ''
ELSE ',#ParamScheduleID=''' + Convert(varchar, #ParamScheduleID) + '''' END +
CASE WHEN #ParamPatientID IS NULL THEN ''
ELSE ',#ParamPatientID=''' + Convert(varchar, #ParamPatientID) + '''' END +
CASE WHEN #ParamHISPatientID IS NULL THEN ''
ELSE ',#ParamHISPatientID=''' + #ParamHISPatientID + '''' END +
CASE WHEN #ParamEvent IS NULL THEN ''
ELSE ',#ParamEvent=''' + #ParamEvent + '''' END +
'</parms>'
This doesn't work, and it isn't as elegant as what I'm hoping for. However, here is an example illustrating what I'm trying to ultimately get to. It creates the temp table, but doesn't add the parameters to it as columns, so I can later extract it as XML.
ALTER PROC uspTest
#ParamID as bigint=null,
#ParamXYZ as varchar(255)=null
as
-- PROC Does whatever it is going to do ....
DECLARE #ProcName varchar(128), #ParmName varchar(128), #ParmType varchar(128), #ParmLen int,
#ParmSQL varchar(1000)
select #ProcName=OBJECT_NAME(##PROCID)
--select * from INFORMATION_SCHEMA.ROUTINES where ROUTINE_TYPE='PROCEDURE' and ROUTINE_NAME=#ProcName
DECLARE csrParms CURSOR
FOR
select PARAMETER_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH from INFORMATION_SCHEMA.PARAMETERS where SPECIFIC_NAME=#ProcName and PARAMETER_MODE='IN'
ORDER BY ORDINAL_POSITION
FOR READ ONLY
OPEN csrParms
FETCH NEXT FROM csrParms
INTO #ParmName, #ParmType, #ParmLen
CREATE TABLE #Parms(ID int identity(1,1), Created DateTime)
INSERT INTO #Parms select GETDATE()
WHILE ##FETCH_STATUS = 0
BEGIN
-- GET Parm value and format as xml attribute to save parm
SET #ParmSQL = 'ALTER TABLE #Parms add ' + #ParmName + ' varchar(' + CAST(ISNULL(#ParmLen, 128) as varchar(128)) + ') NULL '
print #ParmSQL
EXEC (#ParmSQL)
SET #ParmSQL = 'UPDATE #Parms SET ' + #ParmName + ' = ''????'''
print #ParmSQL
--EXEC (#ParmSQL)
FETCH NEXT FROM csrParms
INTO #ParmName, #ParmType, #ParmLen
END
SET #ParmSQL = CAST((select * from #Parms FOR XML RAW) as varchar(1000))
select #ParmSQL
CLOSE csrParms
DEALLOCATE csrParms
This is close to what I'm looking for, I need to know how to replace the ??? with the current value of the parameter dynamically though.
ALTER PROC uspTest
#ParamID as bigint=null,
#ParamXYZ as varchar(255)=null
as
-- PROC Does whatever it is going to do ....
DECLARE #ProcName varchar(128), #ParmName varchar(128), #ParmType varchar(128), #ParmLen int,
#ParmSQL varchar(1000)
select #ProcName=OBJECT_NAME(##PROCID)
--select * from INFORMATION_SCHEMA.ROUTINES where ROUTINE_TYPE='PROCEDURE' and ROUTINE_NAME=#ProcName
set #ParmSQL =
' CREATE TABLE #Parms(ID int identity(1,1), Created DateTime, ' +
STUFF((select (', ' + REPLACE(PARAMETER_NAME,'#','') + ' varchar(' + CAST(ISNULL(CHARACTER_MAXIMUM_LENGTH, 128) as varchar(128)) + ') NULL ')
from INFORMATION_SCHEMA.PARAMETERS where SPECIFIC_NAME='uspTest' and PARAMETER_MODE='IN'
order by ORDINAL_POSITION for XML path(''), type).value('.', 'varchar(max)'), 1, 2, '')
+ ');
' + 'INSERT INTO #Parms (Created) select GETDATE(); ' + STUFF((select (';
UPDATE #Parms SET ' + REPLACE(PARAMETER_NAME,'#','') + ' = ''???''')
from INFORMATION_SCHEMA.PARAMETERS where SPECIFIC_NAME='uspTest' and PARAMETER_MODE='IN'
order by ORDINAL_POSITION for XML path(''), type).value('.', 'varchar(max)'), 1, 2, '')
+ ';
select CAST((select * from #Parms FOR XML RAW) as varchar(1000));'
print #ParmSQL
EXEC (#ParmSQL)
When I execute the proc as:
EXEC uspTest 1, 'test'
Returns:
<row ID="1" Created="2012-04-20T09:44:43.700" ParamID="???" ParamXYZ="???"/>
Prints out:
CREATE TABLE #Parms(ID int identity(1,1), Created DateTime, ParamID varchar(128) NULL , ParamXYZ varchar(255) NULL );
INSERT INTO #Parms (Created) select GETDATE();
UPDATE #Parms SET ParamID = '???';
UPDATE #Parms SET ParamXYZ = '???';
select CAST((select * from #Parms FOR XML RAW) as varchar(1000));
Is this SQL Server 2000 or later? If so you could use the FOR XML clause:
DECLARE #p1 varchar(100) = 'blah'
, #p2 int = 1
, #p3 datetime2(7) = '2011-01-01 13:41'
;
SELECT #p1 StringParm
, #p2 IntParm
, #p3 DateParm
FOR XML RAW
returns:
<row StringParm="blah" IntParm="1" DateParm="2011-01-01T13:41:00"/>
Edit
Ah, the problem there is that you need to parse out the parameter list as well as the values (which are local) into dynamic SQL (where they'd be out of scope).
I suppose you could use INFORMATION_SCHEMA.PARAMETERS to dynamically list the parameters and dbcc_inputbuffers to get the actual values passed. Something like:
create procedure junk
( #int INT
, #string VARCHAR(20)
, #date DATE
)
AS
BEGIN
DECLARE #tmp TABLE
( EventType NVARCHAR(30)
, PARMS INT
, Info NVARCHAR(2000)
);
DECLARE #object NVARCHAR(200);
INSERT INTO #tmp
EXEC('DBCC INPUTBUFFER(##SPID) WITH NO_INFOMSGS');
SELECT INFO
, 'Call' lType
FROM #tmp
UNION
SELECT STUFF(
( SELECT ', ' + parameter_name
FROM INFORMATION_SCHEMA.PARAMETERS
WHERE SPECIFIC_NAME = OBJECT_NAME(##procid)
ORDER BY ORDINAL_POSITION
FOR XML PATH('')
)
, 1
, 2
, ''
)
, 'Parms';
END
That now makes it so that:
exec dbo.junk #int = 3, #string = 'hoo', #date = '2/2/2002';
Returns:
exec dbo.junk #int = 3, #string = 'hoo', #date = '2/2/2002'; Call
#int, #string, #date Parms
Which should get you a ways along. The tricky bit is that DBCC_INPUTBUFFERS returns the EXACT call string. So you'd need to write code to parse out the call to match the input line to the parameter list. If you go that route, you'll likely want a stored function that does the parsing. It would likely take the call string and parameter list something like the return values above, match them, and use the FOR XML clause to return the format you want.
You could also parse call string in a cursor tied to the parameter list. Then you'd pull the parameters in order and look for the commas and #'s. You could still have trouble with parameter values that included those characters if you didn't take that into account.
IMHO, getting that squared away seems like a lot of work compared to a simple select which can almost be copied/pasted from the function header. Of course, if you're talking about a large volume of procedures then it might be worth it. Either way, good luck and thanks for a thought-provoking question.