有一个带有多个值的插入查询(大约18k):
INSERT INTO ENTRIES (ID, USER_ID)
VALUES (nextval('my_seq'), '233'),(nextval('my_seq'), '233');
这是从java应用程序中的liquibase changeset触发的:
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"
像来自sequance的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;
答案 0 :(得分:1)
我的猜测是您的序列计数器需要重置(可能您已经在表中手动输入了数字而不是使用nextval,因此计数器没有增加)并且它会给出表中已有的数字。尝试用
之类的东西重新设置它ALTER SEQUENCE my_seq RESTART 100000;
其中100000是一个大于的数字:
SELECT MAX(id) FROM entries;
答案 1 :(得分:0)
根据经验,如果你的dbms可以自动执行某些操作,你就不应该自己尝试。
CREATE TABLE entries
(
-- bigserial provides automatic sequence numbers under
-- dbms control.
id bigserial 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
);
插入此表而不参考&#34; id&#34;一点都不。
INSERT INTO ENTRIES (USER_ID)
VALUES ('233'),('233');
或使用&#34;默认&#34;值。
INSERT INTO ENTRIES (ID, USER_ID)
VALUES (default, '233'),(default, '233');
在此上下文中,默认不是字符串。 (没有引号。)
答案 2 :(得分:0)
代码是正确的,问题是序列的大小 - 它对于18k插入来说太小了。