Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using temp table with exec @sql in stored procedure

I have a stored procedure and part of them as below: @DRange is a incoming varchar value

declare @sql varchar(max)
set @sql = 'select * into #tmpA from TableA where create_date >= getDate - ' + @DRange + '' and is_enabled = 1'

exec (@sql)

select * from #tmpA

The problem is when I execute the stored procedure, an error message occurs: Cannot find the object "#tmpA" because it does not exist or you do not have permissions.

Is it not possible to use temp table and execute it or did I do something wrong?

like image 331
William Tang Avatar asked Oct 24 '13 01:10

William Tang


People also ask

Can you use temp tables in stored procedures?

Stored procedures can reference temporary tables that are created during the current session. Within a stored procedure, you cannot create a temporary table, drop it, and then create a new temporary table with the same name.

Can we pass temp table as parameter to stored procedure?

A TEMP Table of User Defined Table Type has to be created of the same schema as that of the Table Valued parameter and then it is passed as Parameter to the Stored Procedure in SQL Server.

Can we use temp table in nested stored procedure?

Yes, the temp table is in the scope of the connection, so the nested stored procedure (sp2) will have access to #temp table create in sp1. Yes, in SQL 2008 we have ability to pass a table valued parameter (TVP) as input to a function or stored procedure.


2 Answers

#tmpA is created in a different scope, so is not visible outside of the dynamic SQL. You can just make the ultimate SELECT a part of the dynamic SQL. Also a couple of other things:

  • Always use the schema prefix when creating/referencing objects
  • Always use sp_executesql for dynamic SQL; in this case it allows you to parameterize the @DRange value and avoid SQL injection risks.
  • Always prefix Unicode strings with N - Unicode is required for sp_executesql but if you get lazy about this in other areas of your code it can also lead to painful implicit conversions.
DECLARE @sql NVARCHAR(MAX);

SET @sql = N'select * into #tmpA from dbo.TableA 
    where create_date >= DATEADD(DAY, -@DRange, GETDATE())
    AND is_enabled = 1; SELECT * FROM #tmpA';

EXEC sp_executesql @sql, N'@DRange INT', @DRange;

Of course if all you're doing is selecting, I have a hard time understanding why this is dynamic SQL in the first place. I assume your query (or what you later do with the temp table) is more complicated than this - if so, don't dumb it down for us. Telling us your whole problem will prevent a lot of back and forth, as the additional details could change the answer.

like image 86
Aaron Bertrand Avatar answered Sep 27 '22 20:09

Aaron Bertrand


Here's what I'd do.

declare @sql varchar(max)

set @sql = 'select * from TableA where create_date >= getDate - ' + @DRange + '' and is_enabled = 1'

Select * Into #tmpA from TableA where create_date = '01/01/1000' -- to create a blank table

insert into #tmpA

exec (@sql)

select * from #tmpA
like image 28
Sani Avatar answered Sep 27 '22 19:09

Sani