powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / несколько действий в rules
13 сообщений из 13, страница 1 из 1
несколько действий в rules
    #34224765
tadmin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Исполняются ли несколько действий в одном rules в рамках одной транзакции или нет?
Если нет, то можно ли повесить триггер не на таблицу, а на view?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
create view msaccess.countries as select CountryID::int4, Name from countries;

ALTER TABLE msaccess.countries ALTER COLUMN CountryID SET DEFAULT nextval('Countries_pk_seq'::regclass);

CREATE OR REPLACE RULE "_INSERT" AS
    ON INSERT TO msaccess.countries DO INSTEAD
       (
       SELECT FW_ObjectBeforeCreate( 0 , nextval('Countries_pk_seq')::int4,  79 , null, null);
       INSERT INTO countries (CountryID, name) VALUES (CURRVAL('Countries_pk_seq'),NEW.name);
       SELECT FW_ObjectAfterCreate( 0 , CURRVAL('Countries_pk_seq')::int4,  79 , true);

       );
...
Рейтинг: 0 / 0
несколько действий в rules
    #34225365
tadmin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ага.
нашел вот это:
http://sql.ru/forum/actualthread.aspx?tid=253182&hl=rules

4321кажется вы наступили на типовой грабель с неатомарностью руля.
Выходит так, что нужно писать на триггере.

Можно ли повесить триггер не на таблицу, а на view?
...
Рейтинг: 0 / 0
несколько действий в rules
    #34225440
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tadminАга.
нашел вот это:
http://sql.ru/forum/actualthread.aspx?tid=253182&hl=rules

4321кажется вы наступили на типовой грабель с неатомарностью руля.
Выходит так, что нужно писать на триггере.

Можно ли повесить триггер не на таблицу, а на view?

1. руле, думается, - таки транзакция (откатываться при ошибке батча должна целиком - можно проверить, а при нарушении поднять кипеш).

ПРоблема в другом. она
1.1. перевыполняет все (VOLATILE) ф-ии, переданные ей (в New.field по дефаулту этих field), скоко бы раз они (New.field) не упоминались. Это известный баг, исправляться, как говорят, не будет.
1.2. каждый стейтмент заново пересчитывает набор данных NEW.*, на который/ посредством которого действует. (плохо сформулировал, но найти где-то тут, в старых обсуждениях можно)

и

2. тот же пакет можно завернуть в 1-у хранимку и делать один единственный
SELECT my_batch(new.f1, new.f2 ....);
в руле, вместо пакета. Чем хуже триггера? (если другого доступа к таблицам не давать).
...
Рейтинг: 0 / 0
несколько действий в rules
    #34225685
tadmin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
4321
1. руле, думается, - таки транзакция (откатываться при ошибке батча должна целиком - можно проверить, а при нарушении поднять кипеш).
это утешительно, поскольку два моих currvalue(sequence) подряд не вернут разные значение.


4321
ПРоблема в другом. она
1.1. перевыполняет все (VOLATILE) ф-ии, переданные ей (в New.field по дефаулту этих field), скоко бы раз они (New.field) не упоминались. Это известный баг, исправляться, как говорят, не будет.
1.2. каждый стейтмент заново пересчитывает набор данных NEW.*, на который/ посредством которого действует. (плохо сформулировал, но найти где-то тут, в старых обсуждениях можно)

кажется я понял, если сам повторно внес изменения, то new.* тут же переопределится...

4321
2. тот же пакет можно завернуть в 1-у хранимку и делать один единственный
SELECT my_batch(new.f1, new.f2 ....);
в руле, вместо пакета. Чем хуже триггера? (если другого доступа к таблицам не давать).

Да, видимо это лучший выход.
Не понял только, почему меня ругают за попытку использовать perform FW_ObjectBeforeCreate(),
а select FW_ObjectBeforeCreate() внутри rule позволено делать. Процедура FW_ObjectBeforeCreate всегда возвращает 'true'
...
Рейтинг: 0 / 0
несколько действий в rules
    #34225704
tadmin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
уточнение
"использовать perform .." в теле rule
do instead
(
perform func(); --так нельзя
)


do instead
(
select func(); --так можно
)
...
Рейтинг: 0 / 0
несколько действий в rules
    #34228621
Jelis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
4321
ПРоблема в другом. она
1.1. перевыполняет все (VOLATILE) ф-ии, переданные ей (в New.field по дефаулту этих field), скоко бы раз они (New.field) не упоминались. Это известный баг, исправляться, как говорят, не будет.


А можно это немножко поподробнее разяснить, а то что-то я смысл недогоняю?
...
Рейтинг: 0 / 0
несколько действий в rules
    #34228692
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JelisА можно это немножко поподробнее разяснить, а то что-то я смысл недогоняю?
предположим, в id у вас оперделен DEFAULT mysuperfun('anyparam').
так вот, если вы в руле несколько раз напишете New.id, а при передаче в rule (в стейтменте, которое исертит) id не упоминалось - то каждое упоминание New.id вызовет новое срабатывание mysuperfun('anyparm').

