|
Программирование >> Реляционные базы данных
Основная, работа выполняется ииююм ня строках (III -(16) На строке (12) выбранный кортеж вносится в переменную worth. Поскольку кортежи, порождаемые запросом строки (S), имеют только олин компонент, нужна всего вдна разделяемая переменная, отя в обшем случае требуется столько перемемных, сколько компонентоп вколит в извлекаемые кортежи. Сзрока (13) комоюдирует ycneujHocTb выбора кортежем. Здесь ри.менястся макрокоманде NO MORE TUPLES. которая может бьггь определена как define NO MORE TUPLES! (strcmp(SOLSTATE. 02000 )) Ншоммим, что 02000 - это содержание SQLSTATE, означающее, что не наНлено к и одного кортежа. В таком случае Ш1кл прерывается, н выполняется переход к строке (17). Если кортеж был выбран, на строке (14) число цифр в чистом доходе устанавливается в I. Строка (15) - это цикл, который повторно делит чистый доход на 10 и увеличивает digits на I. Когда чистый доход после деления на Ю превращается в 0. digits содержит верное количество цифр в значении переменной worth, которое было первоначально извлечено. И наконец, строка (1С) увеличивает подходящий элемент набора counts на I. Предполагается, что количество цифр не превьшиет 14. При наличии же чистого дохода с 15 цифрами и более, строка (16) не увеличивает ни олин элемент counts, так как не существует подходящего ранга, т.е. исть ii доход ненормальной величины отбрасывается и не влияет на статистику. Строка (17) завершает действие функции. Курсор закрывается, и строки (18) и (19) печатают значения в наборе counts. □ 7.1.7 Изменения с использованием курсора Когда курсор пробегает по кортежам таблицы базы (т.е. отношения, которое .хранится в БД, а не представления или отношения, порождаемого запросом), можно не только считывать и обрабатывать значения каждого кортежа, но также изменять или ула1ять этот кортеж. Синтаксис операгорои UPDATE и DELETE отличается от синтаксиса, введенного в разделе 5.6 только пунктом WHERE. Здесь он должен содержать ключевые слова WHERE CURRENT OF, за которыми следует имя курсора. Разумеется, программа главного языка, читающая кортеж, может применять любое условие его изменения или удаления. Пример 7.5. На рис. 7.5 описана функция С, аналогичная функции, представленной на рис. 7.4, Обе они вводят курсор execCursor, пробегающий по кортежам отношения MovieExec. Однако первая из них просматривает каждый кортеж и решает, удалить его или удвоить чистый доход. Здесь снова применяется макрокоманда NO MORE TUPLES аля условия, согласно которому переменная SQLSTATE с кодом 02000 означает кортежей больше нет . На строке (12) проверяется величина чистого дохода, и если она меньше ЮОО дол., кортеж удаляется оператором DELETE па строке (13). Если чистый до.чод составляет минимум ЮОО дол., он удваивается на строке (15). □ 7.1.8 Опции курсора SQL2 обеспечивает различные опции курсора. 1. Можно определить порядок, в котором кортежи выбираются нз отношения. 2. Можно ограничить результат изменений отношения, по которому пробегает курсор. 3. Можно варьировать дьнжение курсора по списку кортежей. Подробности этих режимов рассматриваются в разделах 7.1.9 - 7.1.11. 1) void ctiangeWorttiO [ 2) EXEC SQL BEGIN DECLARE SECTION; 3) int worth; 4) char SQLSTATE(6]: 5) EXEC SQL END DECLARE SECTION: 6) EXEC SQL DECLARE execCursor CURSOR FOR 7) SELECT netWorth FROrl IwlovieExec; 8) EXEC SQL OPEN execCursor; 9) while(l) { 10) EXEC SQL FETCH FROM execCursor INTO ;worth; 11) Jf(NO MORE TUPLES) break; 12) if (worth < 1000) 13) EXEC SQL DELETE FROM MovieExec WHERE CURRENT OF execCursor; 14) else 15) EXEC SQL UPDATE MovieExec SET netWorth = 2 * netWorth WHERE CURRENT OF execCursor; 16) EXEC SQL CLOSE execCursor; ) Ри<. 7.5. Изменение чистых доходов одмииистроторое 7.1.9 Упорядочение выбираемых кортежей Рассмотрим сначала порядок кортежей. Их можно выбирать по порядку, согласно значению каждого компонента. Порядок ввсиится в соответствии с определением отношения, которое пробегает курсор, с помошью ключевых слов ORDER BY и списка используемых при сортировке компонентов, точно так же как и в запросах из разделз 5.L5 Компоненты определяются атрибутом или числом. Во втором случае число - это номер позииии атрибута среди других атрибутов отношения. Пример 7.6. Предположим, нужно проверить кортежн отношения, введенного путем объед1 нения отношений Movie и Starsln, и последующей проекции, результатом которой являются только название фильма, год. кинозвезда и студия. Нужно также упорядочить ко1этежи по году выпуска фильма, а кортежи с одним и тем же годом сгрупгтровать по названию фильма в алфавитном порядке. Курсор mov eStarCursor Пю6егающий по такому отношению, описан на рис. 7 6. 1) EXEC SQL DECLARE mov eStarCursor CURSOR FOR 2) SELECT title, year, studio, starName 3) FROM Mov e, Starsln 4) WHERE title-movieTitle AND year = movieYear 5) ORDER BY year tite; Рие. 7.6. Применение ORDER BY дли контроля за порядком выбираемых кортежей Строки {.!) (4) это обычный оператор SELECT, а в строке (1) задан курсор, пробегающи!! по кортежам этого отношения. Согласно строке (э) при выборе кортежей через курсор movieStarCursor первыми будут выбраны кортежи с более ранними гоаами. Названия фильмов одного и юго же гоца будут упорядочены по алфавиту, поскольку именно гак упорядочены значения, представленные строками символов. Никакой порядок для кортежей, представляющих кинозвезд одного и того же фильма, здесь не установлен. О 7.1.10 Предотвращение одновременных изменений Рассмотрим случай, когда одна функция ч гтает кортежи посредством курсора movieStarCursor из примера 7.6. а другая одновременно выполняемая функция (или даже та же самая функция) изменяет базовое отношение Movie или Starsin. Более подробно об одновременном протекании нескольких процессов в единственной БЛ будет сказано в разделе 7.2. Здесь мы просто допустим, что при использовании отношения другой процесс может изменять его. Что же делать в подобной ситуации? Возможно, вообще ничего. Предпо;южим, нужно найти кортежи для конкретных кинозвезд. Тогда неважно, увидим ли мы кинозвезд, кортежи для которых вводятся или удаляются; просто принимаются кортежи, полученные с помои1ью курсора. Однако иногда необходимо запретить одновременные изменения кортежей, которые получаются с помощью курсора. Например, если кортежи, просматриваемые функцией, вынуждают ее добавлять новые кортежи в Starsin, может возникнуть бесконечный цикл, в котором новые кортежи генерируют через курсор дополнительные кортежи, а последние, в спою очередь, создают новые кортежи. Если есть риск такого или какого-либо другого нежелательного явления, курсор нужно объявить нечувствительным К одновременным изменениям Пример 7.7. Строку (I) на рис. 7.6 можно заменить строкой 1) EXEC SQL DECLARE movieStarCursor INSENSITIVE CURSOR FOR При таком описании курсора movieStarCursor система SQL гарантирует, что изменения отношеиий Movie и Starsin, сделанные между открытием и закрытием курсора, не повлияют нв множество выбранных кортежей. □ Нечувствительный курсор может дорого обойтись в том смысле, что системой SQL будет затрачено много времени на управление доступом к данным, гарантирующим нечувствительность курсора. Управление параллельными операциями на обсуждается в разделе 7.2. Здесь же упомянем лишь один способ поддержки нечувствительного курсора. Система SQL должна останавливать любой процесс, способный затронуть базовые отношения Movie и Starsin. Есть пробегающие отношение Л курсоры, о которых можно определенно сказать, что они не изменяют Л. Такой курсор может пробегать Л параллельно с нечувствительным курсором, без риска изменить отношение Л, которое видит последний. При задании курсора FOR READ ONLY СУБД получает гарат-ию, что базовое отношение не будет изменено из-за доступа к отношению через этот курсор. Пример 7.8. К рис. 7.6 можно добавить строку 6) FOR READ ONLY; В результате любая попытка выполнить UPDATE или DELETE с помощью курсора movieStarCursor приведет к ошибке. □
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |