SELECT INTO T-SQL中的表变量

Ind*_*rek 355 t-sql sql-server insert table-variable

有一个复杂的SELECT查询,我想从中将所有行插入表变量,但是T-SQL不允许它.

同样,您不能将表变量与SELECT INTO或INSERT EXEC查询一起使用. http://odetocode.com/Articles/365.aspx

简短的例子:

declare @userData TABLE(
                        name varchar(30) NOT NULL,
                        oldlocation varchar(30) NOT NULL
                       )

SELECT name, location
INTO @userData
FROM myTable
    INNER JOIN otherTable ON ...
WHERE age > 30
Run Code Online (Sandbox Code Playgroud)

表变量中的数据稍后将用于将其插入/更新回不同的表(大多数是具有次要更新的相同数据的副本).这样做的目的是简单地使脚本比SELECT INTO直接进入正确的表更易读,更容易定制.性能不是问题,因为rowcount它相当小,只在需要时手动运行.
......或者告诉我,如果我做错了.

Cri*_*tiC 572

尝试这样的事情:

DECLARE @userData TABLE(
    name varchar(30) NOT NULL,
    oldlocation varchar(30) NOT NULL
);

INSERT INTO @userData (name, oldlocation)
SELECT name, location FROM myTable
INNER JOIN otherTable ON ...
WHERE age > 30;
Run Code Online (Sandbox Code Playgroud)

  • 哇那种有道理,但与此同时我的解析器感觉有点冒犯:) (5认同)
  • 如果将“ SELECT name,location FROM myTable”作为要插入到UserData表中的值,则与select中变量的名称与表定义中的名称匹配无关紧要。您正在选择“名称”以进入UserData“名称”变量,但您正在选择“位置”,并以某种方式将其分配给UserData“ oldlocation”变量。SQL会自动映射这些映射还是会引发某种异常? (2认同)
  • 在插入语句中,如果您没有显式声明列,那么它们将按照原始 create table 语句中声明的顺序进行映射,就像 select * 所做的那样。因此,select 语句中的location 映射到@userData 表中的oldlocation,因为location 在select 结果集中的位置2,而oldlocation 是表定义中的第2 列。也就是说,永远不要这样做。不依赖于列或行的数据库排序。始终明确这一点。 (2认同)

Aak*_*shM 92

目的SELECT INTO是(根据文件,我的重点)

创建另一个表从值的新表

但是你已经有了目标表!所以你想要的是

INSERT语句将一个或多个新行添加到表中

您可以通过以下方式指定数据值:

...

通过使用SELECT子查询指定一行或多行的数据值,例如:

  INSERT INTO MyTable 
 (PriKey, Description)
        SELECT ForeignKey, Description
        FROM SomeView
Run Code Online (Sandbox Code Playgroud)

这种语法中,它被允许MyTable成为表变量.

  • 真的希望接受的答案包含此信息! (2认同)

nan*_*tev 26

您还可以使用公用表表达式来存储临时数据集.它们更优雅,更友好:

WITH userData (name, oldlocation)
AS
(
  SELECT name, location 
  FROM   myTable    INNER JOIN 
         otherTable ON ...
  WHERE  age>30
)
SELECT * 
FROM   userData -- you can also reuse the recordset in subqueries and joins
Run Code Online (Sandbox Code Playgroud)

  • 不利的是,您只能在紧随其后的命令中使用CTE表。如果出于任何原因您需要多次通过结果集,那么CTE将无法工作。OP似乎暗示将进行多次修改,在这种情况下这将不起作用-“表变量中的数据以后将用于将其插入/更新回不同的表中(多数情况下是相同数据的副本,更新)。” (2认同)

Mul*_*lki 15

您可以尝试使用临时表...如果您不是从应用程序执行此操作.(手动运行可能没问题)

SELECT name, location INTO #userData FROM myTable
INNER JOIN otherTable ON ...
WHERE age>30
Run Code Online (Sandbox Code Playgroud)

您跳过了以这种方式声明表的努力...帮助进行特殊查询...这将创建一个本地临时表,除非您在同一会话中,否则其他会话不会显示.如果您从应用程序运行查询,可能会出现问题.

如果您要求它在应用程序上运行,请使用以这种方式声明的变量:

DECLARE @userData TABLE(
    name varchar(30) NOT NULL,
    oldlocation varchar(30) NOT NULL
);

INSERT INTO @userData
SELECT name, location FROM myTable
INNER JOIN otherTable ON ...
WHERE age > 30;
Run Code Online (Sandbox Code Playgroud)

编辑:很多人都提到了来自连接的会话的更新可见性.创建临时表不是Web应用程序的选项,因为会话可以重用,在这些情况下坚持使用临时变量

  • @Franck - 如果你使用全局临时表(两个哈希前缀),你是对的.但是,本地临时表(一个散列前缀)将被隔离到单个会话(也称为单个连接),因此除非您对所有请求使用单个连接,否则不会出现并发问题(不是决定).但是,可能的性能影响仍然存在. (12认同)
  • 创建一个临时更多的开销. (6认同)
  • 对不起,忘了提及我没有CREATE TABLE的权限. (2认同)
  • 使用临时表并不总是安全的.例如,Web服务.对于具有单个连接的webservices来限制服务器上的最大连接并且保护SQL更多,临时表将存在用于每个查询通过并且可以覆盖当前正在使用它的人. (2认同)

Noe*_*ams 8

尝试使用INSERT而不是SELECT INTO:

INSERT @UserData   
SELECT name, location etc.
Run Code Online (Sandbox Code Playgroud)


小智 5

首先创建一个临时表:

步骤1:

create table #tblOm_Temp (

    Name varchar(100),
    Age Int ,
    RollNumber bigint
)
Run Code Online (Sandbox Code Playgroud)

**步骤2:**在Temp表中插入一些值.

insert into #tblom_temp values('Om Pandey',102,1347)
Run Code Online (Sandbox Code Playgroud)

步骤3:声明表变量以保存临时表数据.

declare   @tblOm_Variable table(

    Name Varchar(100),
    Age int,
    RollNumber bigint
)
Run Code Online (Sandbox Code Playgroud)

第4步:从临时表中选择值并插入表变量.

insert into @tblOm_Variable select * from #tblom_temp
Run Code Online (Sandbox Code Playgroud)

最后,将值从临时表插入到Table变量中

第5步:可以检查表变量中的插入值.

select * from @tblOm_Variable
Run Code Online (Sandbox Code Playgroud)