执行 sp_executeSql for select...into #table 但无法选择临时表数据
试图选择...到 sp_Executedsql 中的临时表#TempTable。 不是插入成功与否,而是写入了消息 (359行受影响)这意味着成功插入? 下面的脚本
DECLARE @Sql NVARCHAR(MAX);
SET @Sql = 'select distinct Coloum1,Coloum2 into #TempTable
from SPCTable with(nolock)
where Convert(varchar(10), Date_Tm, 120) Between @Date_From And @Date_To';
SET @Sql = 'DECLARE @Date_From VARCHAR(10);
DECLARE @Date_To VARCHAR(10);
SET @Date_From = '''+CONVERT(VARCHAR(10),DATEADD(d,DATEDIFF(d,0,GETDATE()),0)-1,120)+''';
SET @Date_To = '''+CONVERT(VARCHAR(10),DATEADD(d,DATEDIFF(d,0,GETDATE()),0)-1,120)+''';
'+ @Sql;
EXECUTE sp_executesql @Sql;
执行后,它向我返回消息(受影响的 359 行)。 接下来尝试从 #TempTable 中选择数据。
Select * From #TempTable;
它返回给我:
Msg 208, Level 16, State 0, Line 2
Invalid object name '#TempTable'.
怀疑它仅在“选择”部分起作用。插入件不起作用。 如何修复它?
Was trying to select...into a temp Table #TempTable in sp_Executedsql.
Not its successfully inserted or not but there Messages there written
(359 row(s) affected) that mean successful inserted?
Script below
DECLARE @Sql NVARCHAR(MAX);
SET @Sql = 'select distinct Coloum1,Coloum2 into #TempTable
from SPCTable with(nolock)
where Convert(varchar(10), Date_Tm, 120) Between @Date_From And @Date_To';
SET @Sql = 'DECLARE @Date_From VARCHAR(10);
DECLARE @Date_To VARCHAR(10);
SET @Date_From = '''+CONVERT(VARCHAR(10),DATEADD(d,DATEDIFF(d,0,GETDATE()),0)-1,120)+''';
SET @Date_To = '''+CONVERT(VARCHAR(10),DATEADD(d,DATEDIFF(d,0,GETDATE()),0)-1,120)+''';
'+ @Sql;
EXECUTE sp_executesql @Sql;
After executed,its return me on messages (359 row(s) affected).
Next when trying to select out the data from #TempTable.
Select * From #TempTable;
Its return me:
Msg 208, Level 16, State 0, Line 2
Invalid object name '#TempTable'.
Suspected its working only the 'select' section only. The insert is not working.
how fix it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
在这种情况下使用全局临时表可能会导致问题,因为该表将存在于会话之间,并且可能会导致异步使用调用代码时出现一些问题。
如果在调用 sp_executesql 之前定义了本地临时表,则可以使用它,例如
Using a global temporary table in this scenario could cause problems as the table would exist between sessions and may result in some problems using the calling code asynchronously.
A local temporary table can be used if it defined before calling sp_executesql e.g.
本地临时表
#table_name
仅在当前会话中可见,全局临时表##table_name
在所有会话中可见。两者都存活到会话结束为止。sp_executesql
- 创建自己的会话(也许单词“范围”会更好),这就是它发生的原因。Local temporary table
#table_name
is visible in current session only, global temporary##table_name
tables are visible in all sessions. Both lives until their session is closed.sp_executesql
- creates its own session (maybe word "scope" would be better) so that's why it happens.在您的
@sql
字符串中,请勿将插入 #TempTable
。相反,请调用不带INSERT
语句的SELECT
语句。最后,将结果插入到临时表中,如下所示:
此外,如果使用此方法,则需要声明临时表
In your
@sql
string, don't insertinto #TempTable
. Instead, call yourSELECT
statement without anINSERT
statement.Finally, insert the results into your temporary table like so:
Also, you'll need to declare the temporary table if you use this approach
动态 SQL 中的临时表超出了非动态 SQL 部分的范围。
看看这里如何处理这个问题:关于sql server的本地临时表的一些信息
your temp table in dynamic SQL is out of scope in the non dynamic SQL part.
Look here how to deal with this: A bit about sql server's local temp tables
请注意,从 T-SQL 2021 开始,dm_exec_describe_first_result_set() 可用于构建正确形状的临时表以进行 INSERT INTO - 因为它为您提供将从您的数据库返回的列名称和类型。动态 SELECT 或 EXEC ...因此您可以构建动态 SQL 将临时表更改为您需要的形状。
Note, from T-SQL 2021 onwards, dm_exec_describe_first_result_set() can be used to build a temporary table in the right shape to INSERT INTO - as it gives you the column names and types that will be returned from your dynamic SELECT or EXEC ... so you can build dynamic SQL to ALTER a temporary table into the shape you need.
临时表的存在时间与创建临时表的连接一样长。我希望您无意中在单独的连接上发出选择。您可以通过暂时插入非临时表并查看数据是否存在来测试这一点。如果是这种情况,您可以返回到原始解决方案,并确保将连接对象传递给您的选择。
Temporary tables only live as long as the connection that creates them. I would expect that you're unintentionally issuing the select on a separate connection. You can test this by momentarily doing your insert into a non-temporary table and seeing if your data is there. If that is the case you can go back to your original solution and just be sure to pass the connection object to your select.
这对我有用
This worked for me
要解决此问题,请在运行 sp_executesql 之前先使用 CREATE TABLE #TEMPTABLE 命令生成空临时表。然后使用 sp_executesql 运行 INSERT INTO #TEMPTABLE。这会起作用。这就是我克服这个问题的方法,因为我有一个设置,其中所有查询通常都是通过 sp_executesql 运行。
To work around this issue use a CREATE TABLE #TEMPTABLE command first to generate an empty temp table before running sp_executesql. Then run the INSERT INTO #TEMPTABLE with sp_executesql. This will work. This is how I overcome this problem as I have a setup in which all my queries are usually run via sp_executesql.
这对我有用:
This one worked for me: