有没有一种方法可以向一个没有自动递增ID的表中插入新记录而不需要特别输入ID。我只想让ID成为lastId+1。
INSERT INTO lists VALUES (lastId+1,'KO','SPH', '5')
//新的IDINSERT INTO lists VALUES (lastId+1,'KO','SPH', '5')
//新的ID不要这样做!绝对不要!甚至不要考虑这么做!
这个错误的解决方案可能看起来(实际上并不是)能对你起作用:
INSERT INTO lists VALUES ((SELECT max(id)+1 FROM lists),'KO','SPH', '5');
但是,如果有人在你同时插入数据,你们都会得到相同的id
,这将导致无效结果。您真的应该使用一个sequence
或一些更可靠的机制(当您无法在序列中留下空洞时,辅助表是常见的选择,但它也有一些缺点[它会锁定])。您甚至可以使用serial
数据类型使其更加简便(它会在底层创建一个序列):
CREATE TABLE lists(id serial, col2 text, col3 text, ...);
-- If you don't specify "id", it will autogenerate for you:
INSERT INTO lists(col2, col3, ...) VALUES('KO','SPH', ...);
-- You can also specify using DEFAULT (the same as above):
INSERT INTO lists(id, col2, col3, ...) VALUES(DEFAULT, 'KO','SPH', ...);
如果您真的、真的、真的无法创建和使用序列,您可以像上面那样操作,但是您需要处理异常(假设 id
字段是PK或UK,并使用读取提交的事务),就像这样(在PL/pgSQL中):
DECLARE
inserted bool = false;
BEGIN
WHILE NOT inserted LOOP;
BEGIN
INSERT INTO lists
VALUES ((SELECT coalesce(max(id),0)+1 FROM lists),'KO','SPH', '5');
inserted = true;
EXCEPTION
WHEN unique_violation THEN
NULL; -- do nothing, just try again
END;
END LOOP;
END;
但是,我强烈建议您避免使用它:使用序列,并且很高兴... =D
此外,我知道这只是一个例子,但在INSERT INTO
子句中使用显式列列表。
max
将返回 NULL
(而 NULL+1
返回 NULL
),您可以使用 COALESCE
轻松处理它,我将更新答案来实现这一点。 - MatheusOl