2016-02-05 33 views
2

有一些表:INSERT INTO ... SELECT,如果目標列具有生成列

CREATE TABLE `asource` (
    `id` int(10) unsigned NOT NULL DEFAULT '0' 
); 

CREATE TABLE `adestination` (
    `id` int(10) unsigned NOT NULL DEFAULT '0', 
    `generated` tinyint(1) GENERATED ALWAYS AS (id = 2) STORED NOT NULL 
); 

我一個行復制從asourceadestination

INSERT INTO adestination 
SELECT asource.* 
FROM asource; 

上述生成錯誤:

Error Code: 1136. Column count doesn't match value count at row 1 

好吧,quite strange要求我提及生成查詢。但是好的,我將該列添加到查詢中:

INSERT INTO adestination 
SELECT asource.*, NULL AS `generated` 
FROM asource; 

這在5.7.10中工作正常。然而,它產生於5.7.11(錯誤due to a fix

Error Code: 3105. The value specified for generated column 'generated' in table 'adestination' is not allowed. 

確定,下一步的嘗試:

INSERT INTO adestination 
SELECT asource.*, 1 AS `generated` 
FROM asource; 

但還是同樣的錯誤我都試過0,TRUE,FALSE,但錯誤依然存在。 。

其被表示爲唯一的允許值(specsdocs)的默認值。然而,下面的生成語法錯誤(默認爲不支持那裏):

INSERT INTO adestination 
SELECT asource.*, DEFAULT AS `generated` 
FROM asource; 

那麼,如何從一個表複製一行到另一個使用INSERT INTO ... SELECT如果目標表添加了一些列,其中一些是GENERATED?

調用此查詢的代碼是通用的,並且不知道特定表具有哪些列。它只知道目標表有哪些額外的列。源表是活動表,目標表是源錶的歷史版本。它有額外的如:用戶ID進行了更改,它是什麼類型的變化(插入,更新,刪除)等時

回答

1

您必須聲明列

Insert into adestination (id, generated) 
select id, 1 
from asource; 
+0

調用此查詢的代碼是通用的,不知道特定表具有哪些列。它只知道目標表有哪些額外的列。 – alik

1

這是最好的做法幾列列出列,並將null作爲field1用於自動遞增的id字段。

INSERT INTO adestination 
(id, 
field1, 
field2) 
SELECT 
    null AS generated, 
    asource.field1, 
    asource.field2 
FROM asource; 
+1

imo,_插入時,請勿提及'autoincrement column'。如果他們在查詢中,你只能將它們混淆。如果你從不在插入查詢中提到它們,那麼它們是**確定**由數據庫引擎正確維護。 –

+0

調用此查詢的代碼是通用的,不知道特定表具有哪些列。它只知道目標表有哪些額外的列。 – alik

1

不幸的是,這正是MySQL現在如何「符合SQL標準」的工作原理。

生成的列在更新,插入等中可以接受的唯一值是DEFAULT,或者另一個選項是完全忽略該列。

我的可憐人爲這些工作,只是當我正在處理數據(如導入轉儲)時禁用生成的列,然後返回並添加生成的列表達式。

+1

謝謝(悲傷)確認。關於你禁用生成的列。我不是向「活」用戶添加架構更改權限的樂趣​​,不計算它可能會變慢。 – alik

+0

這是一個有趣的觀點,我沒有想到這一點,但是是非常煩人的。每次我嘗試使用其他工具(如HeidiSQL或Percona Online Schema Alter工具)時,它們在插入時都不起作用,因爲實際上我沒有看到它處理虛擬列的方式 –