2011-10-09 86 views
15

我使用MySQL GUI通過選擇某些表並將從備份轉儲生成的INSERT語句運行到空表(新模式)中,將某些站點遷移到新版本的CMS。有在不新一個存在的舊錶數列,所以腳本這樣的錯誤停止:在「字段列表」有沒有辦法忽略INSERT上不存在的列?

1個未知列「USER_ID」:

腳本行

櫻桃挑選所需的列導出,或編輯轉儲文件將是太繁瑣和耗時。要解決這個問題,我會在生成錯誤時創建未使用的列,通過運行查詢導入數據,然後在完成該表時刪除未使用的列。我看過INSERT IGNORE,但這似乎是忽略重複鍵(不是我要找的)。

有什麼辦法可以在忽略目標表中不存在的列的同時執行INSERT?我正在尋找「無痛」的東西,就像現有的一些SQL功能一樣。

爲了澄清,我正在處理一堆備份文件,並將數據導入本地數據庫進行測試,然後再將其移至活動服務器。該種方案的例子中,我希望:

-- Don't try to insert data from columns that don't exist in "new_table" 
INSERT INTO `new_table` {IGNORE UNKNOWN COLUMNS} (`id`, `col1`, `col2`) VALUES 
    (1, '', ''), 
    (2, '', ''); 

如果這樣的事情是不存在的,我很樂意接受,作爲一個答案,並繼續使用我目前的解決方法。

+1

如果字段列表提到不存在的列,它可能包含偶然匹配的列。無論你知道什麼,它可能是表名是錯誤的,使你無意中在無效的表中插入無效的數據。這是一個非常糟糕的主意。如果插入錯誤,讓它失敗。 – GolezTrol

+0

如果使用不當或「意外」,有很多危險的查詢是危險的,我不明白爲什麼這會是任何異常。 –

+0

當然,但查詢中不存在的列表示直接錯誤,並且會失敗。 INSERT也不例外。 SELECT查詢也會失敗。 – GolezTrol

回答

5

你目前的技術似乎夠實用。只是一個小小的改變。

與其等待錯誤然後逐個創建列,您可以導出模式,做一個比較並找出所有表中所有缺失的列。

這樣做會少一些工作。

您的gui將能夠導出剛纔的模式或mysqldump上的以下開關將有助於找出所有缺少的列。

mysqldump --no-data -uuser -ppassword --database dbname1 > dbdump1.sql 
mysqldump --no-data -uuser -ppassword --database dbname2 > dbdump2.sql 

通過對dbdump1.sql和dbdump2.sql進行區分可以使您在兩個數據庫中都有所區別。

+0

好的補充,在從一個數據庫模式遷移到另一個數據庫模式時非常有用。 +50。 – Kaivosukeltaja

3

你可以寫一個存儲功能類似:

sf_getcolumns(table_name varchar(100)) 

返回字符串指含有的申請表是這樣的: 'field_1,field_2,field_3,......'

然後創建一個存儲過程

sp_migrite (IN src_db varchar(50), IN target_db varchar(50)) 
運行trugh表和每個表獲取申請表,然後

創建像

字符串
cmd = 'insert into ' || <target_db><table_name> '(' || <fileds_list> || ') SELECT' || <fileds_list> || ' FROM ' <src_db><table_name> 

然後執行字符串中的每個表

+1

我不得不承認,我不確定這意味着什麼 - 但它看起來比它的價值更麻煩?我想我希望能找到一個關鍵字,或者我可以添加到現有的'INSERT'腳本中,以便忽略未知列,因爲我已經有了自己的解決方法。我會看看如果我能理解這一點,並給它一個鏡頭,謝謝。我正在使用現有的備份文件,所以不太確定這是我所追求的。 –

+0

我看到這有一個投票,所以我認爲這不是一個壞的解決方案(即使我有限的SQL技能不能理解它)。我是否應該從這個答案中假設我所特別尋找的*不存在? –

+2

@WesleyMurch - 是的。這真是一個** TERRIBLE **的想法,讓你的引擎處理場失準。它表明你不知道你在插入什麼,這是一個主要問題。 – JNK

0

dbForge Studio for MySQL會給你一個機會,compare and synchronize數據的兩個數據庫之間。

默認情況下,僅對名稱相同的對象執行數據比較;您可以使用自動映射或手動映射數據庫對象。 dbForge Studio允許您自定義表和列的映射,以便您可以比較具有不同名稱,所有者和結構的對象的數據。您也可以映射不同類型的列,但這可能會導致數據截斷,舍入以及某些類型同步期間的錯誤。

0

發現你的問題有趣。

我知道有一種方法可以從MySQL中的表中選擇列名;它是show columns from tablename。我忘記了所有的MySQL表數據都保存在一個特殊的數據庫中,名爲「information_schema」。

這是邏輯的解決方案,但它不工作:

mysql> insert into NEW_TABLE (select column_name from information_schema.columns where table_name='NEW_TABLE') values ... 

我會繼續關注,雖然。如果可以從select column_name查詢中獲取以逗號分隔的值,則可能正在進行業務。

編輯:

可以使用select ... from ... into命令生成一個行CSV,如下所示:

mysql> select column_name from information_schema.columns where table_name='NEW_TABLE' into outfile 'my_file' fields terminated by '' lines terminated by ', ' 

我不知道如何得到這個輸出到MySQL CLI標準輸出,但。

1

有什麼辦法來執行INSERT,而忽略目標表中不存在的列?我正在尋找「無痛」的東西,就像現有的一些SQL功能一樣。

不,沒有「無痛」的方式來這樣做。

相反,您必須顯式處理那些最終表中不存在的列。例如,您必須將它們從輸入流中移除,在事實之後放棄它們,玩弄骯髒的技巧(engine=BLACKHOLE +觸發器,以僅插入您想要的真實目標架構的內容),無論如何。

現在,這不一定需要是手冊 - 有工具(如Devart noted)以及查詢db目錄以確定列名稱的方法。但是,它不像簡單地註釋INSERT語句那麼簡單。

也許CMS供應商可以提供合理的遷移腳本?

+0

感謝您的直接回答,不幸的是我是CMS供應商:)我有一個最新版本的遷移系統,但試圖從一個更舊的版本快速啓動更新。 –

0

我仔細閱讀所有這些帖子,因爲我有同樣的挑戰。請檢查我的解決方案:

我在c#中做了它,但您可以使用任何語言。

檢查列名的插入語句。如果你的實際表中缺少任何東西,請將它們添加爲TEXT列,因爲TEXT可以吃任何東西。

當完成插入該表時,刪除添加的列。

完成。

相關問題