2010-01-05 71 views
127

我試圖做到這一點查詢,但即使在表中標識列一個明確的價值和IDENTITY_INSERT爲上的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是一個巨大的行和寬度表,即它有很多列。我不希望手動輸入所有列。我怎樣才能使這個工作?

+0

我已經建立的方式鏈接的服務器! – jhowe 2010-01-05 10:47:21

+3

我也有這個問題,除了「插入到X選擇* Y」不是一個問題,直到我改變表架構 – FistOfFury 2013-11-18 18:17:07

回答

52

那麼,錯誤消息基本上說這一切。您有以下選擇:

  • 使列列表(在INFORMATION_SCHEMA.COLUMNS和良好的文本編輯器或解決方案的選擇由Andomar和Dave提出可以幫你這個)

OR

  • 使tbl_A_archive中的標識列成爲一個常規(非標識)int列(因爲它是歸檔表,爲什麼需要標識列?)。
+1

到您的底部解決方案: 如果列中有「IDENTITY(1,1)」或者類似的東西,他也需要暫時刪除它。 – 2016-04-11 13:37:06

+1

@AleksandrKhomenko:是的,這就是我的意思是「使[它]是一個常規(**非身份**)int列」*。 – Heinzi 2016-04-11 14:23:15

+1

對不起,我感到困惑。我的意思是,他將需要刪除**自動增量**屬性。在SQL-Server的情況下,它調用「IDENTITY(1,1)」 - 你的答案是絕對正確的。但是MySQL和Oracle對它有另一個命令(並且它變得不明顯,請看http://www.w3schools.com/sql/sql_autoincrement.asp) – 2016-04-12 08:24:44

9

如果「存檔」表是爲了您的主表的確切副本,那麼我只是建議您刪除ID是一個同名列的事實。這樣它會讓你插入它們。

或者你可以允許和不允許的身份插入的表格用下面的語句

SET IDENTITY_INSERT tbl_A_archive ON 
--Your inserts here 
SET IDENTITY_INSERT tbl_A_archive OFF 

最後,如果你需要標識列工作,因爲是那麼你可以永遠只是運行存儲過程。

sp_columns tbl_A_archive 

這將返回表中的所有列,然後您可以剪切並粘貼到查詢中。 (這幾乎總是比使用*要好)

29

如果您使用的是SQL Server Management Studio,則不必自行鍵入列列表 - 只需右鍵單擊對象瀏覽器中的表並選擇腳本表爲選擇爲新查詢編輯器窗口

如果你不是,那麼類似這樣的一個查詢應有助於爲出發點:

SELECT SUBSTRING(
    (SELECT ', ' + QUOTENAME(COLUMN_NAME) 
     FROM INFORMATION_SCHEMA.COLUMNS 
     WHERE TABLE_NAME = 'tbl_A' 
     ORDER BY ORDINAL_POSITION 
     FOR XML path('')), 
    3, 
    200000); 
+2

這可以選入一個變量並用於動態SQL查詢。你拯救了我的一天。非常感謝! – 2015-07-09 21:14:46

+1

謝謝!我用它做了這個https://gist.github.com/timabell/0ddd6a69565593f907c7 – 2015-07-24 17:20:48

+0

哇。我絕望地尋找這個動態地建立我的查詢。驚訝在這裏看到這一點。謝了哥們。 – 2016-09-05 10:39:00

12

同意Heinzi的答案。對於第一第二個選項,這裏有一個表中生成一個逗號分隔的列清單查詢:

select name + ', ' as [text()] 
from sys.columns 
where object_id = object_id('YourTable') 
for xml path('') 

對於大表,這樣可以節省很多輸入的工作:)的

+0

@謝謝,真的很有幫助。 :) – 2016-03-30 12:41:35

226
SET IDENTITY_INSERT tableA ON 

你必須做出一個列清單爲您INSERT語句:

INSERT Into tableA ([id], [c2], [c3], [c4], [c5]) 
SELECT [id], [c2], [c3], [c4], [c5] FROM tableB 

不喜歡 「INSERT INTO表A SELECT ........」

SET IDENTITY_INSERT tableA OFF 
+11

+1 ...您只需要查詢的SELECT子句中的顯式列。您可以在查詢 – MacGyver 2013-09-05 20:33:59

+6

的INSERT子句中保留一個星號...除非目標具有標識列,並且源表沒有標識列 – MacGyver 2013-10-16 23:01:50

+0

此答案比Heinzi更清晰一些,因爲它提到了SET IDENTITY_INSERT – Marty 2014-07-20 02:23:39

2

雙方將工作,但如果你仍然如果使用#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,....) 

祝你有美好的一天。

1

爲了將所有列名填充到針對此問題提及的解決方案的Select語句的逗號分隔列表中,我使用以下選項,因爲它們與Andomar's相比較少冗長。然而,Andomar's仍然是完全可以接受的。

1)

SELECT column_name + ',' 
FROM information_schema.columns 
WHERE table_name = 'YourTable' 

2)這可能是創造列最簡單的方法, 如果您有SQL服務器SSMS。

1)轉到對象資源管理器中的表格,然後單擊表格名稱左側的+或雙擊表格名稱以打開子列表。

2)將列子文件夾拖動到主查詢區域,它會自動爲您整理列整體列表。

1

如果存在標識列,則必須指定要插入的列名稱。 那麼該命令會是這樣如下:

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('') 

(刪除最後一個逗號(','))只需複製過去的列名稱。

3

對於SQL語句,還必須指定列列表。例如。

INSERT INTO tbl (idcol1,col2) VALUES (value1,value2) 

代替

INSERT INTO tbl VALUES (value1,value2) 
相關問題