2009-08-12 84 views
7

我想從備份表foo_bk中將所有記錄插入到foo表中而不指定列。SQL:將所有記錄從一個表插入到另一個表,但沒有指定列

,如果我嘗試此查詢

INSERT INTO foo 
SELECT * 
FROM foo_bk 

我會得到錯誤「插入錯誤:列名或提供值的數目不匹配表定義。」

是否可以在不提供列名的情況下從一個表執行批量插入操作? 我已經谷歌,但似乎無法找到答案。所有的答案都需要特定的列。

回答

2

您需要至少具有相同數量的列,並且每列必須以完全相同的方式定義,即varchar列不能插入到int列中。

對於批量傳輸,請檢查您正在使用的SQL實現的文檔。通常可以使用工具將數據從一個表格批量傳輸到另一個表格。例如,對於SqlServer 2005,您可以使用SQL Server導入和導出嚮導。右鍵單擊您嘗試移動數據的數據庫,然後單擊「導出」以訪問它。

1

SQL 2008允許你放棄你的SELECT指定的列名,如果你使用SELECT INTO,而不是INSERT INTO/SELECT:

SELECT * 
INTO Foo 
FROM Bar 
WHERE x=y 

INTO條款並在SQL Server 2000 - 2005年存在的,但仍需要指定列名稱。 2008似乎增加了使用SELECT *的能力。

有關詳細信息,請參閱INTO(SQL2005),(SQL2008)上的MSDN文章。

但是,INTO子句只適用於目標表尚不存在的情況。如果您正在尋找將記錄添加到現有表格,這將無濟於事。

+1

這將僅適用於新表。 – JeffO 2009-08-12 17:15:48

+1

如果表已存在,則INTO不起作用。 – HLGEM 2009-08-12 17:15:52

+0

是的,你可以選擇*進入Sql Server 2000 – HLGEM 2009-08-12 17:16:23

16

你不應該想這樣做。選擇*不應該用作插入的基礎,因爲列可能會移動並破壞插入(或者更糟糕的是,不會破壞插入,但會混淆數據。假設某人在select中添加了一列而不是在其他表中,你的代碼將會中斷,或者假設某人因爲超越理解而頻繁發生的原因,決定在表格上進行刪除和重新創建,並將列移動到不同的順序,現在你的姓氏是first_name最初選擇*會將它放在另一個表的錯誤列中,這是一種極其糟糕的做法,未能指定列以及某個列的特定映射到您想要的表中您感興趣的列的特定映射中。

現在你可能有幾個問題,首先兩個結構不直接匹配,或者第二個表被插入到具有身份的公司lumn等,儘管可插入列是直接匹配的,但表被插入到比其他列多一列,並且通過不指定數據庫假定您將嘗試插入到該列。或者你可能有相同數量的列,但一個是身份,因此不能插入(雖然我認爲這將是一個不同的錯誤信息)。

10

每本的其他職務:Insert all values of a...,你可以做到以下幾點:

INSERT INTO new_table (Foo, Bar, Fizz, Buzz) 
SELECT Foo, Bar, Fizz, Buzz 
FROM initial_table 

通過其他的答案指示指定的列名是很重要的。

0

正如您從以前的答案中可能已經理解的那樣,您無法真正做到您所追求的目標。 我想你可以理解SQL Server遇到的問題,不知道如何映射附加/缺失列。

這就是說,既然你提到你想要在這裏做什麼的目的是備份的,也許我們可以使用SQL Server並解決這個問題。 不知道您的具體情況使得它不可能有正確的答案猛擊這裏,但我相信以下幾點:

  • 要管理備份/審計過程的表。
  • 您可能只有其中的一些,並希望避免在每列添加/刪除時更改相關對象。
  • 備份表可能包含用於審計目的的其他列。

我想建議兩個選項供您:

有效的做法(IMO)對此我們可以利用DDL觸發器來檢測架構更改,並使用它們相應地改變備份表。這將使您能夠使用'select * from ...'方法,因爲列表列表在兩個表格之間是一致的。

我已經成功地使用了這種方法,您可以利用它來讓DDL觸發器自動管理您的審計表。就我而言,我使用了一個需要審計的表的命名約定,而DDL觸發器只是在運行中管理它。

另一個可能對您的特定場景有用的選項是爲對齊列列表的表格創建支持視圖。這裏有一個簡單的例子:

create table foo (id int, name varchar(50)) 
create table foo_bk (id int, name varchar(50), tagid int) 
go 

create view vw_foo as select id,name from foo 
go 

create view vw_foo_bk as select id,name from foo_bk 
go 

insert into vw_foo 
    select * from vw_foo_bk 
go 

drop view vw_foo 
drop view vw_foo_bk 
drop table foo 
drop table foo_bk 
go 

我希望這有助於:)

9

使用此

SELECT * 
INTO new_table_name 
FROM current_table_name 
+3

請注意,這隻在創建新表時才起作用。 I.E.它的功能就像備份。聲明中可能顯而易見,但我想重申一遍。謝謝!這很有用:) – Shrout1 2013-05-23 19:04:21

+0

你不需要在這個查詢中創建,這與insert一起也會創建新表 xameeramir 2014-04-14 14:27:59

相關問題