时间戳转换器

执行 sp_executeSql for select...into #table 但无法选择出临时表数据

日期:2023-02-24     浏览:235    
【中文标题】执行 sp_executeSql for select...into #table 但无法选择出临时表数据【英文标题】:Execute sp_executeSql for select...into #table but Can't Select out Temp Table Data 【发布时间】:2011-12-23 19:35:43 【问题描述】:

试图选择...进入 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'.

怀疑它仅在“选择”部分有效。插入不工作。 怎么解决?

【问题讨论】:

【参考方案1】:

这个对我有用:

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;

【讨论】:

【参考方案2】:

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

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

INSERT INTO @tmpTbl EXEC sp_executesql @sql

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

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

【讨论】:

虽然这个可以工作,但它是不完整的。问题在于,在 OP 的原始示例中,select ... into ... #TempTable ... 实际上会创建临时表,包括动态指定列。为了使您的语句起作用,必须首先创建/声明临时表(或您正在使用的表变量)(以及正确/匹配的列规范)。 啊,是的,我确实忘记提及了。你肯定需要先声明你的临时表。【参考方案3】:

这对我有用

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

【讨论】:

【参考方案4】:
declare @sql varchar(1000)
set @sql="select * into #t from table;"
set @sql =@sql + "select * from #t;"

 execute  SP_EXECUTESQL  @sql

【讨论】:

【参考方案5】:

要解决此问题,请先使用 CREATE TABLE #TEMPTABLE 命令生成一个空的临时表,然后再运行 sp_executesql。然后使用 sp_executesql 运行 INSERT INTO #TEMPTABLE。这将起作用。这就是我克服这个问题的方法,因为我的所有查询通常都通过 sp_executesql 运行。

【讨论】:

【参考方案6】:

本地临时表#table_name 仅在当前会话中可见,全局临时表##table_name 在所有会话中可见。两人都活到他们的会话结束。 sp_executesql - 创建自己的会话(也许“范围”这个词会更好)所以这就是它发生的原因。

【讨论】:

我认为“范围”这个词会更好。 DECLARE @sql NVARCHAR(MAX); SET @sql = 'SELECT @@SPID'; EXECUTE sp_executesql @sql; SELECT @@SPID 谢谢@Michal,我已经想起了这种使用方法。再次感谢 问题是如何解决它。不是为什么它会破裂。我在下面提供了正确答案。 INSERT INTO @tmpTbl EXEC sp_executesql @sql 注意:sp_executesql不创建自己的会话。相反,它会创建自己的 batch(或执行上下文)。临时表可以被同一会话中的其他批次看到。但是,因为它们在创建它们的批处理退出时被删除,实际上它们只能被从属批处理(即由创建 Temp 表的同一上下文创建的执行上下文)看到。 如果多人尝试运行使用这些全局变量的 proc 会不会出现死锁和其他问题【参考方案7】:

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

如果在调用 sp_executesql 之前定义了本地临时表,则可以使用它,例如

CREATE TABLE #tempTable(id int);

sp_executesql 'INSERT INTO #tempTable SELECT myId FROM myTable';

SELECT * FROM #tempTable;

【讨论】:

【参考方案8】:

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

【讨论】:

这并不完全正确。当使用 PreparedStatements 之类的东西时,MSSQL 引擎通过存储过程运行它来执行,这意味着任何临时表在存储过程的上下文中都存在,如果你尝试执行一个紧跟从 tempTable 中选择 * 的 PreparedStatement,你将找不到 tempTable。【参考方案9】:

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

看这里如何处理这个问题:A bit about sql server's local temp tables

【讨论】:

相关文章

SP_EXECUTESQL 中的 SQL 注入

{】SP_EXECUTESQL中的SQL注入【英文标题】:SQLinjectioninSP_EXECUTESQL【发布时间】:2019-09-0717:09:17【问题描述】:我在SQLServer中有一个存储过程,它获取一个XML作为输入参数。在这个XML中定义了-应该使用哪些参数值执行哪些存储过程。...}

实体框架可以在不访问 sp_executesql 的情况下执行存储过程吗?

{】实体框架可以在不访问sp_executesql的情况下执行存储过程吗?【英文标题】:CanEntityFrameworkexecutestoredprocedureswithoutaccesstosp_executesql?【发布时间】:2022-01-0803:42:40【问题描述】:大家好,我继承了多个桌面应用程序,这些应用程...}

sp_executesql调用示例

{declare@dbnameVARCHAR(20)=EDW_Atomicdeclare@sqlstrnvarchar(1000)declare@DbObjectNamevarchar(20)=BED_TYPE_LKPdeclare@idINTset@sqlstr=select@id_out=idfrom+@dbname+.[dbo].sysobjectswherename=+@DbObjectNa}

当使用 sp_executesql 作为过滤器时,保护 t-sql 动态代码的最佳方法是啥

{】当使用sp_executesql作为过滤器时,保护t-sql动态代码的最佳方法是啥【英文标题】:Whatisbestwaytosecuret-sqldynamiccodewhenitcomesasfiltersusingsp_executesql当使用sp_executesql作为过滤器时,保护t-sql动态代码的最佳方法是什么【发布时间】:202...}

在 PHP 执行时显示加载图像

{】在PHP执行时显示加载图像【英文标题】:ShowloadingimagewhilePHPisexecuting【发布时间】:2013-09-2611:27:06【问题描述】:我想在php脚本执行时显示加载图像。我已经阅读了有关如何执行此操作的不同答案,但其中大多数都表示我应该...}

VueJS - 基于表单选择的隐藏和显示

{...选择的隐藏和显示【英文标题】:VueJS-HideandShowbasedonformselection【发布时间】:2021-12-2612:22:28【问题描述】:我有一个表单选择元素和一个数组来在页面上显示一些设备信息。我使用v-for循环渲染所有设备,但我找不到基于form-sele...}

在Query中获取MYSQL查询执行时间

{】在Query中获取MYSQL查询执行时间【英文标题】:TogetMYSQLqueryexecutiontimeinQuery【发布时间】:2013-05-0208:11:31【问题描述】:我正在开发一个查询浏览器,使用一些大型数据库,我需要知道执行查询所花费的时间。在PHPMYADMIN中成功...}

mysqlexplain(代码片段)

{Explain使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理SQL语句的。分析查询语句或是表结构的性能瓶颈。用法:Explain+SQL语句Explain执行后返回的信息:各字段解释id(都是1是最好的ÿ...}

执行for循环,退出,执行另一个for循环(代码片段)

{...100if(string="0800")//executecodeif(string="0900")//executecode然后我想执行另一个仍然读取相同文本文件但仍在寻找不同参数的for循环。for@i=0to100if(string="SANDIEGO")//executecodeif(string="SA}

mysql(21)—explain执行计划的字段详解(代码片段)

{详细介绍了MySQLEXPLAIN执行计划的各个字段的含义以及使用方式。调用EXPLAIN可以获取关于查询执行计划的信息,以及如何解释输出。EXPLAIN命令是查看查询优化器如何决定执行查询的主要方法,但该动能也有局限性,它...}

Copyright ©2021 时间戳转换器 小常识 114pp | 陕ICP备18005036号