генератор последовательностей в коде plsql в приложениях Oracle - PullRequest
0 голосов
/ 29 мая 2018

У меня есть пример таблицы, как показано ниже

PO_HEADER ||    ITEM   || LINE_NUM

   1              X 
   1              Y 
   1              Z 
   1              A 
   1              B 

Я хочу обновить порядковые номера в столбце line_num, например 1 ... 5.и когда я вхожу в другую строку, следующий порядковый номер должен генерироваться автоматически, например, 6 в столбце line_number.

Я хочу написать код для обновления порядковых номеров в line_num, а также для захвата следующего порядкового номера.Чтобы при вводе новой строки я получил следующий порядковый номер

Ответы [ 3 ]

0 голосов
/ 29 мая 2018

Люди обычно используют последовательность (объект Oracle), которая обеспечивает уникальность, но (вообще говоря) не без пробелов.Последовательность легко реализовать;вам нужно будет либо вызвать его во время вставки, либо создать триггер базы данных, в котором значение столбца будет установлено на следующий порядковый номер.

Если вы настаиваете на опции «MAX + 1», обратите внимание, что в этом случае произойдет сбоймногопользовательская среда - два или более пользователей извлекают одно и то же значение MAX, в зависимости от COMMIT момента и уникальности столбца (первичный / уникальный ключ, уникальный индекс), первый из них будет успешным, а вставка всех остальных завершится неудачей.

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

Если вы используете 12c, используйте столбец идентификаторов.В противном случае я бы предложил последовательность.

0 голосов
/ 29 мая 2018

Я бы не использовал последовательность для этого.

Если есть родительская таблица, для которой PO_HEADER является внешним ключом, захватите блокировку родительской строки.Затем SELECT MAX(line_num)+1... для этого заказа и используйте его.Не снимайте блокировку с родительской таблицы, пока не вставите вставку в TABLE1.

Если у вас нет родительской таблицы, вы можете использовать DBMS_LOCK, чтобы выполнить то же самое.(Назначьте пользовательскую блокировку, представляющую PO, и заблокируйте ее вместо родительской таблицы.)

Поскольку ваше приложение хорошо спроектировано и через этот код происходит все TABLE1 вставки, вы знаете,это будет работать.Блокировка родительской таблицы гарантирует, что две сессии не получат одинаковый номер следующей строки, потому что блокировка заставляет их действовать один за другим.

Если ваше приложение не так хорошо разработано, это вам не поможет.

0 голосов
/ 29 мая 2018

Демо: http://sqlfiddle.com/#!4/4d6ff/1

CREATE TABLE Table1
    ("PO_HEADER" int, "ITEM" varchar2(1), "LINE_NUM" int)
;

INSERT ALL 
    INTO Table1 ("PO_HEADER", "ITEM", "LINE_NUM")
         VALUES (1, 'X', NULL)
    INTO Table1 ("PO_HEADER", "ITEM", "LINE_NUM")
         VALUES (1, 'Y', NULL)
    INTO Table1 ("PO_HEADER", "ITEM", "LINE_NUM")
         VALUES (1, 'Z', NULL)
    INTO Table1 ("PO_HEADER", "ITEM", "LINE_NUM")
         VALUES (1, 'A', NULL)
    INTO Table1 ("PO_HEADER", "ITEM", "LINE_NUM")
         VALUES (1, 'B', NULL)
SELECT * FROM dual
;

create sequence alamakota;

и сейчас:

update table1 set LINE_NUM = alamakota.nextval;

select * from table1;

| PO_HEADER | ITEM | LINE_NUM |
|-----------|------|----------|
|         1 |    X |        1 |
|         1 |    Y |        2 |
|         1 |    Z |        3 |
|         1 |    A |        4 |
|         1 |    B |        5 |
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...