如何将数据设置为临时表中的变量?
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?只需像任何其他表一样执行选择语句。像这样执行的时候,表变量在字符串的作用域中是不存在的。 我认为DECLARE
和EXEC
的执行流程是分开的,因此您不能像这样选择@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 函数中的动态命名临时表运行“选择进入”