Программирование баз данных MS SQL Server (1084479), страница 58
Текст из файла (страница 58)
" следует отметить, что в.таблицу енрр1оуесевуужа была вставлена пврвоибчальнал стбоаа) ' Лсатсыу ПреаедпюинапухаааННСй:.ВЫШВ Слзрзцлнуапотаахй Нз.вмазала ПОЛйбаянавщв СдНСЭ ": оыибки.' в противясь. случае лришловь бй вначале зсузаить сурсауяа''таблиду,.'Еир)1оуеея. .и тслькоьъодлвя этот)с СЖД';бй: бвбюг' подводила бы вввбти:насбходлму)с строку в таблицу, О:беда '(наводним, нтб на твблнце еир1оуееэ взлвн внешний ключ), Таким образом, в таблице Спзговегэ уже имеются сведения о заказчике с идентификатором СОБСовег1О, равным 1 (если с таблицей Спяьовегя проводились какие- либо эксперименты, то в действительности идентификатор заказчика может оказаться другим).
Теперь появилась возможность взять числовое значение идентификатора и применить его в следующем операторе 1МБЕЕТ (который наконец-то будет применимым к таблице Ого)егз). Итак, выполним вставку данных о заказе, относящихся к заказчику с идентификатором Спзьовег1Р, равным 1: Ограничения 229 ТИЯКВт тнтО ОгбегоеСазтз ЧАЬОЕЯ (1, '4Х4525', 'Тын 1з а рагС', 25.00, 2] тняКВт тмтО Огбегоегахтз УАТОКЯ (1, 'ОВ2400', 'Тита тз апоглег рагг', 50.00, 2) Теперь приступим к проверке результатов, выполнив следующий оператор Безвест: ЯКЬКСт Огбегтп, Рагтно РВОМ О бегоетазтз Это, как и следовало ожидать, приведет к получению таких двух строк: Огбег1О РагСИо ОВ2400 4Х4525 (2 гон(з) аттесгеб) На данном этапе подготовлены все данные, необходимые для проверки действия конструкции САБСАРЕ, поэтому приступим к экспериментам.
Для этого удалим одну строку из таблицы Огбегя и посмотрим, какое действие окажет эта операция удаления на таблицу ОгбегРеСа11я: ОЯЕ АссоцпСТпд — Вначале рассмотрим строки в обеих таблицах БЕЬЕСТ * РВОМ Огбегз БЕЬЕСТ * РВОМ ОгбегоеСа11з -- Затем удалим строку Огбег ОЕ1ЕТЕ Огбегз ИНЕВЕ Огбег10 = 1 — Наконец, еще раз рассмотрим оба набора данных и определим, в чем -- состоит результат каскадного действия БЕЬЕСТ * РВОМ Огбегз ЯЕЬЕСТ * РВОМ Огбегоета11з В конечном итоге вырабатываются такие интересные результаты: Огбег10 Созтоиегно ОгбегоаСе Еир1оуее10 2000-07-13 22:10:00 1 (1 гон(з) аттесСеб) Огбег1О РагСИо опТСРгтсе ОСу Оезсгтротоп Тата Тз апоСЬег рагг 50.0000 2 Тньз тз а рагС 25.0000 2 ОВ2400 4Х4525 (2 гон(з) аттесгеб) И только после этого появляется возможность осуществить вставку данных в таблицу Огбегоеса11з.
Но для того чтобы пример, в котором рассматривается конструкция САБСАРЕ, стал более наглядным, будут вставлены две строки, а не одна: л30 Глава 6 (1 гон(я) аггессеа) Огс(ег1О Спясопегио Огоеграсе Епр1оуее1О (О гон(я) аееесгес)) Огаег1О Раггно Оп1ГРгзсе Осу Оеясгзрьуоп (О гон(я) аееесгеа) Обратите внимание на то, что в операторе ОЕЬЕТЕ была указана только таблица Огс)егя, но несмотря на это, действие операции удаления распространилось также каскадным путем на строки таблицы Огс)егОега11я, согласующиеся с удаляемой строкой, поэтому произошло удаление строк из обеих таблиц.
Если бы таблица ОгйегОеСа11я была определена с конструкцией САБСАОЕ, касающейся обновления, и произошло обновление соответствующей строки, то результаты операции обновления также были бы распространены на эту дочернюю таблицу, Огс(егОеса11я. Следует учитывать, что пределы ггутгны, на котоРую могут (заслРостфанлть дм1ствил конструкции САБСАОЕ, не установлены. Напримеф, если бы была обьявлена таблица БЛ1ртепСОега11я с конст)эукцизч1 САБСАОЕ, которая ссылоеякл на соуоки таблицы Огс(егОе Саз1я, то пртсзошло бы удаление строк и из таблицы БЛзртепСОегаз1я в Результате применения лить одного оператоРа ОЕ1 Е ТЕ к таблице Ого(егя.
В действительности этот аспект шпользованил каскадных действий явллется одним из самых опасных. Дело в том, что иногда бывает очень т))удно понять, к каким ззосгедппвилм для бовы данных может пРивесгли выпагнение единственного оператора ОЕЬЕТЕ или ((РОАТЕ.
По этой и по д))угим пучсчинаи автоР не вполне одаб)злезп применение каскадньсх действий. Рассчитывая на них, пРогроммисты пытаются сэкономить свои усилия по разработке кода, но каскадное осуществление действий не всегда п))иводит к наилучшим последствиям, особенно когда Речь идет об удалении данных! Другие варианты действий, осуществляемых с помощью конструкции САБСАОЕ Выше в данной главе были приведены примеры каскадных обновлений и удалений, но в определении конструкции САБСАОЕ предусмотрены еще два вида каскадных действий — БЕТ МОЬЬи БЕТ ОЕЕАОЬТ. Эти ключевые слова были впервые введены в версии БОЬ Яегчег 2005, поэтому, если необходимо обеспечить обратную совместимость с программным обеспечением БЯЕ Яегчег 2000, следует избегать их применения. Однако в целом соответствующие действия осуществляются очень просто: если выполняется операция обновления, в результате которой изменяется значение в строке родительской таблицы по отношению к другой строке, то в строке дочерней таблицы задается либо Х~ЛЛ:значение, либо значение, предусмотренное по умолчанию для соответствующего столбца (в зависимости от того, выбрано ли ключевое слово БЕТ ИОЬЬ или БЕТ ОЕРАУЬТ).
Результаты применения указанных ключевых слов сводятся только к этому. Другие вопросы, связанные с использованием внешних ключей Прежде чем завершить описание внешних ключей, необходимо затронуть некоторые другие темы. Безусловно, в настоящей книге мы будем снова и снова возвращаться к проблематике применения внешних ключей, но на данный момент необходимо отметить ряд дополнительных нюансов: Ограничения 231 под влиянием чего значения в столбцах внешних ключей могут становиться обязательными или необязательными; Сз благодаря чему действие внешних ключей становится двунаправленным.
Причины, по которым значения в столбцах внешних ключей могут становиться обязательными или необязательными Согласно самому определению внешнего ключа, предусмотрены два указанных ниже возможных варианта заполнения данными столбца (или столбцов), на котором определен внешний ключ. й Заполнение столбца значениями, которое согласуются со значениями соответствующего столбца в таблице, указанной в ссылке. П Полный отказ от заполнения столбца какими-либо действительными значениями и ввод вместо них Х()ЬЬ-значений.
Прежде всего можно предусмотреть такой вариант заполнения столбца внешнего ключа, чтобы он стал полностью обязательным (в результате чего пользователи таблицы с внешним ключом будут вынуждены применять только первый вариант из приведенного выше списка).
Для этого достаточно определить ссылающийся столбец как имеющий конструкцию НОт НиЬЬ. Таким образом, в столбце родительской таблицы не будет разрешено использование Х()ЬЬ-значений, а поскольку столбец внешнего ключа будет обязан содержать только значения, отличные от нпьь, чтобы обеспечить согласование со значениями в таблице, указанной в ссылке, то заведомо удастся обеспечить согласование каждой строки ссылающейся таблицы хотя бы с одной из строк таблицы, указанной в ссылке. Иными словами, связь между родительской и дочерней таблицами становится обязательной. Если же допускается, чтобы ссылающийся столбец содержал МБЬЬ-значения, то к таблицам предъявляются аналогичные требования, не считая того, что пользователь получает также возможность не задавать значение, поэтому допускается вставка в ссылающуюся таблицу строк, содержащих )ч()ЬЬ-значения в столбце внешнего ключа, даже несмотря на то, что нпьь не может быть согласован со Х()ЬЬ-значением в таблице, указанной в ссылке.
Причины, по которым действие внешних ключей становится двунаправленным Мы вкратце коснулись этой темы при описании каскадных действий, но, возможно, еще недостаточно подчеркнули ту мысль, что в результате определения внешних ключей ограничения по существу налагаются на обе таблицы. Вплоть до этого момента проблематика внешних ключей рассматривалась с точки зрения использования ссылающейся таблицы, но после определения внешнего ключа приходится также соблюдать некоторые требования и при использовании таблицы, указанной в ссылке. ПЕ 'уМОЛЧаНИЮ-йЕЛЬЗя удаюятв 'СтрОКу.'В'табпнцв,' ухаЗайясй, В.ОСЫЛКЕ, ИЛИ 'О6НОВЛсятв:ОтОЛ- ': бвца табянца, указаннсй.я Совщхсв,ЕСЛН 'На.осстеатотау)кнцуЮ!СГтрцху.ухаамяаатт Оосвщха НЗ дйаисныой тебьяйцьк-еслй же есть необходимость,обеспечйт(ь удайение илн обновйение такосй строки, то дляполученияподобнойвозсможности требуетсн предусмотреть нрнмененне каскадных действйи в операциях 'удаления и',(йли) абновлеиия.
Проанализируем более подробно принцип, согласно которому нельзя удалять или обновлять строку, указанную в ссылке. 232 Глава 6 Выше в данной главе был приведен пример, в котором было определено несколько внешних ключей для таблицы Огг(егз. Один из этих внешних ключей ссылается на столбец Екр1оуее1Р таблицы Екр1оуееэ.
Предположим, например, что в компании около двух лет работал служащий с идентификатором Еыр1оуее1Р, равным 10, который ввел много заказов, а затем решил уволиться и перейти на другую работу. Было бы вполне резонным такое решение — удалить из таблицы Етр1оуеез строку с информацией об этом служащем, но реализация подобного решения привела бы к возникновению весьма существенной проблемы, поскольку в таблице Огбегэ появились бы так называемые висячие стдохи Иными словами, в таблице Огбегз осталось бы большое количество строк, в которых по-прежнему было бы указано значение Еир1оуее1Р, равное 10. Таким образом, если бы была возможность удалить строку из таблицы Евр1оуееэ с идентификатором Еыр1оуее1Р, равным 10, то была бы исключена другая возможность — мы больше не могли бы определить, кто из служащих ввел те или другие заказы.
Это означает, что соответствующее значение в столбце Евр1оуее1Р таблицы Огбегэ потеряло бы смысл! Теперь проанализируем рассматриваемый пример немного более подробно. На этот раз предположим, что служащий с идентификатором 10 не уволился, а по какойто причине, не имеющей значения в данном контексте, потребовалось сменить идентификационный номер данного служащего. Если бы такое изменение было внесено (с помощью оператора РРРАТЕ) в таблицу Етр1оуееэ, а соответствующее обновление в таблице Огбегз не было предусмотрено, то снова появились бы висячие строки со значением 10 в столбце Емр1оуее10 таблицы Огбегэ, которому не соответствовал бы ни один служащий. Продолжение анализа данного примера в том же направлении приводит к получению еще более интересных результатов! Предположим, что после этого по недосмотру произошла бы вставка новой строки со значением Епр1оуее1Р, равным 10.