SQL Server SELECT到现有表中


384

我试图从一个表中选择一些字段,并将它们插入到存储过程中的现有表中。这是我正在尝试的:

SELECT col1, col2
INTO dbo.TableTwo 
FROM dbo.TableOne 
WHERE col3 LIKE @search_key

我认为SELECT ... INTO ...是针对临时表的,这就是为什么我得到一个dbo.TableTwo已经存在的错误的原因。

如何从插入多行dbo.TableOnedbo.TableTwo


29
既然您已经接受了答案,我只想提供一个注释:Select Into不是“用于临时表”,而是用于基于查询的select部分的结构(和数据)创建新表。 。对于表X,最多只能选择1次*,之后,您需要使用Insert Into附加任何数据。*如果该表已经存在,则为零次。当然这是除非您先删除表。
pinkfloydx33

8
但请注意,Select Into不会复制索引/主键/外键约束,因此会留下未索引的堆-o-数据。这对于快速的开发工作很有用,但对于添加/移动实际生产表的方式却不是。
Graham Griffiths 2013年

只需运行以下语句“ drop table tabletwo;” 并在查询上方运行。选择... into不适用于临时表。
Shiwangini

Answers:


637

SELECT ... INTO ... 仅在INTO子句中指定的表不存在时才起作用-否则,您必须使用:

INSERT INTO dbo.TABLETWO
SELECT col1, col2
  FROM dbo.TABLEONE
 WHERE col3 LIKE @search_key

假设dbo.TABLETWO中只有两列-否则需要指定这些列:

INSERT INTO dbo.TABLETWO
  (col1, col2)
SELECT col1, col2
  FROM dbo.TABLEONE
 WHERE col3 LIKE @search_key

52
最佳做法是始终指定列,无论它们是否全部存在。当有人添加列时,这将有助于防止事情中断。
HLGEM 2013年

1
嗯,SELECT... INTO...如果INTO子句中指定的表不存在,则该语句似乎不起作用。我收到“未声明的变量”错误。虽然也许这个问题仅适用于MySQL。的CREATE TABLE ... LIKE .. worked;
LazerSharks

1
@Gnuey SELECT ... INTO ...仅在存在现有表的情况下有效。如果没有现有表格,请使用原始张贴者的格式(这将创建一个新表格)
2014年

6
@Will你的意思与你所说的相反吗?“ SELECT ... INTO ...”要求指定一个不存在的表,而“ INSERT INTO ...”要求指定一个现有的表。
安德烈C.安德森

5
我希望有一个计数器可以查询我使用该答案的次数!
MTAdmin

13

有两种不同的方法可以实现将数据从一个表插入到另一个表。

对于现有表-INSERT INTO SELECT

当该表已在数据库中早先创建并且数据要从另一个表插入该表时,使用此方法。如果insert子句和select子句中列出的列相同,则不需要列出它们。优良作法是始终出于可读性和可伸缩性目的列出它们。

----Create testable
CREATE TABLE TestTable (FirstName VARCHAR(100), LastName VARCHAR(100))
----INSERT INTO TestTable using SELECT
INSERT INTO TestTable (FirstName, LastName)
SELECT FirstName, LastName
FROM Person.Contact
WHERE EmailPromotion = 2
----Verify that Data in TestTable
SELECT FirstName, LastName
FROM TestTable
----Clean Up Database
DROP TABLE TestTable

对于不存在的表-SELECT INTO

如果表不是较早创建的,则使用此方法;当将一个表的数据插入到另一表的新创建的表中时,需要使用此方法。使用与所选列相同的数据类型创建新表。

----Create a new table and insert into table using SELECT INSERT
SELECT FirstName, LastName
INTO TestTable
FROM Person.Contact
WHERE EmailPromotion = 2
----Verify that Data in TestTable
SELECT FirstName, LastName
FROM TestTable
----Clean Up Database
DROP TABLE TestTable

参考1 2


3

它将按以下方式工作:

insert into Gengl_Del Select Tdate,DocNo,Book,GlCode,OpGlcode,Amt,Narration 
from Gengl where BOOK='" & lblBook.Caption & "' AND DocNO=" & txtVno.Text & ""

5
+1以抵消-1,并努力提供可被其他用户使用或参考的想法。@MarkSowul是SQL注入的权利,但是出于学术目的,其他人可以尝试这种方法。
阿尔伯特·劳尔2013年

1
大多数表都有一个自动增量字段,无法插入。所以SELECT *不行 这是更好的方法,谢谢!
MJH'1

2
@ User6675636b20796f7521如果要说的是SQL注入,我不会建议其他人尝试这种方法“还可以”。永远不要这样做,因此永远不要尝试。编辑此答案从一开始就显示正确的方法会更有效率,如果有人问,“问号/符号是什么?” 您只需回答:“那些是用于参数化查询的参数标记(超出范围)”,然后让他们从那里找出来。
马特·博尔贾

2
select *
into existing table database..existingtable
from database..othertables....

如果您select * into tablename from other tablenames下次已经使用过添加内容,请说select * into existing table tablename from other tablenames


2
PS在SYBASE ASE 15.5上进行了测试
Verena_Techie

10
OP正在要求MS SQL。
GrandMasterFlush

1

如果目标表确实存在,但您不想指定列名:

DECLARE @COLUMN_LIST NVARCHAR(MAX);
DECLARE @SQL_INSERT NVARCHAR(MAX);

SET @COLUMN_LIST = (SELECT DISTINCT
    SUBSTRING(
        (
            SELECT ', table1.' + SYSCOL1.name  AS [text()]
            FROM sys.columns SYSCOL1
            WHERE SYSCOL1.object_id = SYSCOL2.object_id and SYSCOL1.is_identity <> 1
            ORDER BY SYSCOL1.object_id
            FOR XML PATH ('')
        ), 2, 1000)
FROM
    sys.columns SYSCOL2
WHERE
    SYSCOL2.object_id = object_id('dbo.TableOne') )

SET @SQL_INSERT =  'INSERT INTO dbo.TableTwo SELECT ' + @COLUMN_LIST + ' FROM dbo.TableOne table1 WHERE col3 LIKE ' + @search_key
EXEC sp_executesql @SQL_INSERT
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.