Триггерлерді құру 5. Триггерлердің көмегімен генератордан алынған мәнді автоинкремент өрісіне орнатуға болады. Осындай триггер құрыңыз:
CREATE TRIGGER BEF_INS_NAKLS FOR Nakls
ACTIVE BEFORE INSERT
AS
BEGIN
NEW. NakllD = GEN_ID(GEN_NAKLS,1);
END
Бірінші жолда BEF_INS_NAKLS триггерінің атауынан басқа (триггерлерді сақталған процедураларда немесе SQL сұрауларында оларға қоңырау шалу мүмкін болмаса да, олар серверлік Дерекқордың барлық басқа нысандары сияқты ерекше атауларға ие болуы керек) сонымен қатар nakls кестесі көрсетілген. Келесі жол триггерді қашан іске қосу керектігін көрсетеді (біздің жағдайда — жаңа жазбаны енгізбес бұрын). Үшінші жолда триггердің денесін ашатын сақталған AS сөзі бар. Триггердің денесі әрдайым (егер триггерде біздің жағдайдағыдай жалғыз мәлімдеме болса да) BEGIN және END кілт сөздерімен шектелуі керек. Бесінші жолда жалғыз орындалатын оператор орналасқан, онда NAKLLD өрісінің Жаңа мәні (жаңа предикат) ендірілген GEN_ID функциясынан алынған мән беріледі. Осы функцияға айналудың екі параметрі генератордың атауын және генератордың ағымдағы мәні артуы керек мәнді көрсетеді (генератордың" қадамы"). INSERT және UPDATE триггерлерінде, егер оның аты жаңа предикаттан бұрын болса, ал DELETE және UPDATE триггерлерінде ескі мәнге (old предикаты) сілтеме жасауға болады.
НАЗАР АУДАРЫҢЫЗ Бастамашылық автоинкремент өрісінің көмегімен генераторлар тек триггерлар, срабатывающих алдында вставкой жаңа жазу.
6. Сол сияқты, қалған автоинкремент өрістері үшін BEF_INS_FIRMS, BEF_INS_MOVEB BEF_INS_BOOKS, BEF_INS_PAYMENTS триггерлерін жасаңыз.
7. Үстеме деректерді жоймас бұрын оған қатысты барлық кітаптар туралы деректерді жоятын триггер жасаңыз:
CREATЕ TRIGGER BEFORE_DEL_NAKLS FOR NAKLS ACTIVE BEFORE DELETE AS
BEGIN
DELETE FROM MoveBook WHERE MNakl = NakllD;
END
8. Жеке кітап туралы деректерді жою іс-әрекеттің неғұрлым күрделі логикасын қажет етеді: шот-фактураның түріне сүйене отырып, қоймадағы кітап даналарының санын және серіктес балансын түзету керек, сонымен қатар шот-фактураның мөлшерін өзгерту керек:
CREATE TRIGGER BEFORE_DEL_MOVEBOOK FOR MOVEBOOK ACTIVE BEFORE DELETE
AS
/ * көмекші айнымалыларды жариялау: */
DECLARE VARIABLE Typen INTEGER; / * шот-фактура түрі */
DECLARE VARIABLE FirmN INTEGER; / * Шифр серіктес */
DECLARE VARIBLE Coeff FLOAT; / * коэффициентті */
BEGIN
/* Помещаем түрі жүкқұжаттың переменную TypeN шифры әріптес
FirmN айнымалы және Coeff коэффициенті */
SELECT NType, NFirm FROM Nakls WHERE Nakls. NaklID=OLD. MNaklINTO :TypeN, :FirmN;
IF (:TypeN IN (0,3,4,6)) THEN
BEGIN
/ * Кітаптардың келуіне байланысты жүкқұжаттан кітап жойылады.
Қоймадағы кітаптар санын азайтыңыз */
UPDATE Books
SET BQuan=BQuan-OLD. MQuan
WHERE BookID=OLD. MBook;
/ * Серіктес сальдосын түзетеміз */
IF (:TypeN=4) THEN
/ * Айырбас сальдосын ұлғайтамыз */
UPDATE Firms
SET FChgDelta = FChgDelta+OLD. MQuan*OLD. MPrice*:Coeff
WHERE FirmID=:FirmN; ELSE
/ * Қаржылық сальдоны арттырамыз */
UPDATE Firms
SET FFinDelta = FFinDelta+OLD. MQuan*OLD. MPrice*:Coeff
WHERE FirmID=:FirmN;
END
ELSE
BEGIN
/ * Кітаптың кетуіне байланысты шот-фактурадан кітап алынып тасталады. Қоймадағы кітаптар санын көбейтіңіз */
UPDATE Books SET BQuan=BQuan+OLD. MQuan
WHERE BookID=OLD. MBook;
IF (:TypeN=4) THEN
/ * Айырбас сальдосын азайтамыз */
UPDATE Firms
SET FChgDelta = FChgDelta+OLD. MQuan*OLD. MPrice*:Coeff
WHERE FirmID=:FirmN;
ELSE
/ * Қаржылық сальдоны азайту */
UPDATE Firms
SET FFinDelta= FFinDelta+OLD. MQuan*OLD. MPrice*:Coeff
WHERE FirmID=:FirmN; END END
Көптеген пікірлер белгілі бір әрекеттердің ерекшеліктерін түсіндіреді.
Көріп отырғаныңыздай, жергілікті айнымалылар мен шартты операторлар триггерлерге рұқсат етіледі. Келесі бөлікке назар аударыңыз. BEFORE_DEL_MOVEBOOK триггерінің елеулі кемшілігі бар: ол шот-фактураның мөлшерін реттемейді. Бұл кездейсоқ емес. Мысалы, оның басында келесі жолдарды салуға болады: UPDATE Nakls
SET NSum = NSum-OLD. MQuan*OLD. MPrice*:Coeff WHERE NaklID=OLD. MNakl;
Егер бұл орындалса, триггер шот-фактурадан кітап деректерін жою міндетін өте жақсы шешеді, бірақ шот-фактурадағы барлық ақпаратты жоюға тырысу мүмкін болмайды, өйткені триггер жойылған шот-фактурадағы өрісті өзгертуге тырысады. Бұл мәселені қалай шешуге болады? Факт мынада: процедурадан айырмашылығы, триггерге шот-фактура туралы ақпарат тұтастай жойылатындығын көрсететін параметр берілмейді. Осындай параметрді алғаннан кейін, триггер шот-фактураның сомасын өзгертпейді және бұл жағдайда Серіктес сальдосын түзету bef_del_nakls триггерінде бірден бүкіл сомаға жасалуы мүмкін және оны әр жеке кітап үшін жасамайды. Алайда, мен қайталаймын, триггерге параметр берілмейді, ал дерекқорда Ғаламдық айнымалылар жоқ. Мен мұндай проблемаға алғаш рет тап болған кезде, бұл маған шешілмейтін болып көрінді. Алайда, біраз ойланғаннан кейін, менің ойымша, бұл өте қолайлы шешім. Мен MOVEBOOK кестесіне жаңа өрісті қостым: ALTER TABLE MOVEBOOK ADD IsDelNakl VARCHAR (l)
Бұл өріс BEF_INS_MOVEBOOK триггеріндегі F мәнін енгізу процесінде толтырылады:
CREATE TRIGGER BEF_INS_MOVEBOOK FOR MOVEBOOK BEFORE INSERT AS
BEGIN
NEW. IsDelNakl="F";
NEW. MoveId=GEN_ID(GEN_MOVEBOOK,1);
END
BEF_DEL_NAKL триггері алдымен осындай операторды орындайды:
UPDATE MoveBook SET IsDelNakl="T" WHERE MNakl=OLD. NaklID;
Енді BEF_DEL_MOVEBOOK триггері осы өрісті талдай алады және егер өрісте t: IF (OLD. IsDelNakl<> "Т") сол
UPDATE Nakls
SET NSum = NSum-OLD. MQuan*OLD. MPrice*:Coeff
WHERE NaklID=OLD. MNakl;
Дұрыс триггер мәтіндерін SQL Explorer көмегімен көруге болады. Мұны істеу үшін қажетті кестенің жанындағы түйінді ашыңыз, содан кейін триггерлер түйінін ашыңыз, қалаған триггердің атын таңдаңыз және мәтін қойындысына өтіңіз.