powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / updatable view + BD-триггер с ошибкой (нет "where id=old.id"): странная стат-ка и эффекты
10 сообщений из 10, страница 1 из 1
updatable view + BD-триггер с ошибкой (нет "where id=old.id"): странная стат-ка и эффекты
    #38884185
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hi all

DDL:
Код: plaintext
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.
create or alter view vdata as select 1 id from rdb$database;
create or alter trigger vdata_bd active before delete on vdata as begin end;
commit;

recreate table tdata(id int primary key using index tdata_id);
commit;
insert into tdata select row_number()over() from rdb$types rows 3;
commit;

create or alter view vdata as select * from tdata;
commit;

set term ^;

create or alter trigger vdata_bd active  before  delete on vdata as
  declare n int;
begin
      begin
           delete from tdata;  -- Здесь тумблер "ТУП" был в положении "ВКЛ.", поэтому нету очевидного:  where id = old.id ;
          n = row_count;

          rdb$set_context('USER_TRANSACTION','OLD_ID', old.id || ', rows affected: ' || n );

      end
end

^
set term ;^
commit;

Test:
Код: plaintext
SQL> delete from vdata;

Конфиг трейса:
Код: plaintext
1.
2.
3.
4.
5.
6.
enabled = true
 log_errors = true
 time_threshold = 0
  log_context = true 
 log_statement_start = true
 log_statement_finish = true
 print_perf = true

Результат в трейсе:
Код: plaintext
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.
2015-02-19T16:08:02.4280 (14695:0x7f89c80d4040) EXECUTE_STATEMENT_START
        oltp30 (ATT_128, SYSDBA:NONE, NONE, TCPv4:192.168.43.96)
        C:\MIX\firebird\fb30\isql.exe:23276
                (TRA_921, READ_COMMITTED | REC_VERSION | WAIT | READ_WRITE)

Statement 1529:
-------------------------------------------------------------------------------
delete from vdata

2015-02-19T16:08:02.4280 (14695:0x7f89c80d4040) SET_CONTEXT
        oltp30 (ATT_128, SYSDBA:NONE, NONE, TCPv4:192.168.43.96)
        C:\MIX\firebird\fb30\isql.exe:23276
                (TRA_921, READ_COMMITTED | REC_VERSION | WAIT | READ_WRITE)
[USER_TRANSACTION]  OLD_ID = "1, rows affected: 3"
 
2015-02-19T16:08:02.4280 (14695:0x7f89c80d4040) SET_CONTEXT
        oltp30 (ATT_128, SYSDBA:NONE, NONE, TCPv4:192.168.43.96)
        C:\MIX\firebird\fb30\isql.exe:23276
                (TRA_921, READ_COMMITTED | REC_VERSION | WAIT | READ_WRITE)
[USER_TRANSACTION]  OLD_ID = "2, rows affected: 0" 

2015-02-19T16:08:02.4280 (14695:0x7f89c80d4040) SET_CONTEXT
        oltp30 (ATT_128, SYSDBA:NONE, NONE, TCPv4:192.168.43.96)
        C:\MIX\firebird\fb30\isql.exe:23276
                (TRA_921, READ_COMMITTED | REC_VERSION | WAIT | READ_WRITE)
[USER_TRANSACTION]  OLD_ID = "3, rows affected: 0" 

2015-02-19T16:08:02.4280 (14695:0x7f89c80d4040) EXECUTE_STATEMENT_FINISH
        oltp30 (ATT_128, SYSDBA:NONE, NONE, TCPv4:192.168.43.96)
        C:\MIX\firebird\fb30\isql.exe:23276
                (TRA_921, READ_COMMITTED | REC_VERSION | WAIT | READ_WRITE)

Statement 1529:
-------------------------------------------------------------------------------
delete from vdata
0 records fetched
      0 ms, 45 fetch(es), 3 mark(s)

Table                             Natural     Index    Update    Insert    Delete
*********************************************************************************
TDATA                                   6                                       3

Уже на первой строке, с id = 1, "instead-of" триггер вьюхи должен был грохнуть за компанию все остальные строки. И это действительно произошло, т.к. в трейсе видим: OLD_ID = "1, rows affected: 3" .

ВОПРОС-1. Откуда тогда в этот триггер приплыли записи с OLD.ID = 2 & 3 ? Ведь они уже были грохнуты при OLD.ID = 1, а триггер работает в той же самой транзакции и, след-но, не должен был видеть эти записи.

ВОПРОС-2. Отчего кол-во NR тут в два раза больше, чем самих удалений ?

