I dont believe the evaluated statement is available, meaning your example query 'Select @FooBar' is never persisted anywhere as 'Select 364556243'
Even in a profiler trace you would see the statement hit the cache as '(@Foobar int)select @foobar'
This makes sense, since a big benefit of using sp_executesql is that it is able to cache the statement in a reliable form without variables evaluated, otherwise if it replaced the variables and executed that statement we would just see the execution plan bloat.
updated: Here's a step in right direction:
All of this could be cleaned up and wrapped in a nice function, with inputs (@Statement, @ParamDef, @ParamVal) and would return the "prepared" statement. I'll leave some of that as an exercise for you, but please post back when you improve it!
Uses split function from here link
set nocount on;
declare @Statement varchar(100), -- the raw sql statement
@ParamDef varchar(100), -- the raw param definition
@ParamVal xml -- the ParamName -to- ParamValue mapping as xml
-- the internal params:
declare @YakId int,
@Date datetime
select @YakId = 99,
@Date = getdate();
select @Statement = 'Select * from dbo.Yak where YakId = @YakId and CreatedOn > @Date;',
@ParamDef = '@YakId int, @Date datetime';
-- you need to construct this xml manually... maybe use a table var to clean this up
set @ParamVal = ( select *
from ( select '@YakId', cast(@YakId as varchar(max)) union all
select '@Date', cast(@Date as varchar(max))
) d (Name, Val)
for xml path('Parameter'), root('root')
)
-- do the work
declare @pStage table (pName varchar(100), pType varchar(25), pVal varchar(100));
;with
c_p (p)
as ( select replace(ltrim(rtrim(s)), ' ', '.')
from dbo.Split(',', @ParamDef)d
),
c_s (pName, pType)
as ( select parsename(p, 2), parsename(p, 1)
from c_p
),
c_v (pName, pVal)
as ( select p.n.value('Name[1]', 'varchar(100)'),
p.n.value('Val[1]', 'varchar(100)')
from @ParamVal.nodes('root/Parameter')p(n)
)
insert into @pStage
select s.pName, s.pType, case when s.pType = 'datetime' then quotename(v.pVal, '''') else v.pVal end -- expand this case to deal with other types
from c_s s
join c_v v on
s.pName = v.pName
-- replace pName with pValue in statement
select @Statement = replace(@Statement, pName, isnull(pVal, 'null'))
from @pStage
where charindex(pName, @Statement) > 0;
print @Statement;