Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / row_count внутри VALUES()-списка команды insert (ввод после DML): почему она всегда ноль ? / 14 сообщений из 14, страница 1 из 1
05.03.2016, 17:57
    #39186493
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
row_count внутри VALUES()-списка команды insert (ввод после DML): почему она всегда ноль ?
hi all

Есть after-триггер, навешенный на таблиу t1, в котором идёт запись в лог её изменений (t2) , а также добавление при каждом DML одной строки в еще один, "дурацкий лог", - таблицу t2log. И добавление в t2log использует переменную row_count.
Внезапно выяснилось, что вот этот код:
Код: 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.
recreate table t1(id int, x int);

recreate table t2(evt char(3), new_id int, new_x int, old_id int, old_x int);
recreate table t2log(evt char(3), affected_rows int);
commit;

set term ^;
create trigger t1_aiud after insert or update or delete on t1 as
    declare rc int;
begin
    if (inserting) then
        begin
            insert into t2(evt, new_id, new_x) values ('ins', new.id, new.x);
            insert into t2log(evt, affected_rows) values('ins', row_count);
        end
    else if (updating) then
        begin
            update t2 set 
                evt='upd', 
                old_id = old.id, old_x = old.x, 
                new_id = new.id, new_x = new.x
            where new_id = old.id;

            insert into t2log(evt, affected_rows) values('upd', row_count);
             --rc = row_count;
            --insert into t2log(evt, affected_rows) values('upd', :rc); 
        end
    else
        begin
            update t2 set evt='del', old_x = old.x, new_id = null, new_x = null
            where new_id = old.id;
            insert into t2log(evt, affected_rows) values('del', row_count);
        end
end
^
set term ;^
commit;

insert into t1 values(1, 100);
update t1 set id=2, x=200 where id=1;
delete from t1 where id=2;

select * from t2;

select * from t2log;
-- всегда будет писать в t2log.affected_rows только нулевые значения. А тобы ненулевые были - надо запоминать row_count сразу же после DML с пром. переменной (см в коде выделенный комментарий ).
Читаю доку:
langref 3.0, стр. 388ROW_COUNT
Доступно в: PSQL.
Синтаксис: ROW_COUNT
Тип возвращаемого результата: INTEGER
Контекстная переменная ROW_COUNT содержит число строк, затронутых последним
оператором DML (INSERT, UPDATE, DELETE, SELECT или FETCH) в текущем триггере
,
хранимой процедуре или исполняемом блоке
. . .
Важно
Переменная ROW_COUNT не может быть использована для определения количества строк,
затронутых при выполнении операторов EXECUTE STATEMENT или EXECUTE PROCEDURE.
Для оператора MERGE переменная ROW_COUNT будет содержать 0 или 1, даже если было
затронуто более записей- и в упор не понимаю, что неправильного в указании row_count внутри VALUES() того инсерта, что следует сразу за только что выполненным DML.

Развейте туман, плз...
...
Рейтинг: 0 / 0
05.03.2016, 18:02
    #39186494
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
row_count внутри VALUES()-списка команды insert (ввод после DML): почему она всегда ноль ?
Таблоид,

я точно не уверен, но по моему он пытается посчитать количество затронутых записей сам в себе.
...
Рейтинг: 0 / 0
05.03.2016, 18:02
    #39186495
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
row_count внутри VALUES()-списка команды insert (ввод после DML): почему она всегда ноль ?
точнее в том insert в котором ты его вписал
...
Рейтинг: 0 / 0
05.03.2016, 18:18
    #39186498
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
row_count внутри VALUES()-списка команды insert (ввод после DML): почему она всегда ноль ?
Симонов Денисточнее в том insert в котором ты его вписаля вот тоже так догадываюсь :-)
но с какого перепугу он пишет в row_count результат еще не выполненного insert'a ?
...
Рейтинг: 0 / 0
05.03.2016, 18:21
    #39186499
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
row_count внутри VALUES()-списка команды insert (ввод после DML): почему она всегда ноль ?
Таблоидно с какого перепугу он пишет в row_count результат еще не выполненного
insert'a ?
Потому что надо же эту переменную где-то обнулять. Вполне естественно, что она обнуляется
в начале работы запроса или даже перед ним.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
05.03.2016, 18:51
    #39186507
