Мартин Грубер - Понимание SQL (991940), страница 30
Текст из файла (страница 30)
Что же делать, если мы используем базу данныхкоторая, следуя ANSI, не распознает тип DATЕ? Если мы обьявим поле odate любымтипом числа, мы не сможем использовать наклонную черту вправо (/) или черточку (-)в качестве разделителя. Так как печатаемые номера — это символы ASCII, мы можемобьявить тип поля odate — CHAR. Основная проблема в том, что мы будем должныиспользовать одиночные кавычки всякий раз, когда ссылаемся на значение поля odateв запросе. Нет более простого решения этой проблемы там где тип DATЕ стал такимпопулярным.
В качестве иллюстрации, давайте обьявим поле odate — типом CHAR.Мы можем по крайней мере наложить на него наш формат с ограничением CHECK:CREATE(onumamtodatecnumsnumTABLE Ordersinteger NOT NULL UNIQUE,decimal,char (10) NOT NULL CHECK (odate LIKE '--/--/----'),NOT NULL,NOT NULL);Кроме того, если вы хотите, вы можете наложить ограничение, гарантирующиечто введенные символы — числа, и что они — в пределах значений нашего диапазона.ПРОВЕРКА УСЛОВИЙ, БАЗИРУЮЩИЙСЯ НАМНОГОЧИСЛЕНЫХ ПОЛЯХВы можете также использовать CHECK в качестве табличного ограничения.
Этополезно в тех случаях, когда вы хотите включить более одного поля строки в условие.Предположим, что комиссионные .15 и выше будут разрешены только для продавцаиз Барселоны. Вы можете указать это со следующим табличным ограничениемCHECK:CREATE TABLE Salespeople(snum integer NOT NULL UNIQUE,sname char (10) NOT NULL UNIQUE,city char(10),comm decimal,CHECK (comm < .15 OR city = 'Barcelona'));Как вы можете видеть, два различных поля должны быть проверены, чтобы определить, верен предикат или нет.
Имейте в виду, что это — два разных поля одной итой же строки. Хотя вы можете использовать многочисленые поля, SQL не может проверить более одной строки одновременно. Вы не можете например использовать ограничение CHECK, чтобы удостовериться, что все комиссионные в данном городеодинаковы. Чтобы сделать это, SQL должен всякий раз, просматривая другие строкитаблицы, когда вы модифицируете или вставляете строку, видеть, что значение комиссионных указано для текущего города. SQL этого делать не умеет.Фактически, вы могли бы использовать сложное ограничение CHECK для вышеупомянутого, если бы знали заранее, каковы должны быть комиссионные в разных городах. Например, вы могли бы установить ограничение типа этого:CHECK ((comm = .15 AND clty = 'London')OR (comm = .14 AND city = 'Barcelona')OR (comm = .11 AND city = 'San Jose')..
)Вы получили идею. Чем налагать такой комплекс ограничений, вы могли бы просто использовать представление с предложением WITH CHECK OPTION, котороеимеет все эти условия в своем предикате (смотри Главу 20 и 21 для информации опредставлении и о WITH CHECK OPTION). Пользователи могут обращаться к представлению таблицы вместо самой таблицы. Одним из преимуществ этого будет то,что процедура изменения в ограничении не будет такой болезненной или трудоемкой.Представление с WITH CHECK OPTION — хороший заменитель ограничению CHECK,что будет показано в Главе 21.УСТАНОВКА ЗНАЧЕНИЙ ПОУМОЛЧАНИЮКогда вы вставляете строку в таблицу без указания значений в ней для каждогополя, SQL должен иметь значение по умолчанию для включения его в определенноеполе, или же команда будет отклонена.
Наиболее общим значением по умолчаниюявляется NULL. Это — значение по умолчанию для любого столбца, которому не было дано ограничение NOT NULL или который имел другое назначение по умолчанию.Значение DEFAULT (ПО УМОЛЧАНИЮ) указывается в команде CREATE TABLEтем же способом, что и ограничение столбца, хотя, с технической точки зрения, значение DEFAULT не ограничительного свойства — оно не ограничивает значения, которые вы можете вводить, а просто определяет, что может случиться если вы невведете любое из них.Предположим что вы работаете в оффисе Нью Йорка и подавляющее большинство ваших продавцов живут в Нью Йорке.
Вы можете указать Нью Йорк в качествезначения поля city, по умолчанию, для вашей таблицы Продавцов:CREATE(snumsnamecitycommTABLE Salespeopleinteger NOT NULL UNIQUE,char(10) NOT NULL UNIQUE,char(10) DEFAULT = 'New York',decimal CHECK (comm < 1));Конечно, вводить значение Нью Йорк в таблицу каждый раз когда назначаетсяновый продавец, не такая уж необходимость, и можно просто пренебречь им (не вводя его) даже если оно должно иметь некоторое значение. Значение по умолчанию такого типа, более предпочтительно, чем, например, длинный конторский номер,указывающий на ваше собственное ведомство, в таблице Порядков.Длинные числовые значения — более расположены к ошибке, поэтому если подавляющее большинство (или все) ваших порядков должны иметь ваш собственныйконторский номер, желательно устанавливать для них значение по умолчанию.Другой способ использовать значение по умолчанию — это использовать его какальтернативу для NULL.
Так как NULL (фактически) неверен при любом сравнении,ином чем IS NULL, он может быть исключен с помощью большинства предикатов.Иногда, вам нужно видеть пустые значения ваших полей не обрабатывая их каким-тоопределенным образом. Вы можете установить значение по умолчанию, типа нульили пробел, которые функционально меньше по значению чем просто не установленное значение — пустое значение (NULL). Различие между ними и обычным NULL втом, что SQL будет обрабатывать их также как и любое другое значение.Предположим, что заказчикам не назначены оценки изначально.
Каждые шестьмесяцев, вы повышаете оценку всем вашим заказчикам, имеющим оценку ниже средней, включая и тех кто предварительно не имел никакого назначения оценки. Если выхотите выбрать всех этих заказчиков как группу, следующий запрос исключит всех заказчиков с оценкой = NULL:SELECT *FROM CustomersWHERE rating <= 100;Однако, если вы назначили значение по умолчанию = 000, в поле rating, заказчики без оценок будут выбраны наряду с другими. Приоритет каждого метода зависит отситуации.Если вы будете делать запрос с помощью поля оценки, то захотите ли Вы включить строки без значений, или исключите их?Другая характеристика значений по умолчанию этого типа, позволит обьявитьВам поле оценки — как NOT NULL.Если вы используете его по умолчанию, чтобы избежать значений = NULL, то это— вероятно хорошая защита от ошибок.Вы можете также использовать ограничения UNIQUE или PRIMARY KEY в этомполе.
Если вы сделаете это, то, имеете в виду, что только одна строка одновременноможет иметь значение по умолчанию. Любую строку, которая содержит значение поумолчанию, нужно будет модифицировать прежде, чем другая строка с установкой поумолчанию будет вставлена. Это не так как вы обычно используете значения по умол-чанию, поэтому ограничения UNIQUE и PRIMARY KEY (особенно последнее) обычноне устанавливаются для строк со значениями по умолчанию.РЕЗЮМЕВы теперь владеете несколькими способами управления значениями которыемогут быть введены в ваши таблицы. Вы можете использовать ограничение NOTNULL чтобы исключать NULL, ограничение UNIQUE чтобы вынуждать все значения вгруппе из одного или более столбцов отличаться друг от друга, ограничение PRIMARYKEY, для того чтобы делать в основном то же самое что и UNIQUE но с различнымокончанием, и наконец ограничение CHECK для определения ваших собственныхсделанных на заказ условий, чтобы значения встреченные перед ними могли бы бытьвведены.
Кроме того, вы можете использовать предложение DEFAULT, которое будетавтоматически вставлять значение по умолчанию в любое поле с именем не указанымв INSERT, так же как вставляется значение NULL когда предложение DEFAULT не установлено и отсутствует ограничение NOT NULL.FOREIGN KEY или REFERENCES ограничения, о которых вы узнаете в Главе 19,очень похожи на них, за исключением того, что они связывают группу из одного илиболее полей с другой группой, и таким образом сразу воздействуют на значения, которые могут быть введены в любую из этих групп.РАБОТА С SQL1. Создайте таблицу Порядков, так чтобы все значения поля onum, а также все комбинации полей cnum и snum отличались друг от друга, и так чтобы значения NULLисключались из поля даты.2.
Создайте таблицу Продавцов, так чтобы комиссионные, по умолчанию составляли10%, не разрешались значения NULL, чтобы поле snum являлось первичным ключом, и чтобы все имена были в алфавитном порядке между A и M включительно(учитывая, что все имена будут напечатаны в верхнем регистре).3. Создайте таблицу Порядков, будучи уверенными в том что поле onum больше чемполе cnum, а cnum больше чем snum. Запрещены значения NULL в любом из этихтрех полей.(См. Приложение A для ответов.)19ПОДДЕРЖКАЦЕЛОСТНОСТИ ВАШИХДАННЫХРАНЕЕ В ЭТОЙ КНИГЕ, МЫ УКАЗЫВАЛИ НА ОПРЕДЕЛЕННЫЕ связи, которыесуществуют между некоторыми полями наших типовых таблиц. Поле snum таблицыЗаказчиков, например, соответствует полю snum в таблице Продавцов и таблице Порядков. Поле cnum таблицы Заказчиков также соответствует полю cnum таблицы Порядков.