(и это еще не все вопросы, дальше про возможность / скорость установки коннекта будет :)).
...
Рейтинг: 0 / 0
updatable view + BD-триггер с ошибкой (нет "where id=old.id"): странная стат-ка и эффекты
    #38884237
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ОТВЕТ-1: стабильный курсор, аднака
ОТВЕТ-2: 3 записи прочитал select, 3 записи удалил delete
...
Рейтинг: 0 / 0
updatable view + BD-триггер с ошибкой (нет "where id=old.id"): странная стат-ка и эффекты
    #38884275
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitr,

тогда след. вопрос.

Допустим, табличка стала поширше и потяжелее:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
recreate table tlog(id int primary key, x int, y int, z int, u int, v int, w int);
commit;
insert into tlog
select
  row_number()over()
  ,rand()*100000
  ,rand()*100000
  ,rand()*100000
  ,rand()*100000
  ,rand()*100000
  ,rand()*100000
from rdb$types,rdb$types,(select 1 i from rdb$types rows 10); -- ~645 тыс строк на пустой базе для ФБ-3
commit;

И далее для неё также создаем вьюху с "instead-of" триггером, и также оставляем включённым тумблер "ТУП" для delete-команды:
Код: plaintext
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.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
create or alter view v_log as select * from tlog;
commit;

create or alter trigger v_log_biud
active before insert or update or delete
on v_log as
  declare n int;
  declare c cursor for (select rand()*10 as n from rdb$types);
begin
  if (inserting) then
      insert into tlog(id, x, y, z, u, v, w)
      values(new.id, new.x, new.y, new.z, new.u, new.v, new.w);
  else if (updating) then
      update tlog set
        x = new.x,
        y = new.y,
        z = new.z,
        u = new.u,
        v = new.v,
        w = new.w
      where id = old.id;
  else
      begin
          if ( mod(old.id-1, 20) = 0 ) then rdb$set_context('USER_TRANSACTION','DBG_BEG_ID', old.id );

           delete from tlog;   -- да, опять "ТУП" = "ВКЛ".

          if ( mod(old.id-1, 20) = 0 ) then rdb$set_context('USER_TRANSACTION','DBG_END_ID', old.id );


 -- ### NB ###
-- Если оставить закомментаренными ВСЕ нижеприведенные "бесполезные селекты", то коннект, выполняющий
-- команду "DELETE FROM VLOG;", будет невозможно срубить.
-- Если убрать комментарии с любого, отмеченного как "not helps" -- тоже самое 

-- helps:          for select 1 from rdb$types into n do begin end

 -- not helps:          for select 1 from rdb$types rows 2 into n do begin end 

-- helps,  but need wait 3 min :          for select 1 from rdb$types rows 20 into n do begin end

 -- not helps:          for select 1 from rdb$types rows 10 into n do begin end 

 -- not helps:          for select 1 from rdb$types rows 15 into n do begin end 

-- helps,  but need wait 1'40" min:           for select 1 from rdb$types rows 18 into n do begin end

-- helps,  but need wait ~6 min:           for select 1 from rdb$types rows 16 into n do begin end

 -- not helps: can connect but can not interrupt using del from mon$stt:  for select 1 from rdb$database into n do begin end 

 -- not helps:          select 1 from rdb$types rows 1 into n; 
/*
-- helps, reacts instant:
          open c;
          while (1=1) do
          begin
            fetch c into n; if (row_count=0) then leave;
          end
          close c;
*/
      end
end

^
set term ;^
commit;

Теперь в первом окошке запускаем трейс, а во втором - isql с командой delete from vlog, и даём ему поработать 1-2 минуты.
Далее пытаемся подключиться еще одним isql'ем, дабы выполнить в нём
Код: plaintext
SQL> commit; delete from mon$statements;

РЕЗУЛЬТАТ : а вот это уже зависит от того, ЧТО написано в триггере v_log_biud. Если там то, что помечено как "helps", то подключиться и отменить выполнение - получится. Хотя вполне возможно, что ждать придется несколько минут.
Если же заменить на то, что "not helps" -- то не получится даже подключиться (по кр мере, я ждал по 10 минут).

