我有一个存储过程,它们的一部分如下:
@DRange是传入的varchar值

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


问题是当我执行存储过程时,出现错误消息:
无法找到对象“ #tmpA”,因为该对象不存在或您没有权限。

是否无法使用临时表并执行它,或者我做错了什么?

最佳答案

#tmpA是在其他范围内创建的,因此在动态SQL外部不可见。您可以将最终的SELECT设置为动态SQL的一部分。还有其他几件事:


Always use the schema prefix when creating/referencing objects
Always use sp_executesql for dynamic SQL;在这种情况下,它允许您参数化@DRange值并避免SQL注入风险。
始终为Unicode字符串加上N前缀-sp_executesql需要Unicode,但是如果您在代码的其他区域对此感到懒惰,它也会导致痛苦的隐式转换。


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;


当然,如果您要做的只是选择,那么我很难理解为什么这首先是动态SQL。我认为您的查询(或您以后对临时表的处理)比这更复杂-如果是这样,请不要为我们愚弄它。告诉我们您的整个问题将避免很多来回操作,因为其他详细信息可能会改变答案。

关于sql-server - 在存储过程中将临时表与exec @sql一起使用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19555502/

10-09 05:53
查看更多