【发布时间】:2015-03-24 13:47:26
【问题描述】:
有一个带有多个值的插入查询(大约 18k):
INSERT INTO ENTRIES (ID, USER_ID)
VALUES (nextval('my_seq'), '233'),(nextval('my_seq'), '233');
这是从 Java 应用程序中的 liquibase 变更集触发的:
JdbcConnection connection = (JdbcConnection) database.getConnection();
ResultSet resultSet = connection.prepareStatement("SELECT ID FROM USERS").executeQuery();
List<String> values = new ArrayList<>();
while (resultSet.next()) {
Long userId = resultSet.getLong(1);
for (int i = 0; i < 3; i++) {
values.add("(nextval('my_seq'), '" + userId + "')");
}
}
String sql = "INSERT INTO ENTRIES (ID, USER_ID) VALUES " + join(values, ",") + ";";
connection.createStatement().execute(sql);
当它针对 h2 数据库执行时,一切都很好,但是当我针对 postgres 运行它时,会抛出以下异常:
duplicate key value violates unique constraint "entries_pkey"
序列中的like id 正在被重复使用。
在 pgAdmin 中运行 sql 时一切正常,但从应用程序中它在第一次插入时失败。
我的第一个想法是,也许 sql 应该以不同的方式执行。
对此有什么想法吗?
这是表格说明:
CREATE TABLE entries
(
id bigint NOT NULL,
user_id bigint,
CONSTRAINT entries_pkey PRIMARY KEY (id),
CONSTRAINT fk_e3udjwux3ly7lu31huish0f82 FOREIGN KEY (user_id)
REFERENCES users (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
ALTER TABLE entries
OWNER TO app;
【问题讨论】:
-
能贴出entrys表的定义吗?
-
为什么不对 ID 字段使用默认值?让数据库处理增量就可以了,您不必再在 INSERT 语句中提及此字段了。
-
@FrankHeikens 在默认情况下使用 nextval 时会出现同样的错误。
-
条目表的主键是什么?是否可以简单地使用
INSERT INTO entries (id, user_id) ( SELECT nextval('my_seq'), id FROM users)? -
当你得到同样的错误时,你的序列不是最新的:这个序列生成的值已经被使用了。检查表中的 max(id) 和序列的当前值。
标签: java sql postgresql liquibase