Я не понимаю, с чем это связано.
В узких кругах широко известно, что каждый коннект и стейтмент периодически проверяет, нет ли к нему запроса от мониторинга. И в частности - наличие там просьбы типа "срубись нахрен, плз!"
Однако, это делается только при условии, что коннект / стейтмент хотя бы как-то, но обращаются к БАЗЕ.
Но у меня тут ЕСТЬ обращения к базе, во ВСЕХ случаях. А реакция на просьбу типа "срубись" - далеко не всегда. Кроме того, есть смутное сомнение: скорость реакции на запрос о срубании сильно зависит от того, сколько записей промолачивает аттач в "дополнительных" обращениях к базе по типу тех, что отмечены.

Как это всё объяснить ?
...
Рейтинг: 0 / 0
updatable view + BD-триггер с ошибкой (нет "where id=old.id"): странная стат-ка и эффекты
    #38884291
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrОТВЕТ-1: стабильный курсор, аднакаСтоп! Хальт!
Если тут стабильный курсор, то для любого ID должно было быть одно и то же row_count!
То есть, в трейсе должно было быть во:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
2015-02-19T16:08:02.4280 (14695:0x7f89c80d4040) SET_CONTEXT
[USER_TRANSACTION] OLD_ID = "1, rows affected:  3 "

2015-02-19T16:08:02.4280 (14695:0x7f89c80d4040) SET_CONTEXT
[USER_TRANSACTION] OLD_ID = "2, rows affected:  3 "

2015-02-19T16:08:02.4280 (14695:0x7f89c80d4040) SET_CONTEXT
[USER_TRANSACTION] OLD_ID = "3, rows affected:  3 "

Ы ?
...
Рейтинг: 0 / 0
updatable view + BD-триггер с ошибкой (нет "where id=old.id"): странная стат-ка и эффекты
    #38884340
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидЕсли тут стабильный курсор, то для любого ID должно было быть одно и то же row_count!Курсор, который делает удаление во вьюхе - стабилен (ибо не видит удалений из триггера).
Триггер выполняется вне контекста этого курсора, так шта он видит всё как есть.
...
Рейтинг: 0 / 0
updatable view + BD-триггер с ошибкой (нет "where id=old.id"): странная стат-ка и эффекты
    #38884391
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladТаблоидЕсли тут стабильный курсор, то для любого ID должно было быть одно и то же row_count!Курсор, который делает удаление во вьюхе - стабилен (ибо не видит удалений из триггера ).
Триггер выполняется вне контекста этого курсора, так шта он видит всё как есть.А если взять курсор НЕ во вьюхе, а явно объявленный в каком-нить EB - он должен быть таким же стабильным или нет ?

Например, две таблицы, tmain2 & tdetl2, но при на удаление в tmain2 висит триггер, который опять таки грохает все записи в tdetl2:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
recreate table tmain2(id int primary key using index tmain2_id);
commit;
insert into tmain2 select row_number()over() from rdb$types rows 3;
commit;

recreate table tdata2(id int primary key using index tdata2_id);
commit;
insert into tdata2 select row_number()over() from rdb$types rows 3;
commit;

set term ^;
create or alter trigger tmain2_bd active before delete on tmain2 as
  declare n int;
begin
      begin
          delete from tdata2;
          n = row_count;

          rdb$set_context('USER_TRANSACTION','TRG_TMAIN2_BD_FIRES_FOR_OLD_ID', old.id || ', rows affected in TDATA2: ' || n );

      end
end
^
set term ;^
commit;

И теперь запускаем трейс и вот такой блочёк:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
set term ^;
execute block as
  declare  c  cursor for (select m.id  from tmain2 m natural join tdata2 d  );
  declare v_id int;
begin
  open c;
  while (1=1) do
  begin
    fetch c into v_id;
    if (row_count = 0) then leave;
    rdb$set_context('USER_TRANSACTION','CURSOR_BEFORE_DELETE_IN_TMAIN2_ID', v_id || ', rows in TDATA2: '||(select count(*) from tdata2) );
    --delete from tmain2 where current of c;
     delete from tmain2 where id = :v_id; 
    rdb$set_context('USER_TRANSACTION','CURSOR_AFTER_DELETE_IN_TMAIN2_ID', v_id || ', rows in TDATA2: '||(select count(*) from tdata2) );
  end
  close c;
end
^
set term ;^
rollback;

Должен ли курсор ' c ' быть таким же бесчувственным к удалениям, которые фигачит триггер tmain2_bd в таблице tdetl2 ?
Если да, то как объяснить вот это:
Код: plaintext
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.
2015-02-19T19:23:30.3980 (14695:0x7f89c8b23400) SET_CONTEXT
        oltp30 (ATT_139, SYSDBA:NONE, NONE, TCPv4:192.168.43.96)
        C:\MIX\firebird\fb30\isql.exe:5540
                (TRA_1051, CONCURRENCY | WAIT | READ_WRITE)
