尝试复制现有行的所有列,其中只有一列将更改(称为“字段”),并且自动生成的主键字段(称为“id”)应该像往常一样由insert语句生成,我天真的做法是:
drop table if exists temp1;
create table temp1 as
(
SELECT *
FROM original
WHERE field="old value"
)
;
# Update one of the many fields to a new value
UPDATE temp1
SET field = "new value"
;
# Getting rid of the primary key in the hope that a new one will be auto generated in the following insert
ALTER TABLE temp1 DROP id;
# Fails with syntax error. How can I specify "generate new id" ?
INSERT INTO original
SELECT NULL as id, *
FROM temp1
;
这会因语法错误而失败,因为不允许在最后一个select语句中将 NULL作为id 。那我该怎么做呢?有更简单的方法吗?
答案 0 :(得分:0)
SELECT *
是反模式。您应该明确设置列:
INSERT INTO original(col1, col2, ...) --skip id column
SELECT col1, col2, ...
FROM temp1;
或者甚至更好地跳过temp1表。单一陈述解决方案:
INSERT INTO original(col1, col2, ..., field) -- skip id column
SELECT col1, col2, ..., 'new_value'
FROM original
WHERE field='old value';
为了得到你想要的东西,你需要像Oracle DEFAULT Values On Explicit NULLs这样的机制。
但即使这样你也需要从temp1中删除列,因为:
INSERT INTO original -- only N column
SELECT NULL as id, * -- this will return N+1 columns
FROM temp1;
所以你必须使用:
ALTER TABLE temp1 DROP COLUMN id;
-- now columns match
INSERT INTO original -- only N column
SELECT NULL as id, * -- this will return N columns and
-- NULL is handled by DEFAULT ON NULL
FROM temp1;