寻找插入选择列值的简便方法:
实施例
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为我做其他事情?
哪种方式最好用?
答案 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将按顺序将它们排除。如果最后两列是不同的不兼容数据类型,则查询将失败。如果它们是兼容的数据类型会更糟糕,因为查询将成功,并且您的数据库中将包含错误的数据。
可能出现的其他问题是,当您没有指定列名时,您需要具有完全相同的列数才能使插入工作。如果将列添加到一个表而不是另一个表,则会出现问题。如果从表的中间删除一列并添加一列,最终可能会更改哪些列映射到哪一列,如果数据类型不兼容或更糟,则会导致错误,插入错误数据。插入不良数据特别糟糕,因为您可能不会发现它发生了数周甚至数月。