[USER_TRANSACTION] CURSOR_BEFORE_DELETE_IN_TMAIN2_ID = "1, rows in TDATA2: 3"

2015-02-19T19:23:30.3980 (14695:0x7f89c8b23400) SET_CONTEXT
        oltp30 (ATT_139, SYSDBA:NONE, NONE, TCPv4:192.168.43.96)
        C:\MIX\firebird\fb30\isql.exe:5540
                (TRA_1051, CONCURRENCY | WAIT | READ_WRITE)
[USER_TRANSACTION] TRG_TMAIN2_BD_FIRES_FOR_OLD_ID = "1, rows affected in TDATA2: 3"

2015-02-19T19:23:30.3980 (14695:0x7f89c8b23400) SET_CONTEXT
        oltp30 (ATT_139, SYSDBA:NONE, NONE, TCPv4:192.168.43.96)
        C:\MIX\firebird\fb30\isql.exe:5540
                (TRA_1051, CONCURRENCY | WAIT | READ_WRITE)
[USER_TRANSACTION] CURSOR_AFTER_DELETE_IN_TMAIN2_ID = "1, rows in TDATA2:  0 "  
-- "внешний" курсор вдруг увидел, что триггер грохнул строки. Отчего это? ^  

2015-02-19T19:23:30.3980 (14695:0x7f89c8b23400) SET_CONTEXT
        oltp30 (ATT_139, SYSDBA:NONE, NONE, TCPv4:192.168.43.96)
        C:\MIX\firebird\fb30\isql.exe:5540
                (TRA_1051, CONCURRENCY | WAIT | READ_WRITE)
[USER_TRANSACTION] CURSOR_BEFORE_DELETE_IN_TMAIN2_ID = "2, rows in TDATA2: 0"

2015-02-19T19:23:30.3980 (14695:0x7f89c8b23400) SET_CONTEXT
        oltp30 (ATT_139, SYSDBA:NONE, NONE, TCPv4:192.168.43.96)
        C:\MIX\firebird\fb30\isql.exe:5540
                (TRA_1051, CONCURRENCY | WAIT | READ_WRITE)
[USER_TRANSACTION] TRG_TMAIN2_BD_FIRES_FOR_OLD_ID = "2, rows affected in TDATA2: 0"
. . .
...
Рейтинг: 0 / 0
updatable view + BD-триггер с ошибкой (нет "where id=old.id"): странная стат-ка и эффекты
    #38884873
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидА если взять курсор НЕ во вьюхе, а явно объявленный в каком-нить EB - он должен быть таким же стабильным или нет ?Явные курсоры никто не обещал стабилизировать.
Они работают по-прежнему
...
Рейтинг: 0 / 0
updatable view + BD-триггер с ошибкой (нет "where id=old.id"): странная стат-ка и эффекты
    #38884899
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

это не внешний курсор увидел. Ты count(), то откуда берёшь. Правильно из таблицы, а не из курсора. А выполненный отдельный статмент обязан видеть изменения.

Код: plsql
1.
rdb$set_context('USER_TRANSACTION','CURSOR_AFTER_DELETE_IN_TMAIN2_ID', v_id || ', rows in TDATA2: '||(select count(*) from tdata2) );
...
Рейтинг: 0 / 0
updatable view + BD-триггер с ошибкой (нет "where id=old.id"): странная стат-ка и эффекты
    #38884905
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

+1
...
Рейтинг: 0 / 0
updatable view + BD-триггер с ошибкой (нет "where id=old.id"): странная стат-ка и эффекты
    #38884907
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

и кстати здесь как раз получается что курсор стабилен, иначе он бы не пошёл дальше этой строки

Код: plaintext
1.
2.
3.
4.
5.
2015-02-19T19:23:30.3980 (14695:0x7f89c8b23400) SET_CONTEXT
        oltp30 (ATT_139, SYSDBA:NONE, NONE, TCPv4:192.168.43.96)
        C:\MIX\firebird\fb30\isql.exe:5540
                (TRA_1051, CONCURRENCY | WAIT | READ_WRITE)
[USER_TRANSACTION] CURSOR_AFTER_DELETE_IN_TMAIN2_ID = "1, rows in TDATA2: 0" 
-- "внешний" курсор вдруг увидел, что триггер грохнул строки. Отчего это? ^ 
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / updatable view + BD-триггер с ошибкой (нет "where id=old.id"): странная стат-ка и эффекты
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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