INSERT INTO ...如果目标列具有生成的列,则选择SELECT

时间:2016-02-05 18:25:06

标签: mysql insert-select virtual-column

有一些表格:

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
);

我将一行从asource复制到adestination

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,但错误仍然存​​在。

DEFAULT值,表示为唯一允许的值(specsdocs)。但是,以下生成语法错误(不支持DEFAULT):

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

那么,如果目标表添加了一些其中一些是GENERATED的列,那么如何使用INSERT INTO ... SELECT将一行从一个表复制到另一个表?

调用此查询的代码是通用的,并且不知道特定表具有哪些列。它只知道目标表有哪些额外的列。源表是一个实时表,目标表是源表的历史版本。它有很少的列,比如用户ID进行了更改,更改的类型(插入,更新,删除)等等。

3 个答案:

答案 0 :(得分:1)

您必须声明列

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

答案 1 :(得分:1)

最佳做法是列出列,并将null作为field1用于自动递增的id字段。

32.62

答案 2 :(得分:1)

可悲的是,这就是MySQL现在如何工作以符合SQL标准"。

生成的列在更新,插入等中可以接受的唯一值是DEFAULT,或者另一个选项是完全省略该列。

我的穷人可以解决这些问题,只是在我处理数据时禁用生成的列(比如导入转储),然后返回并添加生成的列表达式。