powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / ASA9, триггер на удаление меняющий PK
4 сообщений из 4, страница 1 из 1
ASA9, триггер на удаление меняющий PK
    #33508569
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Понадобилось тут нам делать автоматическую перенумерацию строк в табличке... И напоролись на симатичный глюк.
Вот урезаный скрипт воспроизводящий его:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
create table a(d date, id numeric( 2 ), c char( 1 ),
                    primary key(d, id));

insert into a values(today(),  1 , 'a');
insert into a values(today(),  2 , 'b');
insert into a values(today(),  3 , 'c');
insert into a values(today(),  4 , 'd');
insert into a values(today(),  5 , 'e');
insert into a values(today(),  6 , 'f');
insert into a values(today(),  7 , 'g');
insert into a values(today(),  8 , 'h');
insert into a values(today(),  9 , 'i');
insert into a values(today(),  10 , 'j');

create trigger tr after delete on a
	referencing old as old_row for each row
begin
    update a set id = id- 1 
        where a.d=old_row.d and a.id>old_row.id;
end;

delete from a where id>= 4  and id<= 7 ;
select * from a;
Перенумерация работает отлично, если изменяемое поле не входит в первичный ключ или ключа нет вообще. Проявляется естественно только на групповых удалениях.
Устойчиво проявляется на ASA 9.0.2.2451
Проверьте пожалуйста на более новых ebf.
...
Рейтинг: 0 / 0
ASA9, триггер на удаление меняющий PK
    #33509572
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это даже не глюк, а фича. И на последних версиях она вести себя будет так же. Единственный способ добиться нужного эффекта, это воспользоваться вот таким триггером (я так понял, нумерация id поддерживается в разрезе группировки даты):
Код: 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.
ALTER TRIGGER tr AFTER DELETE 
ORDER  1  ON a
REFERENCING OLD AS Deleted 
FOR EACH STATEMENT
BEGIN
  DECLARE LOCAL TEMPORARY TABLE #n (
    d date NOT NULL, 
    id numeric( 2 ) NOT NULL,
    new_id numeric( 2 ) NOT NULL,
    PRIMARY KEY (d, id),
    PCTFREE  0 
  ) NOT TRANSACTIONAL;

  INSERT INTO #n (d, id, new_id)
    SELECT a.d, a.id, Row_Number() OVER (PARTITION BY a.d ORDER BY a.d, a.id) + f_id -  1  AS new_id
    FROM a WITH (REPEATABLEREAD) 
      INNER JOIN (
        SELECT d, Min(id) AS f_id
        FROM Deleted
        GROUP BY d
      ) AS d ON d.d = a.d AND d.f_id < a.id;

  UPDATE a 
    INNER JOIN #n n ON n.d = a.d AND n.id = a.id
  SET a.id = n.new_id;
END;

P.S. Хотя все таки я считаю, вообще не гоже трогать PK и уж тем более на каждое удаление пересчитывать значение PK (интересно сколько суток работал бы Ваш триггер при удалении миллиона записей, где на каждую удаляемую запись, вызывался бы апдейт всех следующих в таблице записей). Лишние не нужные нагрузки, плюс абсолютно не будет работать с репликацией, которая запрещает изменение ключа. В таких случаях лучше уж делать PK инкрементом, а d и id сделать как unique constraints, где пересчет id можно инициализировать в хранимых процедурах, а не триггерах.
...
Рейтинг: 0 / 0
ASA9, триггер на удаление меняющий PK
    #33510993
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да вообще нельзя менять PK в таблице, тем более триггер не сможет вообще работать на ней -- вы просто не сможете найти , где какая запись. Конечно, частные случаи возможны, но в общем это -- классический случай, как не надо делать.
...
Рейтинг: 0 / 0
ASA9, триггер на удаление меняющий PK
    #33511833
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну то что PK нельзя менять это вообще-то вне вопросов :)
Но к сожалению не все хорошо учились в школе... Приходится потом отлавливать такие вот глюки :(
ASCRUSЭто даже не глюк, а фича
По моему это все таки глюк :) Во всяком случае то, как ведет себя такой триггер если на таблице нету (или другой PK) согласуется со всеми учебниками SQL, а вот наблюдаемое поведение оказалось неожиданностью.
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / ASA9, триггер на удаление меняющий PK
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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