Каскадна актуализация на непървичен ключ в sql сървър 2008

Опитвам се да внедря каскадна актуализация и потърсих онлайн ограничението Fk. Намерих решения като http://sqlandme.com/2011/08/08/sql-server-how-to-cascade-updates-and-deletes-to-related-tables/

и този блог обяснява процеса доста добре. Не съм сигурен, че тази доза работи само на PK или можем да настроим каскадното актуализиране/изтриване и на полета, които не са pk.

Имам две маси.

tblregistration:

  • UserID (PK)
  • потребителско име
  • CompName

и т.н

tblposting_detail:

  • Bidid (pk)
  • UserID (Fk с tblregistration)
  • CompName

Сега, когато потребител редактира своя профил и актуализира името на фирмата, което означава актуализиране на 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