подробнее - см например тут поиском. догонишь, и ссылку на описание траблы на родном сайте постгриса найдешь. и ответы разработчиков по ссылкам тоже.
...
Рейтинг: 0 / 0
несколько действий в rules
    #34228888
Jelis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Аааа.... догнал! Спасиба! :-)
А если функция IMMUTABLE - то тогда тоже каждый раз вызов этой функции в рулесе будет? Хотя чего ее вызывать то, если параметр не изменился. Мда.... хотя некоторая логика в этом тоже есть, но странная : одним словом - "особенность" :-)
...
Рейтинг: 0 / 0
несколько действий в rules
    #34228899
Jelis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А если NEW.id это nextval() то он тоже будет каждый раз новый браться в пределах одного рулеса????
...
Рейтинг: 0 / 0
несколько действий в rules
    #34228948
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JelisА если NEW.id это nextval() то он тоже будет каждый раз новый браться в пределах одного рулеса????
гм . А поиск так и не попробовали?
rule+default+nextval
...
Рейтинг: 0 / 0
несколько действий в rules
    #34249753
tadmin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
попробовал переписать на ХП

Rules:
Код: plaintext
1.
2.
3.
CREATE OR REPLACE RULE "_INSERT" AS
    ON INSERT TO msaccess.countries DO INSTEAD   (
       SELECT msaccess.countrygen(NEW.name);
         );

Функция:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
CREATE OR REPLACE FUNCTION msaccess.countrygen(in_Name VARCHAR( 64 )) RETURNS ?ЧтоИменно?  AS $$
DECLARE
   seq_id  INT8;
BEGIN
   seq_id:=NEXTVAL('Countries_pk_seq');
   PERFORM FW_ObjectBeforeCreate( 0 , seq_id::int4,  79 , null, null);
   INSERT INTO countries (CountryID, name) VALUES (seq_id::int4, in_Name);
   PERFORM FW_ObjectAfterCreate( 0 , seq_id::int4,  79 , true);

RETURN   ?ЧтоИменно?  ;
END;
$$ language 'plpgsql' security definer;

очевидно, что функция msaccess.countrygen должнв возращать одну и только одну запись из таблицы msaccess.countries. Если функция ничего не возвращает, то rules откатывает транзакцию.

Для проверки добавил лишний insert в тело rules, вот так:
Код: plaintext
1.
2.
3.
4.
CREATE OR REPLACE RULE "_INSERT" AS
    ON INSERT TO msaccess.countries DO INSTEAD   (
       SELECT msaccess.countrygen(NEW.name);
       INSERT INTO countries (CountryID, name) VALUES (NEXTVAL('Countries_pk_seq'), NEW.name);
      );

после чего записи (естественно) дублируются.

Как именно вернуть из функции Setof данных, чтобы rules был доволен?
...
Рейтинг: 0 / 0
несколько действий в rules
    #34249794
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tadmin
Код: plaintext
1.
CREATE OR REPLACE FUNCTION msaccess.countrygen(in_Name VARCHAR( 64 )) RETURNS ?ЧтоИменно?  AS $$

void не провали?

tadmin очевидно????, что функция msaccess.countrygen должнв возращать одну и только одну запись из таблицы msaccess.countries. Если функция ничего не возвращает, то rules откатывает транзакцию.
гм. у вас руле не на селект, а на инсерт. Почему ф-я внутре инсерта должна что-то возвращать?

tadminКак именно вернуть из функции Setof данных, чтобы rules был доволен?если надо вернуть сетоф - возвращайте. только сначала объясните, почему он вам нужен. И какой.
...
Рейтинг: 0 / 0
несколько действий в rules
    #34249931
tadmin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
4321
tadmin очевидно????, что функция msaccess.countrygen должнв возращать одну и только одну запись из таблицы msaccess.countries. Если функция ничего не возвращает, то rules откатывает транзакцию.
гм. у вас руле не на селект, а на инсерт. Почему ф-я внутре инсерта должна что-то возвращать?
эээ...
я тут не прав, конечно.
Rules on insert не обязан ничего возвращать, но если view, на которой висит rules on insert, смонтирована по ODBC в MS Access, то происходит следующее:
- вставка данных в смонтированную таблицу
- запускается rules on insert
- запускается ХП
- Акцесс не видит результатов вставки
- rules откатывает все изменения, в том числе - изменения сделаные ХП.

с чем я и столкнулся.

4321
tadminКак именно вернуть из функции Setof данных, чтобы rules был доволен?если надо вернуть сетоф - возвращайте. только сначала объясните, почему он вам нужен. И какой.
Мне кажется, возможно необоснованно, что ODBC пугается, не получив данные после вставки.
"размер поля недостаточен, чтобы принять добавляемы данные".

Если я в тело rules on insert после вызова ХП добавлю insert явным образом (последний пример), то срабатывают обе вставки: добавил country='Russia', появилось две строки 'Russia' с разными идентификаторами, которые выдала ХП и insert в теле rules.
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / несколько действий в rules
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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