如何将数据设置为临时表中的变量?

Posted

技术标签:

【中文标题】如何将数据设置为临时表中的变量?【英文标题】:How to set data to a variable from temporary table? 【发布时间】:2015-09-28 11:20:18 【问题描述】:

我已经声明了一个临时表

DECLARE @Table Table
(
  ID INT IDENTITY(1,1),
  TableColumn VARCHAR(MAX)
) 

DECLARE @Temp VARCHAR(MAX)
SET @Temp='SELECT * FROM '+'@Table'+''

SELECT @Temp
EXEC (@Temp)

我想将@Table的所有数据设置为变量@Temp。以上我试过的做法是否正确?目前它显示了一些错误。

消息 1087,第 15 级,状态 2,第 1 行 必须声明表变量“@Table”。

我尝试了上面的方法然后它显示错误

消息 156,第 15 级,状态 1,第 1 行

关键字“AS”附近的语法不正确。

消息 1087,第 15 级,状态 2,第 9 行

必须声明表变量“@Table”。消息 139,级别 15,状态 1, 第 0 行

无法为局部变量分配默认值。

消息 137,级别 15,状态 2,第 17 行

必须声明标量变量“@Temp”。

【问题讨论】:

为什么要使用字符串。只需执行:Select * From @Table @Jeremy 我想将值设置为这个字符串 您的问题不清楚。你想设置什么? 您为什么要尝试使用动态 SQL?只需像任何其他表一样执行选择语句。像这样执行的时候,表变量在字符串的作用域中是不存在的。 我认为DECLAREEXEC 的执行流程是分开的,因此您不能像这样选择@Table 的数据形式。删除动态 SQL 并运行 SELECT * FROM @Table,它会带你到你想要的地方。 【参考方案1】:

这是为了显示表变量和临时表之间的区别。你不能做你想做的事。此外,@temp 只是一个包含您要执行的 SQL 的变量。如果您希望将结果放在另一个变量中,则必须声明另一个变量。

DECLARE @Table TABLE (
    ID INT IDENTITY(1, 1)
    ,TableColumn VARCHAR(MAX)
    )

INSERT INTO @Table (TableColumn)
VALUES ('testing 1,2,3')

SELECT *
FROM @table --with table variables, you can only select in the scope

DECLARE @Temp VARCHAR(MAX)

SET @Temp = 'SELECT * FROM @Table'

BEGIN TRY
    --SELECT @Temp
    EXEC (@Temp) --fails, because @table is not in scope
END TRY

BEGIN CATCH
    SELECT 'Table variable dynamic execution failed'
END CATCH
GO

CREATE TABLE #table (
    ID INT IDENTITY(1, 1)
    ,TableColumn VARCHAR(MAX)
    )

INSERT INTO #Table (TableColumn)
VALUES ('testing 1,2,3')

DECLARE @Temp VARCHAR(MAX)

SET @Temp = 'SELECT * FROM #Table' --you can select out of a temp table with dynamic sql, because it will remain in scope for called procedures

--SELECT @Temp
EXEC (@Temp) 
DROP TABLE #table

【讨论】:

它可以工作,但#table 将由 Azurewebsites(Cloud) 支持 @SemilSebastian 您需要在问题中提供所有相关信息,以便我们有效。就您的意图和环境提出 100 个问题并不能帮助我们帮助您。正如我之前所说,在非常高的层次上说明您要解决的业务问题。很有可能,有一种不同的方法可以解决您想要的问题。 @Jeremy,先生,请参阅我更新的问题。不使用#table 是否可能?为什么因为当我在我的云服务器中运行您的查询时它显示错误(Azure 云)【参考方案2】:

EXEC() 创建新上下文,变量在那里不可见,因此您需要将它们作为参数传递。但是临时表和普通表是可见的。这就是你得到的原因

必须声明表变量“@Table”。

如果您可以将临时变量更改为临时表。

SqlFiddleDemo

CREATE TABLE #Table
( ID INT IDENTITY(1,1),
  TableColumn VARCHAR(MAX));

INSERT INTO #Table
VALUES ('aaa'), ('bbb');

DECLARE @Temp NVARCHAR(MAX) ='SELECT * FROM <placeholder>';

SET @Temp = REPLACE(@Temp, '<placeholder>', '#Table');

-- SELECT @Temp;

EXEC [dbo].[sp_executesql]
      @Temp;

如果你想查询临时变量,你需要创建表类型并作为参数传递给动态 sql:

Demo

CREATE TYPE MyTable AS TABLE 
( 
 ID INT IDENTITY(1,1),
  TableColumn VARCHAR(MAX)
);

DECLARE @Table AS MyTable;

INSERT INTO @Table
VALUES ('aaa'), ('bbb');

DECLARE @Temp NVARCHAR(MAX) ='SELECT * FROM '+'@Table'+'';

-- SELECT @Temp;

EXEC [dbo].[sp_executesql]
      @Temp
      ,N'@Table MyTable READONLY'
      ,@Table;

【讨论】:

@SemilSebastian 你看到临时变量与临时表的区别了吗?您需要将临时变量作为参数传递给动态 sql,请参阅第二个演示 @SemilSebastian 一件事,EXEC() 创建了新的上下文,变量在那里不可见,因此您需要将它们作为参数传递。但是临时表和普通表是可见的。这就是为什么你会得到Must declare the table variable "@Table". @ lad2025 2 , Msg 156, Level 15, State 1, Line 1 关键字“AS”附近的语法不正确。 Msg 1087, Level 15, State 2, Line 9 必须声明表变量“@Table”。消息 139,级别 15,状态 1,行 0 无法将默认值分配给局部变量。 Msg 137, Level 15, State 2, Line 17 必须声明标量变量“@Temp”。 我在运行它时遇到了这么多错误 @SemilSebastian 我没有看到你的代码,看小提琴演示,一切正常 @SemilSebastian 或分成两行 DECLARE @Temp VARCHAR(MAX) SET @Temp='SELECT * FROM '+'@Table'+''

以上是关于如何将数据设置为临时表中的变量?的主要内容,如果未能解决你的问题,请参考以下文章

无法从 plpgsql 函数中的动态命名临时表运行“选择进入”

如何将数据帧传递到气流任务的临时表中

将表变量中的值插入到已经存在的临时表中

在 Sql Server 中,如何将游标中的值放入临时表中?

RedShift 临时表中的编码

如何使用 SQL 中的 Case 语句将数据插入临时表