2015-01-26 5 views
0

Существует одна вставки запрос с несколькими значениями (около 18k):множественная вставка с последовательностью проваливается в Postgres

INSERT INTO ENTRIES (ID, USER_ID) 
VALUES (nextval('my_seq'), '233'),(nextval('my_seq'), '233'); 

Который уволен из LiquiBase ревизии в Java-приложениях:

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" 

Как идентификатор из последовательности, используется повторно.

При запуске sql в pgAdmin все в порядке, но из приложения он терпит неудачу при первой вставке.

Моя первая мысль состоит в том, что, возможно, 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; 
+1

Можете ли вы опубликовать определение таблицы записей? – Patrick

+0

Почему вы не используете значение по умолчанию для ID-поля? Пусть база данных обрабатывает приращения, и все в порядке, вам больше не нужно упоминать это поле в ваших инструкциях INSERT. –

+0

@FrankHeikens при использовании nextval по умолчанию является той же ошибкой. – sandris

ответ

1

Я думаю, что ваш счетчик последовательности должен быть сброшен (возможно, вы уже вручную введенные цифры в таблице вместо использования NEXTVAL так счетчик не увеличивается) и ее предоставление вы уже имеете в своем столе. Попытка переустановку его с чем-то вроде

ALTER SEQUENCE my_seq RESTART 100000; 

Где 100000 это число больше:

SELECT MAX(id) FROM entries; 
+0

проблема в том, что это происходит на пустой таблице, данные вставляются только с этим запросом на вставку. так что это невозможно. – sandris

+0

sandris, извините пропустил считывание эта часть. Ваш код для jdbc того, что мало помню о jdbc, выглядит отлично (кроме user_id не следует указывать, если целое число). Хотя это не вызовет вашей проблемы. – LR1234567

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

Вставьте эту таблицу без ссылки на «id» вообще.

INSERT INTO ENTRIES (USER_ID) 
VALUES ('233'),('233'); 

Или используйте значение по умолчанию.

INSERT INTO ENTRIES (ID, USER_ID) 
VALUES (default, '233'),(default, '233'); 

В этом контексте по умолчанию не является строкой. (Нет кавычек.)

0

Код был верным, проблема была в размере последовательности - она ​​была слишком мала для вставки 18k.

Смежные вопросы