Правильная реализация автоинкрементных первичных ключей в OpenEdge 10.2B с использованием SQL / JDBC - PullRequest
1 голос
/ 18 марта 2012

Я хотел бы имитировать функцию автоинкрементного первичного ключа, которая есть во многих базах данных в 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 заявлении.: -)

Ответы [ 2 ]

1 голос
/ 12 июня 2012

Нет жизнеспособных способов реализовать это;пользователь должен либо указать значение для PK, либо указать имя последовательности, чтобы можно было использовать CURRVAL / NEXTVAL.

Невозможный обходной путь заключается в создании специальной хранимой процедуры, специально предназначенной для выполненияINSERT, но это не общее решение, поскольку команда INSERT принимает переменное число параметров (не в последнюю очередь из которых являются столбцы и данные для заполнения), в то время как хранимая процедура должна иметь фиксированное количество параметров.

Если бы существовала функция SQL, которая бы возвращала специальный идентификатор сеанса, который соответствует временному соединению клиента с механизмом SQL, было бы возможно, чтобы клиент и триггер / хранимая процедура взаимодействовали с использованием заранее определенной таблицыкак очередь запросов (используя идентификатор сеанса в качестве ключа).К сожалению, согласно документации, такой идентификатор сессии отсутствует.

0 голосов
/ 15 мая 2012

1 глупый вопрос ... Почему вы используете этот код SQL для обновления данных в Progress DB? Это проще сделать в коде 4GL (соответственно ABL) ... Вы должны сделать простую процедуру создания или службу на сервере приложений. У меня была такая же проблема с доступом ODBC SQL из инструмента миграции (ложка). Я должен сдаться ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...