Как сохранить указатель на родительскую запись при вставке дочерних записей в PL / SQL? - PullRequest
1 голос
/ 28 июня 2010

У меня есть пакет, который будет вставлять одну родительскую запись в одну таблицу, и зависимые дочерние записи в другой таблице с FK на parent_id.Каждая из этих функций будет вызываться внешней программой, и все вызовы для вставки дочерних элементов могут не содержаться в одной и той же транзакции.

Интересно, есть ли для меня способ избежать отслеживанияparent_id вручную и передать его в список параметров каждой процедуры.Я подумал об использовании sys_context, но не думаю, что это сработает, потому что его не будет в одной транзакции.

Есть ли другие стратегии для этого или мне просто нужно смириться спередать parent_id каждому методу?

Ответы [ 2 ]

3 голосов
/ 28 июня 2010

Вы можете просто использовать переменную пакета следующим образом:

package body mypackage is

    g_parent_id integer;

    procedure insert_parent (...)
    is
    begin
        insert into parent (...) values (...)
        returning id into g_parent_id;
    end;

    procedure insert_child (...)
    is
    begin
        insert into child (parent_id, ...) values (g_parent_id, ...);
    end;
end;

Переменная пакета сохраняется до тех пор, пока существует ваше соединение с базой данных.Это не будет работать в среде без сохранения состояния, такой как веб-приложение.

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

1 голос
/ 29 июня 2010

Ключевой вопрос заключается в том, объединены ли сеансы в вашем вызывающем приложении или они «липкие».

Если одно и то же соединение / сеанс повторно используется вашей внешней программой для каждой транзакции, тогда сохранение parentId в переменной пакета будет правильным.

Если у вас есть пул соединений, то использование переменных пакета начинает становиться хитрым / позитивно опасным.

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

Предупреждение: если вас больше интересует упрощение API для пакета, чем производительность, и у вас есть что-то в этом роде. , ,

Для каждого вызова базы данных во внешнем приложении установите что-то, что однозначно идентифицирует вызывающий процесс, в SYS_CONTEXT или переменную пакета (у нас есть что-то вроде этого, чтобы мы могли получить вызывающий метод и «реальный», а не объединенный / b пользователь).

Создание вторичного ключа / индекса для родительской таблицы на основе этого уникального идентификатора и времени.

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

Используйте эту функцию в вашем дочернем элементе.

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