20

我创建了一个程序

create procedure testProcedure_One 
as
DECLARE @Query nvarchar(4000)

begin
SET @Query = 'SELECT * into #temptest FROM  Table1'

Exec sp_Executesql @query

SELECT * FROM #temptest
drop table #temptest
end

当我运行该程序testProcedure_One时,我收到错误消息:

Invalid object name '#temp'

但如果我使用##temp means它的工作:

create procedure testProcedure_two 
as
DECLARE @Query nvarchar(4000)

begin

SET @Query = 'SELECT * into ##temptest FROM  Table1'


Exec sp_Executesql @query

SELECT * FROM ##temptest
drop table ##temptest
end

testProcedure_two工作正常

可能是什么问题?我该如何解决?

4

3 回答 3

20

大概您有以下代码从#temp 中选择,给您错误?

这取决于范围。##temp 是一个全局临时表,在其他会话中可用。#temp 是“本地”临时表,只能由当前执行范围访问。sp_executesql 在不同的范围内运行,因此它将数据插入#temp,但如果您尝试在 sp_executesql 调用之外访问该表,它将找不到它。

例如,此错误是因为 #Test 已创建且仅对 sp_executesql 上下文可见:

EXECUTE sp_executesql N'SELECT 1 AS Field1 INTO #Test'
SELECT * FROM #Test

以上适用于##Test,因为它创建了一个全局临时表。

这是可行的,因为 SELECT 是同一范围的一部分。

EXECUTE sp_executesql N'SELECT 1 AS Field1 INTO #Test; SELECT * FROM #Test'

我的问题是:

  1. 你真的需要使用临时表吗,如果没有它们,你就找不到解决方案,例如使用子查询吗?
  2. 你真的需要像这样使用 sp_executesql 执行 sql 吗?
于 2009-08-12T11:19:07.733 回答
5

使用CREATE TABLE创建临时表,然后使用INSERT INTO而不是 SELECT INTO 插入值。

这为我解决了这个问题。

于 2016-09-09T05:29:32.430 回答
1

为了让您执行,我认为应该首先使用 ddl 语句创建#tmp_table。

然后你执行你的 exec 并且你在 exec 中创建的存储过程应该具有相同的命名temp table viz.#tmp_table

于 2011-06-09T16:06:44.177 回答