|
Программирование >> Программирование баз данных
В данном примере впервые в настоящей книге иллюстрируется одна из сложностей, возникающих в процессе эксплуатации реляционной базы данных, - цепочки зависимостей. Цепочка зависимостей обнаруживается в таких ситуациях, когда выполнение операции над некоторым объектом зависит от результатов операции над каким-то другим объектом, что может зависеть от результатов работы еще над каким-то объектом, и т.д. При этом фактически пользователь не может найти приемлемый выход из положения, поскольку возникновение указанной ситуации обусловлено структурой самой базы данных. Поэтому пользователь обязан перейти к началу цепочки и выполнять все необходимые в ней действия до тех пор, пока не сможет осуществить действительно требуемую ему операцию. Но, к счастью, чаще всего результаты, которые должны быть получены на промежуточных этапах прохождения цепочки зависимостей, уже имеются в основном в базе данных, пусть даже на одном или двух уровнях зависимостей. В данном случае вставка строки в таблицу OrderDetails может быть осуществлена только при том условии, что в таблице Orders уже будет хотя бы одна строка. Но, к сожалению, дяя ввода строки в таблицу Orders требуется, чтобы в таблице Customers также была хотя бы одна строка. Напомним, что на таблице Orders сформирован внешний ключ. Поэтому вставка требуемой строки должна проводиться поэтапно, начиная, допустим, с вьшолнения следующего оператора: INSERT INTO Customers -- Данные о заказчике; следует учитывать, что -- столбец CustomerNo - столбец идентификации. AVALUES (Billy Bobs Shoes, 123 Main St., I I Vancouver, WA , 98685, Billy Bob, (360) 555-1234, 931234567, GETDATE () В данном случае сформировано значение CustomerlD, равное 1. Если же с таблицей Customers проводились какие-либо эксперименты, то в действительности вден-тификатор заказчика может оказаться другим. Теперь появилась возможность взять числовое значение идентификатора и применить его в следующем операторе INSERT (который наконец-то станет применимым к таблице Orders). Итак, выполним вставку данных о заказе, относящихся к заказчику с идентификатором CustomerlD, равным 1: INSERT INTO Orders (CustomerNo, OrderDate, EmployeelD) VALUES (1, GETDATE0 , 1) Ha этот раз выполнение операции вставки должно завершиться успешно. Причина, по которой проведение указанной выше операции вставки не вызвало появления еще одной ошибки, состоит в том, что в таблицу Employees уже была вставлена первоначальная строка; в противном случае пришлось бы вначале вставить строку в таблицу Employees и только после этого СУБД SQL Server позволила бы ввести необходимую строку в таблицу Orders. (Напомним, что на таблице Employees задан внешний ключ.) И только после этого появляется возможность осуществить вставку данных в таблицу OrderDetails. Но для того чтобы пример, в котором рассматривается конструкция CASCADE, стал более наглядным, будут вставлены две строки, а не одна: INSERT INTO OrderDetails VALUES (1, 4X4525, This is a part, 25.00, 2) INSERT INTO OrderDetails VALUES (1, 0R2400, This is another part, 50.00, 2) Ha данном этапе подготовлены все данные, необходимые для проверки действия конструкции CASCADE, поэтому приступим к экспериментам. Для этого удалим одну строку из таблицы Orders и посмотрим, какое действие окажет эта операция удаления на таблицу OrderDetails: USE Accounting -- Вначале рассмотрим строки в обеих таблицах SELECT * FROM Orders SELECT * FROM OrderDetails -- Затем удалим запись Order DELETE Orders WHERE OrderlD = 1 -- Наконец, еще раз рассмотрим оба набора данных и определим, в чем состоит -- результат каскадного действия SELECT * FROM Orders SELECT * FROM OrderDetails В конечном итоге вырабатываются такие интересные результаты: OrderlD CustomerNo OrderDate EmployeelD (1 row{s) OrderlD 2000-07-13 22:18:00 affected) PartNo Description 0R2400 4X4525 This is another part This is a part UnitPrice 50.0000 25.0000 (2 row(s) affected) (1 row{s) OrderlD affected) CustomerNo OrderDate EmployeelD (0 row{s) affected) OrderlD PartNo Description UnitPrice (0 row(s) affected) Обратите внимание на то, что применение операции удаления к таблице Orders привело к распространению каскадного удаления на согласующиеся строки, которые находятся в таблице OrderDetails. Записи в обеих таблицах были удалены. Если таблица определена с конструкцией CASCADE, касающейся обновления, и происходит обновление соответствующей строки, то результаты операции обновления распространяются также на дочернюю таблицу. Следует учитывать, чтю пределы глубины, на которую могут распространяться действия конструкции CASCADE, не установлены. Например, если бы бьша объявлена таблица ShipmentDetails с конструкцией CASCADE, которая ссьшается на строки таблицы OrderDetails, то произошло бы удаление строк и из таблицы ShipmentDe tails в результате применения лишь одного оператора DELETE к таблице Orders. В действительности этот аспект иепользования каскадных действий является одним из самых опасных. Дело в том, что иногда бывает очень трудно понять, к каким последствиям для базы данных может привести выполнение единственного оператора DELETE или UPDATE. По этой и по другим причинам автор не вполне одобряет применение каскадных действий. Рассчитывая на них, программиеты пытаются сэкономить свои усилия по разработке кода, но каскадное осуществление действий не всегда приводит к наилучшим последствиям, особенно когда речь идет об удалении данных! Другие варианты действий, осуществляемых с помощью конструкции cascade В СУБД SQL Server, особенно в последних версиях, предусмотрена возможность выполнять не только каскадное обновление и удаление, но также два других типа каскадных действий. Для этого, в частности, применяются конструкции SET NULL и SET DEFAULT. Эти ключевые слова были впервые введены в версии SQL Server 2005, поэтому, если необходимо обеспечить обратную совместимость с программным обеспечением SQL Server 2000, следует избегать их применения. Однако в целом соответствующие действия осуществляются очень просто: если выполняется операция обновления, в результате которой изменяется значение в строке родительской таблицы по отношению к другой строке, то в строке дочерней таблицы задается либо NULL-значение, либо значение, предусмотренное по умолчанию для соответствующего столбца (в зависимости от того, выбрано ли ключевое слово SET NULL или SET DEFAULT). Результаты применения указанных ключевых слов сводятся только к этому. Причины, по которым значения в столбцах внешних ключей могут становиться обязательными или необязательными Согласно самому определению внешнего ключа, предусмотрены два указанных ниже возможных варианта заполнения данными столбца (или столбцов), на котором определен внешний ключ. Заполнение столбца значениями, которые согласуются со значениями соответствующего столбца в таблице, указанной в ссылке. Полный отказ от заполнения столбца какими-либо действительными значениями и ввод вместо них NULL-значений. Прежде всего можно предусмотреть такой вариант заполнения столбца внешнего ключа, чтобы он стал полностью обязательным (в результате чего пользователи таблицы с внешним ключом будут вынуждены применять только первый вариант из
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |