Oto kod, który działa:Pobieranie id seryjny z partii wstawiony wierszy w PostgreSQL
Connection c = ds.getConnection();
c.setAutoCommit(false);
PreparedStatement stmt = c.prepareStatement("INSERT INTO items (name, description) VALUES(?, ?)");
while (!(items = bus.take()).isEmpty()) {
for (Item item : items) {
stmt.setString(1, item.name);
stmt.setString(2, item.description);
stmt.addBatch();
}
stmt.executeBatch();
c.commit();
}
Ale teraz muszę wypełnić inną tabelę gdzie id jest kluczem obcym. Jeśli używam INSERT z RETURNING id
, wówczas executeBatch
kończy się niepowodzeniem z komunikatem "Wynik został zwrócony, gdy nie był oczekiwany".
widzę kilka sposobów rozwiązania tego
- Czy indywidualną wkładkę zamiast wkładki partii.
- Zamień identyfikator seryjny na identyfikator wygenerowany przez klienta.
- Użyj jakiejś procedury przechowywanej, aby wstawić wsad i wyświetlić listę identyfikatorów.
z trzech metod, które widzę ten ostatni wydaje się zachować zarówno skuteczność wkładki wsadowym i powrócić identyfikatory, ale jest to także najbardziej skomplikowane dla mnie, nigdy nie pisałem procedur przechowywanych.
Czy istnieje lepszy sposób wstawienia partii i uzyskania identyfikatorów? Nie mam problemu z używaniem specyficznego API PostgreSQL zamiast jdbc.
Jeśli nie, czy ktokolwiek mógłby szkicować taką procedurę przechowywaną?
Oto schemat tabela:
CREATE UNLOGGED TABLE items
(
id serial,
name character varying(1000),
description character varying(10000)
)
WITH (
OIDS=FALSE
);
Spójrz na metody JDBC 'getGeneratedKeys'. Jednak nie weryfikowaliśmy tego specjalnie dla połączeń wsadowych. –
Co powiesz na zapełnianie obu tabel jednocześnie za pomocą WCTE? –
@JakubKania - co to jest WCTE? Czy możesz pokazać przykład? – mark