powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Вопрос по триггерам
3 сообщений из 3, страница 1 из 1
Вопрос по триггерам
    #39411470
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В БД есть понятия Клиент (таблица CUSTOMERS), Счет (таблица ACCOUNTS), Услуга (таблица SERVICES) и другие сущности.
Клиент может принадлежать какой-то определенной группе (CUSTOMERS.GROUP_ID).
В БД работают пользователи, права доступа которых определяются на уровне клиентской группы (например к одной группе у пользователя доступа нет вообще, в другой группе доступ только на просмотр, в третьей группе доступны все действия, кроме удаления).
В таблицах ACCOUNTS и SERVICES тоже есть поле GROUP_ID, по всей видимости оно выполняет вспомогательные функции, т.к. в пользовательском интерфейсе не предусмотрена возможность задания групп в Счетах или Услугах.
Группа Клиента может изменятся, в информационной системе это обеспечивает следующий программный код:

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
# treat group_id specially 
my $group_id = $cgi->param('group_id');

if ($group_id ne '') {
    $auth->action(action_name => ['move_customer']);

    if ($auth->staff->can_do($auth->action, $group_id) &&
        $auth->staff->can_do($auth->action, $customer->group_id) &&
        $group_id != $customer->group_id) {
        # Change group.. 
        $alog->log(action               => 'edit_customer',
                   customer             => $customer,
                   new_value            => $group_id,
                   old_value            => $customer->group_id,
                   staff_comment        => "changed field `group_id`");

        $customer->group_id($group_id);

        # update group_id in accounts & services for this customer 

        foreach my $tbl (qw(accounts
                            services
                            bm_agreement
                            bm_payment
                            bm_invoice
                            bm_bill
                            bm_action_log)) {
            my $q = qq{UPDATE $tbl
                   SET          group_id = $group_id
                   WHERE        customer_id = $customer_id AND group_id IS NOT NULL};
            $dbh->do($q);
        }

        $dbh->do("UPDATE bm_payorder SET group_id = $group_id WHERE account_id IN  
                  (SELECT account_id FROM accounts WHERE customer_id = $customer_id)");

        $dbh->do(qq{UPDATE bm_invoice_item
                    SET group_id = $group_id
                    WHERE account_id IN (select account_id from accounts where customer_id = $customer_id) AND group_id IS NOT NULL});
    }
}



Программный код на Perl, суть его в том, что при изменении группы вначале обновляется CUSTOMERS.GROUP_ID, а затем обновляется GROUP_ID во всех связанных таблицах.
То есть в теории GROUP_ID у всех подчиненных данных должен соответствовать CUSTOMERS.GROUP_ID.
Но почему-то это происходит не всегда, видимо в информационной системе есть недоработки или баги, из-за которых GROUP_ID обновляется не всегда и CUSTOMERS.GROUP_ID может отличаться от SERVICES.GROUP_ID, что приводит к неприятным побочных эффектам (пользователи не могут редактировать Услуги, т.к. группа на Услуге отличается от группы на Клиенте, а у пользователя нет прав для работы с группой Услуги).
Происходит это нечасто, время от времени я вручную синхронизирую группы подчиненных записей, но хотелось бы автоматизировать процесс.
Я хочу задать для таблицы CUSTOMERS триггер на обновление поля GROUP_ID, в котором буду обновлять группу во всех подчиненных записях. Но прежде чем это делать на production-сервере, хотелось бы вначале спросить, на что вначале следует обратить внимание и какие возможны побочные эффекты.

________________________
Мы смотрим с оптимизмом...
...в оптический прицел.
...
Рейтинг: 0 / 0
Вопрос по триггерам
    #39411626
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И еще уточню.
В приведенном коде я не вижу возможностей для описанного сбоя (когда группа Клиента и Услуги различается).
Скорее всего группа обновляется еще где-то, но найти это место не представляется возможным, это больше 8 МБ исходных кодов.
Я думаю, что скорее всего где-то выполняется update SERVICES set GROUP_ID = ...
Поэтому вопрос такой — если я задам триггер на таблицу SERVICES, чтобы при обновлении столбцу GROUP_ID всегда присваивалось значение с родительской записи в CUSTOMERS — возможно ли тут зацикливание или взаимная блокировка? В БД триггеров нет совсем (вернее есть, но только на PK, заполнение новых значений из sequence).
...
Рейтинг: 0 / 0
Вопрос по триггерам
    #39412196
Фотография Immunitet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дратути,
Alibek B.В таблицах ACCOUNTS и SERVICES тоже есть поле GROUP_ID, по всей видимости оно выполняет вспомогательные функции, т.к. в пользовательском интерфейсе не предусмотрена возможность задания групп в Счетах или Услугах.

Есть подозрение, что эти поля реализуют нечто похожее на механизм Oracle Label Security - выборочный доступ к данным одной и той же таблицы разными пользователями.
Подозреваю, что группа у того или иного пользователя меняется не часто (как и сама таблица CUSTOMERS), т.е. ваш триггер будет вызываться редко, а значит и существенных проблем для производительности приложения не создаст. Вообще, я бы посмотрел на связи между таблицами - REFERENCE CONSTRAINTS, а то вдруг закусится ваш триггер с одним из них.
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Вопрос по триггерам
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]