Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / несколько действий в rules / 13 сообщений из 13, страница 1 из 1
26.12.2006, 12:18
    #34224765
tadmin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
несколько действий в rules
Исполняются ли несколько действий в одном 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
26.12.2006, 15:05
    #34225365
tadmin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
несколько действий в rules
Ага.
нашел вот это:
http://sql.ru/forum/actualthread.aspx?tid=253182&hl=rules

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

Можно ли повесить триггер не на таблицу, а на view?
...
Рейтинг: 0 / 0
26.12.2006, 15:25
    #34225440
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
несколько действий в rules
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
26.12.2006, 16:35
    #34225685
tadmin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
несколько действий в rules
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
26.12.2006, 16:39
    #34225704
tadmin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
несколько действий в rules
уточнение
"использовать perform .." в теле rule
do instead
(
perform func(); --так нельзя
)


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


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

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

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
11.01.2007, 18:02
    #34249794
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
несколько действий в rules
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
11.01.2007, 18:45
    #34249931
tadmin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
несколько действий в rules
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
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / несколько действий в rules / 13 сообщений из 13, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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