我正在尝试使用动态 sql (MS SQL Server 13.0.5426) 创建一个临时表。这是一个简化的例子:
使用直接 SQL 可以:
DROP TABLE #tmp_ts; -- will error, but ignored on the first execution
SELECT CURRENT_TIMESTAMP ts INTO #tmp_ts;
SELECT * FROM #tmp_ts;
通过动态 SQL 创建它不起作用。
DROP TABLE #tmp_ts; -- drop from previous test.
EXEC sp_executesql N'SELECT CURRENT_TIMESTAMP ts INTO #tmp_ts';
SELECT * FROM #tmp_ts;
输出:
(受影响的 1 行)
消息 208,级别 16,状态 0,第 63 行无效的对象名称“#tmp_ts”。
我的解决方法是不使用临时表,但我很好奇是否有人知道为什么这不起作用。
谢谢!
这从来没有奏效。
如果要动态插入静态临时表,可以这样做:
如果您需要动态构建临时表,请参阅此问答:
问题是您的临时表的范围是您当前的连接。当您
EXEC sp_executesql
看不到您的本地临时表时。您可以使用全局临时表,使用两个# 而不是一个来表示。即
##tmp_ts
。但是,对于您的小代码示例,没有理由使用动态 SQL。如果您只是想在插入临时表之前确保它不存在,则可以使用OBJECT_ID
元数据功能给定下一个示例:
您可以将 SELECT 查询添加到动态查询:
或使用全局临时表:
db<>在这里摆弄
引用自 MS-Docs(粗体是我的)
sp_executesql 在批处理、名称范围和数据库上下文方面与 EXECUTE 具有相同的行为。在执行 sp_executesql 语句之前,不会编译 sp_executesql @stmt 参数中的 Transact-SQL 语句或批处理。然后,@stmt 的内容被编译并作为一个执行计划执行,该执行计划与调用 sp_executesql 的批处理的执行计划分开。sp_executesql 批处理不能引用在调用 sp_executesql 的批处理中声明的变量。sp_executesql 批处理中的本地游标或变量对调用 sp_executesql 的批处理不可见。数据库上下文中的更改仅持续到 sp_executesql 语句的末尾。