执行sp_executeSql以选择...#table 但无法选择临时表数据



试图选择…到一个临时表#TempTable在sp_Executedsql。不是它是否成功插入,而是那里写了消息(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行)返回me。接下来,当尝试从#TempTable.

中选择数据时
Select * From #TempTable;

它返回我:

Msg 208, Level 16, State 0, Line 2
Invalid object name '#TempTable'.

怀疑它只工作'select'部分。插入不工作。如何修复它?

在这种情况下使用全局临时表可能会导致问题,因为表存在于会话之间,并且可能导致异步使用调用代码时出现一些问题。

本地临时表可以在调用sp_executesql之前定义,例如

CREATE TABLE #tempTable(id int);
execute sp_executesql N'INSERT INTO #tempTable SELECT myId FROM myTable';
SELECT * FROM #tempTable;

本地临时表#table_name只在当前会话中可见,全局临时表##table_name在所有会话中可见。直到会议结束,两者都可以生存。sp_executesql -创建自己的会话(也许词"范围"会更好),所以这就是为什么它发生。

在您的@sql字符串中,不要插入into #TempTable。相反,调用没有INSERT语句的SELECT语句。

最后,将结果插入临时表,如下所示:

INSERT INTO @tmpTbl EXEC sp_executesql @sql

如果使用这种方法,还需要声明临时表

DECLARE @tmpTbl TABLE (
    //define columns here...
)

动态SQL中的临时表超出了非动态SQL部分的范围。

关于sql server的本地临时表

临时表只存在于创建它们的连接中。我希望您无意中在另一个连接上发出select。您可以通过暂时插入一个非临时表并查看数据是否在那里来测试这一点。如果是这种情况,您可以回到最初的解决方案,并确保将连接对象传递给您的选择。

declare @sql varchar(1000)
set @sql="select * into #t from table;"
set @sql =@sql + "select * from #t;"
 execute  SP_EXECUTESQL  @sql

这对我有用

declare @sql nvarchar(max)     
create table #temp ( listId int, Name nvarchar(200))     
set @sql = 'SELECT top 10 ListId, Name FROM [V12-ListSelector].[dbo].[List]'    
insert into #temp
exec sp_executesql  @sql    
select * from #temp    
drop table #temp

要解决这个问题,首先使用CREATE TABLE #TEMPTABLE命令在运行sp_executesql之前生成一个空的临时表。然后使用sp_executesql执行INSERT INTO #TEMPTABLE命令。这是可行的。这就是我如何克服这个问题,因为我有一个设置,其中我所有的查询通常通过sp_executesql运行。

注意,从T-SQL 2021开始,dm_exec_describe_first_result_set()可以用来建立一个正确形状的临时表来插入-因为它给你将从动态SELECT或EXEC返回的列名和类型…因此,您可以构建动态SQL来将临时表更改为您需要的形状。

DECLARE @strSQL NVarChar(max) = 'EXEC [YourSP] @dtAsAt=''2022-11-09'', @intParameter2=42'
--*** Build temporary table: create it with dummy column, add columns dynamically 
--*** using an exec of sys.dm_exec_describe_first_result_set()  and dropping the dummy column
DROP TABLE IF EXISTS #tblResults;
CREATE TABLE #tblResults ([zz] INT); 
DECLARE @strUpdateSQL NVarChar(max);
SELECT @strUpdateSQL = STRING_AGG( CONCAT(  'ALTER TABLE #tblResults ADD ', 
                                            QUOTENAME([name]), ' ', 
                                            [system_type_name], ';') 
                                , ' ')  WITHIN GROUP (ORDER BY [column_ordinal])
    FROM sys.dm_exec_describe_first_result_set (@strSQL, NULL, 0)
SET @strUpdateSQL += 'ALTER TABLE #tblResults DROP COLUMN [zz];'
EXEC (@strUpdateSQL);
    
--*** Now we have #tblResults in the right shape to insert into, and use afterwards
INSERT INTO #tblResults     EXEC (@strSQL);
SELECT * FROM #tblResults;
--*** And tidy up
DROP TABLE IF EXISTS #tblResults;

这个很适合我:

DECLARE @Query as NVARCHAR(MAX);
SET @Query=(SELECT * FROM MyTable) ;
SET @Query=(SELECT 'SELECT * INTO dbo.TempTable FROM ('+@Query +') MAIN;');
EXEC sp_executesql @Query;
SELECT * INTO #TempTable FROM dbo.TempTable;
DROP TABLE dbo.TempTable;
SELECT * FROM #TempTable;

相关内容

  • 没有找到相关文章

最新更新