Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Каскадные обновления через триггер
|
|||
|---|---|---|---|
|
#18+
Привет. Вопрос чисто академический - случайно столкнулся и заинтересовался. Вопрос такой - можно ли через триггер организовать поддержку каскадных обновлений, как это аппаратно поддерживается через CASCADE UPDATE ? Например есть 2 таблицы: \ncreate table Table1(Key_id int not null primary key) create table Table2(Id int not null identity primary key, Key_id int not null) При изменении Key_id в Table1 надо организовать изменение соответствующих Key_id в Table2 на новое значение: \nupdate Table set Key_id = 2 where Key_id = 1 При таком раскладе триггер выглядит просто: \ncreate triger trg_Table1_Update on Table1 for update as if update(Key_id) update t2 set Key_id = (select Key_id from Inserted) from Table2 t2 inner join Deleted d on t2.Key_id = d.Key_id Однако как написать триггер при таком варианте: \nupdate Table set Key_id = Key_id + 1 Получится, что таблицы Inserted и Deleted просто не с чем соединить, так как Key_id в них совпадать не будут. Какие будут предложения ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.04.2002, 07:29 |
|
||
|
Каскадные обновления через триггер
|
|||
|---|---|---|---|
|
#18+
IMHO - если Key_id у вас первичный ключ в понятиях SQL-я, т.е. имеется уникальный индекс, то при AFTER триггерах вы не сможете сделать Key_id + 1 даже для одной записи, если уже имеется запись с таким значением. - замену первичного ключа можно делать через промежуточное поле ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.04.2002, 10:18 |
|
||
|
Каскадные обновления через триггер
|
|||
|---|---|---|---|
|
#18+
Почему не могу ? \ndeclare @T table (Id int not null primary key) insert into @T values (1) insert into @T values (2) insert into @T values (3) select * from @T update @T set Id = Id + 1 select * from @T Прекрасно работает с изменением первичного ключа (лог-файл не только для отката транзакций существует ). А вот в моем примере в дочерней таблице Key_id не первичный ключ. Значит и там можно изменить. Так что вопрос остается в силе. Я тут как решение попробовал такой способ: \ncreate triger trg_Table1_Update on Table1 for update as if update(Key_id) begin declare @I table(Row_id int identity not null primary key, Key_id int not null) declare @D table(Row_id int identity not null primary key, Key_id int not null) insert into @I(Key_id) select Key_id from Inserted insert into ID select Key_id from Deleted update t2 set Key_id = i.Key_id from Table2 t2 inner join @D d on t2.Key_id = d.Key_id inner join @I i on d.Row_id = i.Row_id end Единственное что в этом решении не хорошо, что нет гарантии, что в таблицы @I и @D записи попадут под одинаковыми Row_id, хотя пока у меня все сработало. Какие еще будут предложения ? Никто не копал Inserted и Deleted поглубже ? P.S. Повторяюсь - вопрос чисто теоретический, так как я в здравом уме и твердой памяти и менять Primary Key считаю признаком дурного тона. Просто для самообразования интересуюсь ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.04.2002, 16:18 |
|
||
|
Каскадные обновления через триггер
|
|||
|---|---|---|---|
|
#18+
У меня команда create table Table1(Key_id int not null primary key) приводит к созданию уникального индекса поэтому на update Table1 set Key_id = 2 where Key_id = 1 выдается Server: Msg 2627, Level 14, State 1, Line 1 Violation of PRIMARY KEY constraint 'PK__Table1__4865BE2A'. Cannot insert duplicate key in object 'Table1'. The statement has been terminated. и с таблицами-переменными тоже. Массовое же изменение update Table1 set Key_id = Key_id + 1 проходит (но вам-то оно как раз не нужно) IMHO логичнее использовать INSTEAD триггеры ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.04.2002, 08:05 |
|
||
|
Каскадные обновления через триггер
|
|||
|---|---|---|---|
|
#18+
Возвращаясь к исходному вопросу и отвлекаясь от справедливых замечаний Glory оставляя контроль за значениями на ключ на совесть ASCRUS-а (например update Table set Key_id = Key_id + 10000), где изначально Key_id<10000, замечу, что можно ведь не мудрствуя лукаво просто выполнить такое обновление в триггере в два этапа - просто Delete from table2 from table2 join deleted on table2.key_id=deleted.key_id insert into table2 select * from inserted За исключением, конечно случаев с полями с identity (как в Table1, так и в Table2), но и эта проблема решаема с помощью identity_insert ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.04.2002, 09:26 |
|
||
|
Каскадные обновления через триггер
|
|||
|---|---|---|---|
|
#18+
Сапсибо - действительно красивое решение. Насчет ключа - я действительно от балды первое попавшееся в голову привел в пример. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.04.2002, 17:37 |
|
||
|
|

start [/forum/topic.php?fid=46&gotonew=1&tid=1823208]: |
0ms |
get settings: |
11ms |
get forum list: |
18ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
27ms |
get topic data: |
8ms |
get first new msg: |
5ms |
get forum data: |
2ms |
get page messages: |
28ms |
get tp. blocked users: |
1ms |
| others: | 270ms |
| total: | 376ms |

| 0 / 0 |
