INSERT - SELECT *而不是一列

时间:2016-12-06 20:26:29

标签: sql sql-server

寻找插入选择列值的简便方法:

实施例

TableA    TABLEB
-----------------
Field1    Field1
Field2    Field2
Field3    Field3
Field4    Field4
Field5    Field5
          FleldX

我的表包含大约80列。现在我只想将数据从一个表复制到另一个表,例如:

Insert Into table B (Field1, Field2, Field3, Field4, Field5, FieldX) 
VALUES SELECT (Field1, Field2, Field3, Field4, Field5, 'HARDCODEVALUE') 
       FROM TableA

我是否需要设置显式的所有80个列名称,或者最好的解决方案是自动映射字段,以便我可以这样设置

Insert Into table B (Field1, Field2, Field3, Field4, Field5, FieldX) 
VALUES
    SELECT (Field4, Field3, Field2, Field1, Field5, 'HARDCODEVALUE' AS FieldX) 
    FROM TableA  

我可以在哪里重新排序列名和SQL为我做其他事情?

哪种方式最好用?

1 个答案:

答案 0 :(得分:2)

好的,首先你的语法无论如何都行不通。尝试

INSERT INTO tableB (Field1, Field2, Field3, Field4, Field5, FieldX) 
SELECT Field4, Field3, Field2, Field1, Field5, 'HARDCODEVALUE' AS FieldX 
FROM TableA  

接下来是的,您应该始终按照您要在select和insert中将它们插入表中的顺序使用所有列。否则是一个非常大的SQL反模式,它将导致问题,特别是如果列正在改变。您始终希望右列与右列匹配。如果字段名称并不总是直接匹配,则会出现更多问题。

如果您的表格结构每天都会改变结构,那么您就会遇到设计问题,因为这种问题永远不会发生。

我建议您使用informationschema表来动态查找列,但是如果tableA添加了一列,您如何知道将哪个列映射到tableB?如果从tableB中删除了一列,您如何知道从SELECT中删除要从TableA中删除的列?让我来说明问题。

假设您有这种结构:

TABLEA
USERID
USERLOGIN
USERPASSWORD

TABLEB
USERID
SYSLOGIN
SYSPASSWORD
USERTYPE

然后查看SELECT * insert

INSERT INTO tableB 
SELECT *, 'User' AS USERTYPE
FROM TableA  

相当于

INSERT INTO tableB (USERID,SYSLOGIN,SYSPASSWORD,USERTYPE) 
SELECT USERID,USERLOGIN,USERPASSWORD, 'User' AS USERTYPE
FROM TableA 

此时一切都很好。但是当结构改变时会发生什么?

然后结构变成

TABLEA
USERID
USERLOGIN
USERPASSWORD
LASTLOGINDATE

TABLEB
USERID
SYSLOGIN
SYSPASSWORD
USERTYPE
LASTLOGINDATE

如果您使用select *

INSERT INTO tableB 
SELECT *
FROM TableA  

相当于

INSERT INTO tableB (USERID,SYSLOGIN,SYSPASSWORD,USERTYPE, LASTLOGINDATE) 
SELECT USERID,USERLOGIN,USERPASSWORD, LASTLOGINDATE,'User' AS USERTYPE
FROM TableA  

正如您所看到的,通过使用SELECT *,您最终会尝试将LASTLOGINDATE插入到USERTYPE中,并将以前硬编码的值USERTYPE导入LASTLOGINDATE。这是因为当您不指定列时,SQL Server将按顺序将它们排除。如果最后两列是不同的不兼容数据类型,则查询将失败。如果它们是兼容的数据类型会更糟糕,因为查询将成功,并且您的数据库中将包含错误的数据。

可能出现的其他问题是,当您没有指定列名时,您需要具有完全相同的列数才能使插入工作。如果将列添加到一个表而不是另一个表,则会出现问题。如果从表的中间删除一列并添加一列,最终可能会更改哪些列映射到哪一列,如果数据类型不兼容或更糟,则会导致错误,插入错误数据。插入不良数据特别糟糕,因为您可能不会发现它发生了数周甚至数月。