将 SQL Server SELECT 导入现有表格

451

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

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

我认为SELECT ... INTO ...是用于创建临时表的,这就是为什么会出现错误,提示dbo.TableTwo已经存在。

我该如何将dbo.TableOne中的多行数据插入到dbo.TableTwo中?


33
既然你已经接受了一个答案,我只想提供一个说明:Select Into并不是“用于临时表”,它是基于查询的选择部分的结构(和数据)创建新表的语句。对于一个名为X的表,你只能最多使用一次Select Into进行创建,之后需要使用Insert Into来追加任何数据。如果这个表已经存在,则不能再使用Select Into。当然,除非你先删除该表。 - pinkfloydx33
9
请注意,使用Select Into语句时不会复制索引/主键/外键约束,因此表格将成为无索引的堆数据。这在快速开发中很有用,但不适合用于真正的生产环境中添加/移动表格。 - Graham Griffiths
只需运行此语句'drop table tabletwo;'并运行上面的查询。Select ...into 不适用于临时表。 - Channa
创建新表格(此处为destination)的语法是SELECT select_list INTO destination FROM source [WHERE condition]select_list可以是特定的列,但也可以使用* - surfmuggle
7个回答

741

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

67
无论是否存在所有列,始终指定列是最佳实践。这将有助于防止添加列时出现故障。 - HLGEM
2
嗯,如果在INTO子句中指定的表不存在,则SELECT... INTO...语句似乎无法工作。我收到了一个“未声明的变量”错误。不过,也许这个问题只出现在MySQL中。CREATE TABLE ... LIKE ..是可以工作的; - LazerSharks
1
@Gnuey 如果存在表,则SELECT ... INTO ...才有效。如果不存在表,请使用原始帖子的格式(这将创建一个新表)。 - Will
6
你是说你的意思与原本相反吗?´SELECT ... INTO ...´需要指定一个不存在的表格,而´INSERT INTO ...´则需要指定一个已存在的表格。 - André C. Andersen
8
我希望有一个计数器能记录我查看并使用这个答案的次数! - MTAdmin
显示剩余2条评论

37

有两种不同的方法可以将一张表中的数据插入到另一张表中。

对于已存在的表格 - INSERT INTO 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


5
它的工作方式如下所示:
insert into Gengl_Del Select Tdate,DocNo,Book,GlCode,OpGlcode,Amt,Narration 
from Gengl where BOOK='" & lblBook.Caption & "' AND DocNO=" & txtVno.Text & ""

6
+1是为了抵消-1,并表示赞赏提供可以被其他用户使用或参考的想法。@MarkSowul提到了SQL注入的正确性,但出于学术目的,其他人可以尝试那种方法。 - Albert Laure
1
大多数表都有自增字段,不能插入。因此,“SELECT *”无法使用。这是更好的方法,谢谢! - MJH
2
@User6675636b20796f7521 我不会建议其他人尝试那种方法,如果我们谈论的是SQL注入的话,这样做是不可以的,也不应该去尝试。从一开始就展示正确的方法会更加有效,如果有人问起“问号/艾特符号是什么意思?”,你只需要回答:“这些是用于参数化查询的参数标记(超出范围)”,然后让他们自己解决问题。 - Matt Borja

4
如果目标表已存在,但您不想指定列名:
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

1
如果您想在使用select into创建的新表中拥有标识列,则可以按以下方式完成。
SELECT 
 ID = IDENTITY(INT, 1, 1),
        name
INTO    table2
FROM table1    

0
如果您想要从Table_B插入数据到Table_A,但仅当该列在Table_A中不存在时,请使用以下代码:
BEGIN TRANSACTION

INSERT INTO dbo.Table_A (Column_1)
SELECT DISTINCT Some_Column AS Column_1
FROM dbo.Table_B 
WHERE Some_Column 
    NOT IN (SELECT DISTINCT GroupId 
            FROM dbo.Table_A)

COMMIT

0
这在MS SQL Server上不起作用,但在Sybase上可以正常工作。
select *
into existing table database..existingtable
from database..othertables....

如果你已经使用过select * into tablename from other tablenames,下次要追加的话,你可以这样说:select * into existing table tablename from other tablenames

2
已在SYBASE ASE 15.5上进行了测试。 - Verena_Techie
13
楼主正在寻求 MS SQL。 - GrandMasterFlush
1
请删除此内容,因为它与 SQL Server 无关,会造成混淆和干扰。 - Julian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接