Я хотел бы имитировать функцию автоинкрементного первичного ключа, которая есть во многих базах данных в OpenEdge (то есть не нужно указывать значение первичного ключа при выполнении INSERT) с помощью адаптера JDBC.До сих пор я подошел очень близко к тому, что мне нужно, за исключением части возможности доступа к значению первичного ключа, которое база данных генерировала при возврате из INSERT (хм, так что, возможно, не так близко;)).
Мое текущее решение использует комбинацию значения по умолчанию таблицы PK, триггера и последовательности, чтобы выполнить его:
CREATE TABLE users (
id BIGINT PRIMARY KEY DEFAULT -1,
name VARCHAR(200)
);
CREATE SEQUENCE users_seq
START WITH 0,
INCREMENT BY 1,
NOCYCLE;
CREATE TRIGGER users_trigger
BEFORE INSERT ON users
REFERENCING NEWROW
FOR EACH ROW
IMPORT
import java.sql.*;
BEGIN
Long current_id = (Long)NEWROW.getValue(1, BIGINT);
if (current_id == -1) {
SQLCursor next_id_query = new SQLCursor("SELECT TOP 1 users_seq.NEXTVAL FROM SYSPROGRESS.SYSCALCTABLE");
next_id_query.open();
next_id_query.fetch();
Long next_id = (Long)next_id_query.getValue(1,BIGINT);
next_id_query.close();
NEWROW.setValue(1, next_id);
}
END
Это позволяет мне выполнить оператор вставки, подобный этому:
INSERT INTO users(name) VALUES('Foo Bar')
и новая строка автоматически получает идентификатор из триггера базы данных.Эта часть работает нормально.
Что мне действительно нужно сейчас, так это значение идентификатора, который устанавливается;либо получить значение напрямую, либо ResultSet, который содержит только что вставленную строку (которая затем может быть развернута для просмотра идентификатора).Я знаю, что Oracle и Postgres поддерживают предложение RETURNING для вставок, как правило, это то, как это делается.Однако я не вижу ничего подобного для OpenEdge.
Единственная релевантная часть, которую я мог найти в руководстве по разработке SQL 10.2B, находится в разделе 5-10, где показано, как получить доступ к CURRVAL
последовательности после выполнения INSERT
, которая использует NEXTVAL
.Однако это опасно, так как я мог бы получить чужой ID, если для этой таблицы в течение нескольких сеансов JDBC (условия гонки и еще много чего) используется большое количество INSERT
.
Единственная альтернатива, на которую я могу прийтидо сих пор стоит написать хранимую процедуру специально для переноса / выполнения операции INSERT
, которая имеет выходной параметр идентификатора, который генерируется.Тем не менее, это неосуществимо для того, над чем я работаю, который должен использовать простой оператор SQL INSERT
, а также кажется немного хакерским и хрупким (например, как обрабатывать различные комбинации и перестановки значений, которые могут быть предоставлены).на INSERT
, и что, если схема изменится?).
Кроме того, весь смысл этого в том, что нет необходимости ссылаться на первичный ключ в INSERT, поэтому, пожалуйста, не говорите мне использоватьusers_seq.NEXTVAL
в моем INSERT
заявлении.: -)