Каскадное обновление непервичного ключа в sql server 2008

Я пытаюсь реализовать каскадное обновление и искал в Интернете ограничение Fk. Я нашел такие решения, как http://sqlandme.com/2011/08/08/sql-server-how-to-cascade-updates-and-deletes-to-related-tables/

и этот блог довольно хорошо объясняет процесс. Я не уверен, что это работает только для PK, или мы можем настроить каскадное обновление/удаление и для не-pk полей.

У меня есть две таблицы.

табличная регистрация:

  • ID пользователя (ПК)
  • Имя пользователя
  • НазваниеКомп

так далее

tblposting_detail:

  • Бидид (упак.)
  • UserID (Fk с tblregistration)
  • НазваниеКомп

Теперь, когда пользователь редактирует свой профиль и обновляет название компании, то есть обновляет compname в tblregistration, я хочу, чтобы compname также обновлялось в моем tblposting_detail для того же пользователя, который обновил свой профиль.

Я читал статью, в которой говорилось, что каскадное обновление и удаление иногда дают неожиданные результаты, поэтому не рекомендуется все время и лучше иметь два разных SQL-оператора обновления вместо каскадного обновления.

Может ли кто-нибудь помочь мне понять процесс и лучшие практики для этой конкретной проблемы.

Спасибо.


person arpan shah    schedule 03.12.2013    source источник
comment
Почему вы храните CompName в таблице tblposting_detail?   -  person gvee    schedule 03.12.2013
comment
CASCADE можно применять только к внешним ключам - и, видя, что ваш столбец compname не является FK, вы не можете этого сделать. Также: почему compname хранится в двух местах и ​​требует обновления дважды? Это плохой дизайн - не нормализовано - compname нужно сохранить только один раз, так что если вы его обновите - все готово.   -  person marc_s    schedule 03.12.2013
comment
Потрясающий. Я подумал, что допустил некоторую основную ошибку и подумал, что может быть способ решить эту проблему с моим дизайном, я обновлю дизайн и нормализую таблицу, чтобы применить каскадное обновление. И просто для того, чтобы очистить, я могу установить ограничение FK для таблицы tbl_posting на UserID (FK), который сопоставляется с Userd (PK) таблицы tblregistration, верно?   -  person arpan shah    schedule 03.12.2013


Ответы (2)


Каскадное обновление и каскадное удаление дают совершенно предсказуемые результаты. Они дают неожиданные результаты только тогда, когда разработчики не знают об их предсказуемых результатах.

Целью ограничения внешнего ключа должен быть набор уникальных столбцов — набор столбцов должен иметь либо ограничение первичного ключа, либо ограничение уникальности.

В вашем случае tblregistration.CompName не уникален. (Возможно, не может быть уникальным.) Вы можете имитировать каскады с помощью триггеров или путем отзыва разрешений для таблиц и требования к коду приложения использовать хранимую процедуру, но вы лучше удалить столбец CompName из tblPosting_detail. Используйте запрос SELECT с объединением, когда вам нужны данные из этого столбца.

person Mike Sherrill 'Cat Recall'    schedule 03.12.2013

Вы можете сделать это, введя "супер-ключ", который охватывает как ваш существующий PK, так и дополнительные столбцы, которые вы хотите каскадировать:

create table tblregistration (
    UserID int not null primary key,
    UserName int not null,
    CompName int not null,
    constraint UQ_reg_target UNIQUE (UserID,CompName)
)
go
create table tblposting_detail (
    Bidid int not null primary key,
    UserID int not null references tblregistration (UserID),
    CompName int not null,
    constraint FK_post_reg FOREIGN KEY (UserID,CompName)
       references tblregistration (UserID,CompName) on update cascade
)
go
insert into tblregistration values (1,1,1)
go
insert into tblposting_detail values (2,1,1)
go
update tblregistration set CompName = 4 where UserID = 1
go
select * from tblposting_detail

Результат:

Bidid       UserID      CompName
----------- ----------- -----------
2           1           4

Но я согласен с другими, что вам, вероятно, не следует иметь этот столбец во второй таблице. Я бы также посоветовал не использовать префикс tbl во всех ваших таблицах.

(Обратите внимание, что на данный момент вам решать, оставить ли вы FK только на UserID, а также FK на UserID и CompName, или просто оставить последний)

person Damien_The_Unbeliever    schedule 03.12.2013
comment
Спасибо, Дэмиен. Я буду придерживаться первых решений удаления compname из таблицы tblposting. Я хотел бы проголосовать, но не хватает представителей. - person arpan shah; 03.12.2013