September 30, 2013 at 10:24 am
I am trying to pass a column name as a parameter to build a #temp table combining data from two tables. When I exec the dynamic query it seems to build the temp table because I am receiving a message saying 2048 rows affected; however, I can't select from it, I am receiving an error saying that #TempLevels is an invalid object. Is this possible to do? What am I missing? Thank you in advance!
declare @ColumnLevel as varchar(10);
declare @ReportLevel as varchar(10);
Set @ReportLevel = '2'
set @ColumnLevel =
case
when @ReportLevel = '2' then 'level2'
when @ReportLevel = '3' then 'level3'
when @ReportLevel = '4' then 'level4'
end
print @ColumnLevel
declare @sql as varchar(1000)
set @sql =
'select * into #TempLevels from tblLevels as a join tblReports as b on a.'+ColumnLevel+' = b.ReportLevel'
exec(@sql)
select * from #TempLevels
drop table #TempLevels
September 30, 2013 at 10:30 am
A temp table is dropped as soon as the scope in which it was created ends, that scope is the dynamic SQL, so it's created, populated and then dropped at the end of the dynamic SQL
You either need to CREATE TABLE #... outside the dynamic SQL or do all processing in a single piece of dynamic SQL. The first option is definitely preferred.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
September 30, 2013 at 10:32 am
Thank you for the explanation Gila 🙂
Thant really helps and clears my confusion, I'll use your suggestion.
September 30, 2013 at 10:33 am
You could also avoid using dynamic SQL, even if it might reduce performance a bit.
You could try this.
DECLARE @ReportLevel AS VARCHAR(10);
SELECT *
INTO #TempLevels
FROM tblLevels AS a
INNER JOIN tblReports AS b ON CASE
WHEN @ReportLevel = '2'
THEN a.level2
WHEN @ReportLevel = '3'
THEN a.level3
WHEN @ReportLevel = '4'
THEN a.level4
END = b.ReportLevel
September 30, 2013 at 10:58 am
What Louis posted is the way to go; no DSQL needed for what you are doing. That said, to accomplish this with a temp table you would need to use a global temp table (e.g. temp table that begins with "##") instead of a local temp table.
Below is a modified version of your code (since I don't have access to your tblLevels and tblReports tables) that would work.
declare @ColumnLevel as varchar(10);
declare @ReportLevel as varchar(10);
Set @ReportLevel = '2'
set @ColumnLevel =
case
when @ReportLevel = '2' then 'level2'
when @ReportLevel = '3' then 'level3'
when @ReportLevel = '4' then 'level4'
end
print @ColumnLevel
declare @sql as varchar(1000)
set @sql =
'select *, '''+@ColumnLevel+''' AS xxx into ##TempLevels from sys.databases'
exec(@sql)
select * from ##TempLevels
drop table ##TempLevels
-- Itzik Ben-Gan 2001
September 30, 2013 at 1:45 pm
Be aware that a global temp table means the code must be single-threaded, as simultaneous executions of the code would stomp on each other.
SQL DBA,SQL Server MVP(07, 08, 09) A socialist is someone who will give you the shirt off *someone else's* back.
Viewing 6 posts - 1 through 5 (of 5 total)
You must be logged in to reply to this topic. Login to reply