只有使用列列表且IDENTITY_INSERT为ON时,才能指定表中标识列的显式值SQL Server
我试图做这个查询
INSERT INTO dbo.tbl_A_archive SELECT * FROM SERVER0031.DB.dbo.tbl_A
但即使跑了之后
set identity_insert dbo.tbl_A_archive on
我收到此错误消息
表'dbo.tbl_A_archive'中的标识列的显式值只能在使用列列表且IDENTITY_INSERT为ON时指定。
tbl_A
是一个巨大的行和宽度的表,即它有很多列。 我不希望手动input所有列。 我怎样才能使这个工作? 请帮忙!
那么,错误消息基本上说这一切。 您有以下select:
- 制作一个列表(一个在INFORMATION_SCHEMA.COLUMNS上的SELECT和一个好的文本编辑器或由Andomar和Dave提出的解决scheme可以帮助你)
要么
- 使
tbl_A_archive
的标识列tbl_A_archive
一个常规(非标识)int列(因为它是一个归档表,为什么你需要一个标识列?)。
SET IDENTITY_INSERT tableA ON
您必须为INSERT语句创build一个列列表:
INSERT Into tableA ([id], [c2], [c3], [c4], [c5] ) SELECT [id], [c2], [c3], [c4], [c5] FROM tableB
不喜欢“INSERT into tableA SELECT ……..”
SET IDENTITY_INSERT tableA OFF
如果您正在使用SQL Server Management Studio,则不必自己键入列列表 – 只需右键单击对象资源pipe理器中的表,然后select脚本表作为 – > select至 – > 新查询编辑器窗口 。
如果你不是,那么类似这样的查询应该有助于作为一个起点:
SELECT SUBSTRING( (SELECT ', ' + QUOTENAME(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'tbl_A' ORDER BY ORDINAL_POSITION FOR XML path('')), 3, 200000);
同意Heinzi的回答。 对于第一个选项,下面是一个在表中生成以逗号分隔的列列表的查询:
select name + ', ' as [text()] from sys.columns where object_id = object_id('YourTable') for xml path('')
对于大桌子,这可以节省大量的打字工作:)
如果“存档”表是为了你的主表的确切副本,那么我只是build议你删除这个ID是一个相同的列的事实。 这样它会让你插入它们。
或者,您可以使用以下语句允许和不允许的身份插入表中
SET IDENTITY_INSERT tbl_A_archive ON --Your inserts here SET IDENTITY_INSERT tbl_A_archive OFF
最后,如果你需要标识列的工作,那么你总是可以运行存储的过程。
sp_columns tbl_A_archive
这将返回表中的所有列,然后可以剪切并粘贴到查询中。 (这几乎总是比使用*好)
两者都会工作,但如果你仍然如果你通过使用#1错误,然后去#2
1)
SET IDENTITY_INSERT customers ON GO insert into dbo.tbl_A_archive(id, ...) SELECT Id, ... FROM SERVER0031.DB.dbo.tbl_A
2)
SET IDENTITY_INSERT customers ON GO insert into dbo.tbl_A_archive(id, ...) VALUES(@Id,....)
祝你有美好的一天。
为了将所有列名填充到用于这个问题的解决scheme的Select语句的逗号分隔列表中,我使用了下面的选项,因为它们比Andomar稍小一些。 然而,Andomar's仍然是完全可以接受的。
1)
SELECT column_name + ',' FROM information_schema.columns WHERE table_name = 'YourTable'
2)如果您有SQL Server SSMS,这可能是创build列的最简单的方法。
1)转到对象资源pipe理器中的表格,然后单击表格名称左边的+,或者双击表格名称打开子列表。
2)将列子文件夹拖到主查询区域,它会自动为您整个列列表。
如果存在标识列,则必须指定要插入的列名称。 所以命令将如下所示:
SET IDENTITY_INSERT DuplicateTable ON INSERT Into DuplicateTable ([IdentityColumn], [Column2], [Column3], [Column4] ) SELECT [IdentityColumn], [Column2], [Column3], [Column4] FROM MainTable SET IDENTITY_INSERT DuplicateTable OFF
如果你的表有很多列,那么通过使用这个命令来得到这些列的名字。
SELECT column_name + ',' FROM information_schema.columns WHERE table_name = 'TableName' for xml path('')
(删除最后一个逗号(','))只需复制过去的列名称。