dimitr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
row_count внутри VALUES()-списка команды insert (ввод после DML): почему она всегда ноль ?
Таблоидс какого перепугу он пишет в row_count результат еще не выполненного insert'a ?
инсерт начинает свою работу с обнуления этого счетчика, потом читает VALUES-список
...
Рейтинг: 0 / 0
05.03.2016, 18:52
    #39186509
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
row_count внутри VALUES()-списка команды insert (ввод после DML): почему она всегда ноль ?
Dimitry SibiryakovТаблоидно с какого перепугу он пишет в row_count результат еще не выполненного
insert'a ?Потому что надо же эту переменную где-то обнулять. Вполне естественно, что она обнуляется
в начале работы запроса или даже перед ним.Вот если бы она обнулялась "чуток позже" начала DML (т.е. когда уже пошли изменения), то было бы гут. А так получается, что обнуляется "чуток перед" ним, и выглядит это как-то не очень... лишнюю переменную держать надо...
...
Рейтинг: 0 / 0
05.03.2016, 18:54
    #39186510
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
row_count внутри VALUES()-списка команды insert (ввод после DML): почему она всегда ноль ?
dimitrТаблоидс какого перепугу он пишет в row_count результат еще не выполненного insert'a ?инсерт начинает свою работу с обнуления этого счетчика, потом читает VALUES-списокА почему не было сделано наоборот ? (и про update/delete, судя по всему, - там тоже самое ?)
...
Рейтинг: 0 / 0
05.03.2016, 18:55
    #39186511
miwaonline
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
row_count внутри VALUES()-списка команды insert (ввод после DML): почему она всегда ноль ?
ТаблоидВот если бы она обнулялась "чуток позже" начала DML (т.е. когда уже пошли изменения), то было бы гут. А так получается, что обнуляется "чуток перед" ним, и выглядит это как-то не очень.
Ну не знаю, не знаю. Всегда обнуляю переменные перед началом цикла/условия/логического блока, а не "чуток позже". Странно как раз ожидать чего-то другого, как по мне.
...
Рейтинг: 0 / 0
05.03.2016, 18:58
    #39186512
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
row_count внутри VALUES()-списка команды insert (ввод после DML): почему она всегда ноль ?
miwaonlineТаблоидВот если бы она обнулялась "чуток позже" начала DML (т.е. когда уже пошли изменения), то было бы гут. А так получается, что обнуляется "чуток перед" ним, и выглядит это как-то не очень.
Ну не знаю, не знаю. Всегда обнуляю переменные перед началом цикла/условия/логического блока, а не "чуток позже". Странно как раз ожидать чего-то другого, как по мне.не, погодь! ты про переменные, которыми ты сам явно управляешь - это один коленкор. А тут речь про row_count, которая управляется движком, ты менять её не можешь. Ну, и вот: сделал ты некий "DML_1", дальше хочешь записать в базу значение row_count, которую движок пока еще "держит" именно для этого "DML_1". И выясняется вдруг, что записать её можно, только предварительно сохранив в переменной. Неуклюже как-то.
...
Рейтинг: 0 / 0
05.03.2016, 19:02
    #39186513
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
row_count внутри VALUES()-списка команды insert (ввод после DML): почему она всегда ноль ?
ТаблоидА тут речь про row_count, которая управляется движком, ты менять её не
можешь.
А вот движок - может. И меняет.

Как ты вообще себе представляешь, например, "insert into t2 select row_count from t1"?..
Нету унутре места для обнуления.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
05.03.2016, 19:20
    #39186519
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
row_count внутри VALUES()-списка команды insert (ввод после DML): почему она всегда ноль ?
Dimitry SibiryakovКак ты вообще себе представляешь, например, "insert into t2 select row_count from t1"?..
Нету унутре места для обнуления.Было бы логично, если бы в этом инсерте использовался row_count, который был установлен по итогам вполнения предыдущего DML. И если сейчас добавилось 3 строки, а предыдущий DML поменял только 1 строку, то в таблицу t2 должно было бы вставиться в каждую из трёх строк именно число 1.
Но теперь я вообще ничего не понимать. Потому что вот эта штука:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
recreate table ta(c int, x int);
commit;

set term ^;
execute block as
begin
  insert into ta(c,x) values(1,-12345678);
  insert into ta(c,x) select 2,row_count from ta;
  insert into ta(c,x) select 3,row_count from ta;
  insert into ta(c,x) select 4,row_count from ta;
  insert into ta(c,x) select 5,row_count from ta;
end
^
set term ;^
select * from ta;
- выведет в 3.0 RC2:CX1-12345678203031404142435051525354555657Объясните мне популярно: с какого будуна row_count еще и меняется в процессе выполнения insert'a ?
...
Рейтинг: 0 / 0
05.03.2016, 19:28
    #39186523
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
row_count внутри VALUES()-списка команды insert (ввод после DML): почему она всегда ноль ?
Таблоид,

row_count изначально не был рассчитан на такое использование. А то что он меняется по мере insert ... select довольно предсказуемо
...
Рейтинг: 0 / 0
05.03.2016, 19:28
    #39186524
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
row_count внутри VALUES()-списка команды insert (ввод после DML): почему она всегда ноль ?
ТаблоидОбъясните мне популярно: с какого будуна row_count еще и меняется в процессе
выполнения insert'a ?
А где ещё ему меняться, когда основное и единственное назначение этой переменной -
подсчитывать число обработанных записей?

Хотя с другой стороны, конечно, движок мог бы делать и row_count = RowsAffected() один раз
уже после успешного выполнения запроса.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / row_count внутри VALUES()-списка команды insert (ввод после DML): почему она всегда ноль ? / 14 сообщений из 14, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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