Теория и практика построения баз данных (1088289), страница 106
Текст из файла (страница 106)
Чтобы изменить существующую хранимую процедуру, щелкните правой кнопкой мыши на ее названии в списке процедур н выберите пункт РгорегВез (Свойства). Хранимая процедура йевтгСиаФопзег111И1тТгапаас1!оп Хранимая процедура, создающая представление ИеууСи51огпег, показана в листин- ге 13.2.
Эта процедура принимает семь параметров, содержащих данные о новом клиенте и сделанном им приобретении. Рис. 13.19. Вызов процедуры 0051огпег !пзел из окна Осегу Апа)узег )ХР 1: йз пот';:д!'; Ф:;:;:,$':::::Ф':::8К)1',";.1':411 яС:6~~~н .: '':,:! сы!оьеуго на!«е ",:- ', вуеасава«,"'. ' а ' ':: -: яя ф":~: ":й ен з 1 СФ1:;:;$,')г)1".'"Фь)гд<Увп 1 Я'О. 1, Ъ:.':, '::,$ рис.
13.90. результаты вызова хранимая процедуры ив рис 18 19 492 Глава 13. Работа с базами данных в 80Е Вептег 2000 Логика приложения 493 Листинг 13.2. Хранимая процедура МеитСцэтогпегу)д(ПТгапзаст(оп СЙЕАТЕ РЙОСЕООЙЕ МенСизтовегйтСПТгапзасттоп 9йенйаве спаг(50), 9йеилгеаСобе спаг (3), 9йеиРПопе сПаг (8). 9Агстзтйаве слаг(50), 9йогйтт 1)е слаг(50), 9йогКСору слаг(10), 9Ргзсе арпа))вопеу А5 ОЕССАЙЕ 9Соцпт аз зва))тпс ОЕССАЙЕ 9Ятб аз тпС ОЕССАЙЕ 9Стб аз тпт ОЕС(ЯЙЕ 9йтб аз тпг ОЕССАЙЕ 9Т)О аз тпт 5ЕСЕСТ 9СоцпГ=Соцпт (*) ГРОМ ОЬо.С05ТОМЕЙ ННЕЙЕ [йаве]=9йеийаве АИО АгеаСоде-9йеиАгеаСоде АИО Соса1йцвоег=9йенрпопе !Г9Соцпь > 0 ВЕ6!й РЙ!МТ ' Клиент уже есть в базе данных -- никаких действий не предпринято ' ЙЕТОЙИ ЕМО ВЕ6!й ТЙАИ5АСТ10И /* Начинаем транзакцию: если не мовен ее выполнить -- делаем откат всех изменений */ 1И5ЕЙТ 1йТО ОЬо.С05ТОМЕЙ ((йаве], АгеаСобе. Еоса1йцгпбег) ЧЯСОЕ5 (9йенйаве, 9йенягеаСобе, 9йенРПопе) 5е1есь 9610 = Сцзтовег10 ГРОМ ОЬо,С05ТОМЕЙ ННЕЙЕ Ейаве]=ййенйаве АМО ЯгеаСо()е=ййенАгеаСобе АИО Соса)йцгпбег=9йенРПопе 5ЕСЕСТ 9А)О = Агттзт10 ГРОМ ОЬо.ЯЙТ15Т ИНЕЙЕ ЯгГтзтйаве=йлгттзтйагпе !т 9Атб [5 МОСС /* Неправильный идентификатор художника */ ВЕ61й Рш пг' неправильный идентификатор худоиника ' ЙОССВЯСК ЙЕТОЙИ ЕИО 5ЕСЕСТ 9йттб = Носк!0 ГЙОМ бЬо Н~ИОЙК] ННЕЙЕ Агттзт10 - 9Азб АМО Ттс1е - 9йогктт(1е АМО Сору = 9йогкСору 1/9йтд 15 МОСЕ /* Неправильный идентификатор произведения */ ВЕНИ Ргтпт 'Неправильный идентификатор произведения' ЙОЕСВАСК ЙЕТОЙИ ЕМО 5ЕСЕСТ 9Т)б=тгапвасгтоп!0 ГЙОМ ОЬо ДТЙЯИ5] ННЕЙЕ ИогК10-9йтб АИО 5а1езРгтсе 15 ИОЕЕ 1Т 9Т) б 15 МОСЕ /* Неправильный идентификатор транзакции */ ВЕ61И Ргтпт ' Неправильный идентификатор транзакции ' ЙОЕЕВАСК ЙЕТОЙИ ЕИО 0РОАТЕ обо.(ТЙАИ5] /* Все в порядне.
обновляем строку в таблице ТЙАИ5 */ 5ЕТ Рцгспазебабе = 6ЕТОАТЕ(), 5а1езргтсе = 9Ргтсе, Сцзтовег10 - 9С)б ННЕЙЕ Тгапзасттоп10=9Т1О !И5ЕЙТ 1ИТО ОЬо.(С05ТОМЕЙ-ЯЙТ!51- 1МТ] /* Регистрируем интерес клиента к данному художнику */ [Сцзтовег!0, Агттзсрб) Ча)цез (9Стб. 9Ато) СОММ1Т 60 Первое, что нужно сделать, — это проверить, не существует ли уже этот клиент в базе данных; если да, процедура завершает работу с сообщением об ошибке. Если этого клиента нет в базе данных, процедура начпнает транзакцию. Вспомните из главы 11, что транзакции гарантируют атомарность действий, выполняемых с базой данных: либо выполняются все обновления, либо не выполняется ни одного.
Итак, начинается транзакция, и в таблицу С05ТОМЕЙ вставляется строка для нового клиента. Далее считывается новое значение Святоше(10, как показано выше. Затем процедура проверяет допустимость значений Агг(з(10, У/огй10 и Тгапзасбоп10, Если хотя бы одно из штх является некорректным, происходит откат транзакции. Если все перечисленные значения правильны, оператор 0РОАТЕ обновляет столбцы РцгсйазеОа(е, Рпсе и Сцз(опзег10 в соответствутошей строке таблицы ТЙАМ5. В столбец РцгсйазеОа1е записывается системная дата (с помощью системной функции 6ЕТОАТЕО), в столбец 5а(езРпсе — значение параметра фРпсе, а в столбец Сцзгопзег10 — значение переменной (вС(б, Наконец, добавляется строка в таблицу С05ТОМЕЙ АЙТ!5Т 1МТ, чтобы зарегистрировать интерес клиента к данному художнику.
Если до этого момента все идет нормально, транзакция сохраняется. На рис. 13.21 показан вызов этой процедуры с тестовыми данными, а на рис. 13.22 изображены результаты вызова в базе данных. Новому клиенту бььч присвоен идентификатор Сцз(ошег10, равный 1040„и этот идентификатор был записан Логика приложения 495 Триггеры ОЕС[АРЕ (акеиргтсе аз зюа11юопеу ОЕС[АРЕ (атб аз тпт тств11 РВм9'~1:": "-:]91"-12 '. 9: '3 т [тат 05 696 9 5 си Е 509 5 509 505 ОРОАТЕ бЬо . ТРАМ 5 5 ЕТ Аз» 1 прРг 1 се = (апеирг1 се ИНЕРЕ Тт апз асС топ ! 0 - Сат б 5505 95 вма вам 90 9М5 9' в950 и аа 96099 ~авь О 59569 69Оь 9 95ввм 99% 9 ОД СЮО ! 7 5 И аав ыаа 494 Глава 13.
Работа с базами данных в 80С Яептег 2000 в столбец внешнего ключа Сцздогпег10 таблицы ТРАМ5, как и требовалось. Соответ- ствующим образом были установлены значения столбцов РцгсйазеОаае и 5а1езРпсе. Обратите внимание на новую строку в таблице пересечения, которая отражает интерес клиента под номером 1040 к художнику под номером 14. 'Рййяв/Йтйай6»твибфяка46 йвяаяй591ВЮГ$Й(ЯГЯтеа»»йы твГЗ;ММЫВЬ»55114ЯИЙ:;:-ива Ч6 ТГвжт. С Рис. 13.21.
Вызов процедуры неисцвтопвегуувтптгзпвасг1оп из окна Оцету Апа1уяег Рис. 13.22. Результаты вызова хранимой процедуры ив рис. 13.21 Триггеры представляют собой хранимые процедуры, вызываемые при выполнении заданной команды — вставки, обновления или удаления. Завершающие триггеры выполняются после обработки соответствующей команды, а замещающие триггеры — вместо оператора, который привел к вызову триггера. Завершающие триггеры запускаются после выполнения всех каскадных обновлений и удалений. Предваряющие триггеры в Яа].
Яегуег не поддерживаются, в отличие от Огас!е. Триггер йеятч РГ1се В листинге 13.3 показан триггер, с помощью которого вычисляется значение столбца Меи/Рпсе. Вид оператора СРЕАТЕ ТР166ЕР показывает, что триггер должен вызываться при вставках и обновлениях в таблице ТРАМ5. Первым делом код триггера определяет, затрагивает ли изменение (здесь под изменением понимает- ся вставка или обновление) столбец Асов]з]1]опРпсе. Если нет, триггер завершает свою работу. Листинг 13.3. Триггер 1Четы Рисе СРЕАТЕ ТР166ЕР Иеи Рг1се ОИ [бЬо] [ТРАМ5] ГОР 1И5ЕРТ.ОРОАТЕ А5 1Г ИОТ ОРОАТЕ (Асоц1з1С1опРг1се) РЕТОРИ /* Интерес представляют только новые значения ипи изменения атрибута Ассц1зтстопРгтсе */ 5е[ест (аиеиргтсе = Асоцтз111опРгтсе, (а14 = тгапзасттоп10 ГНОИ тпзегтеб 5ет [акеирг!се юпеиРг1се * 2 /* Здесь можно было бы использовать функцию.
вычисляющую изменение цены по более сложному закону */ /* Обратите внимание: выполнение следующих операторов приведет к рекурсивному вызову дачного триггера. Он сразу заверщит свою работу, поскольку зто обновление не затрагмяает атрибут Асоы1з121опРгтсе. */ Если же вставка или обновление затрагивает столбец Асцц]з]ь]опрг1се, стоящий далее оператор 5Е[ЕСТ возвращает новое значение Асцц1з1с]опРпсе и значение Тгапзасбоп10, Данный оператор работает с псевдотаблицей, которая поддерживается БЯ1 Зегуег. Эта таблица называется 1пзегтеб и содержит все вставленные или измененные данные.
Есть еще одна подобная таблица (не используемая здесь), которая называется бе[е1ео и содержит данные, существовавшие до опера- 496 Глава ! 3. Работа о базами данных в 8ОС Вещет 2000 Логика приложения 497 ции удаления. Таблицы !пзеттеб и бе1етеб доступны только в коде триггера. Они сходны по своей функции с префиксами:петю и:оЫ, используемыми в Огас1е, Далее триггер вычисляет новую цену в переменной С4Рпсе.
Полученное значение затем записывается в столбец Азй!пдрпсе обновляемой строки. Как говорится в комментарии, обновление таблицы ТЙАМ5 в этом триггере приведет к повторному, рекурсивному его срабатыванию. Однако при втором запуске триггера обновление не будет затрагивать столбец Асдц!з!1!опРпсе, поэтому второй экземпляр триггера завершит свою работу, не производя второго обновления. Это, кстати, довольно затратный способ реализации для такой простой формулы, Лучшим решением было бы определить формулу обновления как свойство столбца Азй!пдРпсе в определении таблицы ТЙАМ5.
Однако если бы вычисление Азк!пдРпсе производилось более сложным способом либо если бы для этого требовалось обращение к другим таблицам или даже другим базам данных, то такой триггер был бы необходим. Триггер Оп МЧОЯК !пвег1 В листинге 13.4 изображен более типичный способ использования триггера. Как уже говорилось в главе 1О, одно и то же произведение искусства может быть продано галереей несколько раз.
Но поскольку мы используем суррогатные ключи, то каждый раз при регистрации произведения в базе данных информация о нем будет помещаться в новую строку, что создаст впечатление, будто это какое-то другое произведение. Чтобы предотвратить такую ситуацию, мы напишем триггер Оп ВОЙК 1пзетт, который будет проверять, не было ли это произведение зарегистрировано в базе данных когда-либо ранее.
Если да, то вновь созданная строка будет удалена из таблицы ВОЙК и вместо нее будет использоваться старая. Листинг 13.4. Триггер Оп УУОНК !пэен СЙЕАТЕ ТЙ166ЕЙ Оп МОЙК 1пзегт ОМ обо.[ЫОЙК] ГОЙ 1М5ЕЙт ОЕСЕАЙЕ РМеышогй10 аз )пт ОЕСЕАЙЕ Рсоцпт аз вша11)пт ОЕСЕАЙЕ РАзб аз зпс ОЕСЕАЙЕ Рт!11е аз сваг (50) ОЕССАЙЕ РСору аз ст~аг 110) 5ЕСЕСТ РМеыногк10 = Могй)0. Рдзб = Агт!зс10. Рт!11е = ТГЕ1е, РСору = Сору ГЙОМ 1пзегтео !* Эта псевдотаблица, содержащая вставленные данные, является доступной для триггеров *! 5ЕЕЕСТ Рсоцпт = Соцпт (*) ГЙОН УзЕыйзцдЕ1,ОЬО.ЕЫОЙК] МНЕЙЕ Агт!зг10 = РА)б АМО Ттт1е = Рт!1)е АМО Сору = 9Сору 1Г Рсоцпт > 2 l* Ошибка для данного произведения было доступно 2 строки ДО вставки *! ВЕ61М ЙОЕСВАСК Рг!пс ' Ошибка в таблице ЫОЙК; для данного произведения доступно более одной строки ' ЙЕТОЙМ ЕМО 1Г Рсоцп1 - 2 !* Означает.