0% нашли этот документ полезным (0 голосов)
3 просмотров25 страниц

11 SQL

Глава 11 посвящена языку SQL, который был разработан в 70-х годах для управления данными в реляционных базах данных. Документ описывает ключевые функции SQL, его стандарты, включая SQL:92 и SQL:2003, а также типы данных, поддерживаемые языком. SQL является декларативным языком, позволяющим пользователям выполнять операции с данными, такие как создание баз данных, редактирование данных и выполнение запросов.

Загружено:

bmf50816
Авторское право
© All Rights Reserved
Мы серьезно относимся к защите прав на контент. Если вы подозреваете, что это ваш контент, заявите об этом здесь.
Доступные форматы
Скачать в формате PDF, TXT или читать онлайн в Scribd
0% нашли этот документ полезным (0 голосов)
3 просмотров25 страниц

11 SQL

Глава 11 посвящена языку SQL, который был разработан в 70-х годах для управления данными в реляционных базах данных. Документ описывает ключевые функции SQL, его стандарты, включая SQL:92 и SQL:2003, а также типы данных, поддерживаемые языком. SQL является декларативным языком, позволяющим пользователям выполнять операции с данными, такие как создание баз данных, редактирование данных и выполнение запросов.

Загружено:

bmf50816
Авторское право
© All Rights Reserved
Мы серьезно относимся к защите прав на контент. Если вы подозреваете, что это ваш контент, заявите об этом здесь.
Доступные форматы
Скачать в формате PDF, TXT или читать онлайн в Scribd

Глава 11

Знакомимся с SQL

В середине 70-х годов XX века, сразу после появления реляционной мо-


дели, специалисты БД приступили к разработке принципиально нового
языка, предназначенного для управления данными. Среди огромного
количества пожеланий, предъявляемых к делающему первые шаги язы-
ку, мы выделим самые ключевые. Перспективный язык реляционных
баз данных должен был позволять:
 создавать базы данных, таблицы и другие объекты БД;
 выполнять основные операции редактирования данных в табли-
цах (вставка, модификация и удаление);
 выполнять запросы пользователя к данным, преобразующие хра-
нящиеся в таблицах данные в выходные отношения.

Ко всему прочему разрабатываемый язык должен был в принципе


отличаться от высокоуровневых языков программирования тех лет.
Во-первых, базы данных работают в трехзначной логике. У них наряду
с классическими для любого языка понятиями истина/ложь (True/False)
предусмотрено третье значение неопределенности UNKNOWN. Во-вторых,
новый язык создавался не только в интересах программистов, но и в
интересах пользователей, поэтому в идеале он должен быть не проце-
дурным, а декларативным. В соответствии с этим пользователь лишь
ставит БД задачу (указывает, что ему нужно от БД), а каким образом
СУБД станет решать поставленную задачу, пользователя не интересует.
Стандартом SQL (Structured Query Language) стал в 1986 году благо-
даря Американскому национальному институту стандартов (American
National Standards Institute, ANSI) и Международной организации стан-
дартизации (International Organization for Standardization, ISO). Кстати,
первый стандарт SQL иногда называют по имени принявшей его орга-
низации – ANSI SQL.
Знакомимся с SQL  195

В 1990-х годах официально действующим и общепризнанным


стал считаться стандарт SQL:92, принятый, как вы уже догадались, в
1992 году. Практически любая серьезная компания, разрабатывающая
СУБД, старается поддерживать требования SQL:92.
В 1999 году на сцене появился очередной стандарт. В этом году было
опубликовано пять частей стандарта SQL–3 (SQL:99):

 Framework – концептуальная структура стандарта;


 Foundation – базисное описание SQL.
 Call-Level Interface (SQL/CLI) – уточнения к интерфейсу уровня
вызовов;
 Persisted Stored Modules (SQL/PSM) – уточнение описания храни-
мых процедур;
 Host Language Bindings (SQL/Bindings) – определение правил
взаимо­действия SQL и ряда стандартных языков программиро-
вания.

Спустя некоторое время появилось еще три части стандарта:


 Management of External Data (SQL/MED) – управление внешними
данными;
 Object Language Bindings (SQL/OLB) – правила взаимодействия с
объектно-ориентированными языками;
 Information and Definition Schemas (SQL/Schemata) – информаци-
онная схема.
Однако многие специалисты вновь скептически отнеслись к SQL-3,
обвинив его в незавершенности. Вместе с этим новый стандарт сде-
лал важный шаг в направлении поддержки объектных БД. В частности,
здесь были объявлены структурные определяемые пользователем дан-
ные (User Defined Type, UDT) и типизированные таблицы (Typed Table).
Во многом по этой причине в 2003 году к вопросу модернизации SQL
вернулись вновь. В обновленный стандарт с необходимыми изменени-
ями вошли все части прежнего SQL:99 (правда, часть SQL/Bindings в са-
мостоятельном виде существовать перестала и была включена во вто-
рую часть стандарта SQL/Foundation). В дополнение к перечисленным
выше частям SQL:2003 приобрел еще несколько документов:
 Routines and Types Using the Java Programming Language (SQL/
JRT) – взаимодействие с языком Java;
 XML-Related Specifications (SQL/XML) – работа с XML-документами.
196  Глава 11. Знакомимся с SQL

После 2003 года очередные версии стандарта SQL выходили пример-


но раз в 3–5 лет (рис. 11.1), так что на момент написания этих строк по-
следним действующим стандартом считается SQL:2016, этот стандарт
вобрал в себя наработки всех своих предшественников.

Рис. 11.1. Хронология выхода стандартов SQL

История совершенствования SQL отчасти подтверждает один из не-


писаных законов программирования: лучшее – враг хорошего. С каж-
дым очередным витком развития стандарта все меньше и меньше
производителей программного обеспечения могут его поддерживать в
строгом соответствии с его требованиями. У признанного гуру в облас­
ти баз данных Криса Дейта на этот счет есть хорошее высказывание,
сделанное еще на рубеже веков: «…в наши дни ни один программный
продукт не поддерживает полностью даже SQL:92; вместо этого такие
продукты, как правило, поддерживают то, что можно было бы назвать
“надмножеством подмножества” стандарта…» [19]. Как следствие стан-
дарт не поспевает за производителями, а это неминуемо ведет к появ-
лению различных ветвей языка, что с каждым годом все более и более
минимизирует вероятность появления редакции SQL, однозначно на
100 % поддерживаемой всеми разработчиками ПО.

Замечание
Полную спецификацию стандарта SQL:2016 вы можете найти в интернете на сайте
ISO, например по адресу [Link]
Возможности SQL  197

Возможности SQL
Если читатель только начинает знакомиться с SQL, то необходимо сра-
зу заметить, что это весьма мощный, но далеко не всемогущий язык.
В сферу интересов SQL не попали задачи, стоящие перед прикладным и
тем более системным программистом. Ни реализации низкоуровневых
операций ввода-вывода, ни вопросы построения пользовательского ин-
терфейса, ни организации работы с периферийными устройствами и т.
п. Одним словом, на SQL не напишешь ни одного даже самого элемен-
тарного приложения для Windows, OS X, Linux или для любой другой ОС.

Рис. 11.2. Основные задачи языка SQL

Язык SQL выступает неотъемлемой частью реляционных СУБД и


применяется только в интересах обработки данных. В общем случае
можно выделить следующие задачи SQL (рис. 11.2):
 определение данных. Реализуется средствами подъязыка
определения данными (DDL, Data Definition Language). Язык на-
целен на решение вопросов создания и удаления базы данных и
ее объектов. Перечень объектов БД достаточно велик, это табли-
цы, представления, индексы, курсоры, определения доменов. Ви-
зитной карточкой DDL выступают операторы CREATE, ALTER и DROP;
 манипулирование данными (DML, Data Manipulation Language)
обеспечивает проведение операций вставки, редактирования и
удаления данных из таблиц БД:
• манипулирование данными. Для модификации данных в
распоряжении DML предоставлено три команды: INSERT,
UPDATE и DELETE;
198  Глава 11. Знакомимся с SQL

• построение запросов. Вторая и наиболее востребованная


часть DML, основанная на инструкции SELECT, позволяет из-
влекать данные из одной или нескольких таблиц;
 ограничение доступа к данным. Определяет набор прав пользо-
вателей при работе с объектами БД. В основу положены две ко-
манды GRANT и REVOKE;
 управление курсором позволяет обрабатывать данные построч-
но. Задача решается за счет квартета команд: DECLARE CURSOR, OPEN
CURSOR, FETCH CURSOR, CLOSE CURSOR;
 управление транзакцией. Включает инструкции SET TRANSACTION,
BEGIN TRANSACTION, COMMIT и ROLLBACK. Язык позволяет определять
уровень изоляции транзакции, стартовать, фиксировать или воз-
вращать транзакцию в исходное состояние.
В последующих главах книги мы узнаем, каким образом с помощью
SQL решается большинство из перечисленных выше задач.

Типы данных SQL


Знакомство с языком начнем с рассмотрения поддерживаемых им
типов данных. На рис. 11.3 представлен перечень стандартных типов
данных SQL. В распоряжении СУБД, поддерживающей SQL:92, имеется
богатый набор предопределенных типов данных, который включает:
 точные числовые типы;
 приближенные числовые типы;
 типы для работы с датой и временем;
 временные интервалы;
 логические типы данных;
 строки символов;
 битовые строки.
Если СУБД совместима с более новыми стандартами, то к перечню
добавляется еще несколько типов. В стандарте SQL:2003 их называют
непредопределенными (non-predefined) и даже более жестко – типами
данных, не относящимися к SQL (non-SQL types). С некоторой степенью
допущения их можно причислить к структурным типам данных, име-
ющимся в большинстве высокоуровневых языков программирования:
 коллекции;
 последовательности;
Типы данных SQL  199

 типы данных, определяемые пользователем;


 ссылочные типы.

Рис. 11.3. Типы данных SQL

Кроме того, современные стандарты SQL способны работать с попу-


лярными сегодня форматами данных XML и JSON.
Где используются перечисленные типы данных? Во-первых, при
определении столбцов таблиц. Во-вторых, при объявлении перемен-
ных в хранимых процедурах, функциях, определяемых пользователем,
и триггерах. В-третьих, при организации обмена данными между БД и
клиентским приложением.

Предопределенные типы
Точные числовые типы (exact numeric) предназначены для обслужива-
ния целочисленных значений и значений, имеющих дробную часть без
потерь точности. При задании такого типа данных необходимо указать
два аргумента: точность (n) и масштаб (m). Точность задает общее число
значащих цифр, используемых при отображении числа. Масштаб опре-
200  Глава 11. Знакомимся с SQL

деляет число значащих цифр справа от десятичной точки. Обязательно


должно соблюдаться условие: точность больше масштаба (n>m). Масштаб
не является обязательным аргументом, если его не указывать, то он счи-
тается равным 0. Например, тип данных NUMERIC(5,2) определяет число,
состоящее не более чем из 5 цифр, включая две цифры после запятой.
В табл. 11.1 представлены основные типы точных чисел. Единствен-
ным дополнением к набору точных числовых данных, существовавших
с первых версий стандарта SQL, стал введенный в 1999 году тип данных
BIGINT.

Таблица 11.1. Точные числовые типы

Спецификация Описание
NUMERIC [(n[,m])] Точное число, описываемое аргументами n и m
DECIMAL [(n[,m])] В отличие от NUMERIC, способно хранить число дальше с
или большей точностью, чем определено в аргументе m. Поэто-
DEC [(n[,m])] му говорят, что NUMERIC задает реальное значение точно-
сти, а DECIMAL – минимальное значение точности
BIGINT Тип данных, предназначен для хранения больших целых
чисел (обычно 64 бит). Типы данных BIGINT, INTEGER
и SMALLINT являются частным случаем типа данных
NUMERIC, у которого масштаб установлен в 0, а точность
определена возможностями СУБД
INTEGER
Тип данных, предназначен для хранения целых чисел
или
(обычно 32 бит)
INT
SMALLINT Тип данных, предназначен для хранения малых целых чи-
сел (обычно 16 бит)
Количество байт, необходимых для хранения значений NUMERIC и
DECIMAL, состоит в прямой зависимости от размерности аргумента n. На-
пример, если вы намерены хранить число из 15–16 сохраняемых зна-
ков, то вам потребуется 8 байт, 34–36 знаков – 16 байт.

Замечание
Практически во всех СУБД для работы с денежными величинами на базе NUMERIC
реализован свой собственный специализированный тип данных. Такие типы дан­
ных хранят действительные числа с точностью до 4-го знака после запятой.

Приближенные числовые типы (approximate numeric) представляют


собой тип данных для определения чисел с плавающей точкой, осущест-
Типы данных SQL  201

вляющий хранение числа в научном формате (мантисса плюс порядок).


Имеет аргумент точность (n), но, в отличие от типа NUMERIC, не обладает
масштабом. Термин «приближенный» вовсе не означает, что, внеся в
столбец таблицы число, допустим 4 целых 5 десятых, то на следующий
день вы на этом месте найдете приблизительно 5. Просто тип данных
предназначен для обслуживания значений, не требующих высокой точ-
ности (табл. 11.2).
Таблица 11.2. Приближенные числовые типы данных

Спецификация Описание
REAL Точность и предел значений зависят от СУБД. Как прави-
ло, занимает в памяти 6 байт и в состоянии хранить число
в интервале от –3,4Е – 38 до +3,4Е + 38 с точностью до
7 цифр после запятой
FLOAT [(n)] Аргументом n определяется минимальное значение точ-
ности. Если значение n не указано, то потребует 8 байт
памяти. Тип данных способен хранить число в интервале
от 1,7Е – 308 до +1,7Е – 308 с точностью до 15 знаков
DOUBLE PRECISION Точность определяется версией СУБД, превышает точность
REAL

Логический тип данных (boolean type) языка SQL весьма неординарен.


Особенность заключается в том, что два классических элемента (true/
false) булевой логики здесь дополнены третьим значением – неопре-
деленностью Unknown. Как следствие логика становится более сложной –
трехзначной. В табл. 11.3 представлены результаты основных операций
логического «И» (AND) и «ИЛИ» (OR).
Таблица 11.3. Таблица основных логических операций
Операция AND TRUE FALSE UNKNOWN
TRUE TRUE FALSE UNKNOWN
FALSE FALSE FALSE FALSE
UNKNOWN UNKNOWN FALSE UNKNOWN

Операция OR TRUE FALSE UNKNOWN


TRUE TRUE TRUE TRUE
FALSE TRUE FALSE UNKNOWN
UNKNOWN TRUE UNKNOWN UNKNOWN
202  Глава 11. Знакомимся с SQL

Есть особенность и у операции отрицания NOT. Если оператор NOT,


примененный к истине, возвращает ложь – NOT (TRUE) IS FALSE, а ко лжи,
наоборот, – NOT (FALSE) IS TRUE, то операция отрицания неизвестности
вернет неизвестность NOT (UNKNOWN) IS UNKNOWN.
Тип данных строки символов (characters strings) специализируется на
обслуживании текстовых данных (табл. 11.4). Во всех случаях работы с
текстовыми данными (при объявлении строковой переменной, описа-
нии столбца таблицы, параметра хранимой процедуры и т. п.) следует
указывать размерность строки n.
Таблица 11.4. Строки символов

Спецификация Описание
CHARACTER [n], Тип данных предназначен для создания тек-
или сокращенно стовой строки фиксированной длины. Коли-
CHAR[n] чество символов в строке определяется в
квадратных скобках после указания типа
данных. Если в поле типа CHAR помещается
текстовое значение меньшего размера, чем
размерность поля, то оставшиеся позиции
символов заполнятся пробелами
CHARACTER VARYNG[n], Текстовая строка переменной длины. Мак-
или сокращенно симальный размер строки определяется в
VARCHAR[n] квадратных скобках. Преимущество такого
типа данных над типом CHAR заключается в
том, что здесь пустые позиции не заполня-
ются пробелами и, соответственно, таблица
требует меньшего размера оперативной и
дисковой памяти
NATIONAL CHARACTER [n], Строка национального символьного набора
или сокращенно фиксированной длины
NCHAR [n]
NATIONAL CHARACTER VARYING [n], Строка национального символьного набора
или сокращенно переменной длины
NCHAR VARYING [n]
CHARACTER LARGE OBJECT [n], Тип данных CHARACTER LARGE OBJECT пред-
или сокращенно назначен для определения столбцов таблиц,
CLOB [n] хранящих большие группы символов
NATIONAL CHARACTER LARGE Тип данных NATIONAL CHARACTER LARGE
OBJECT [n] OBJECT предназначен для определения
столбцов таблиц, хранящих большие группы
национальных символов
Типы данных SQL  203

Данные типа CHAR и NCHAR в операторах SQL должны выделяться оди-


нарными кавычками, кроме того, при использовании символов нацио­
нальных алфавитов следует указать спецификацию набора символов,
воспользовавшись командой CHARACTER SET.
STR = 'Символьные переменные берутся в кавычки'

Для данных символьного типа допускается операция сложения (кон-


катенация).
STR = 'Сложение ' + 'строк'

Битовая последовательность (bit strings) предназначена для хранения


любой двоичной информации. Тип данных универсален и позволяет
описывать как простейшие логические данные, так и сложные объекты,
например файлы мультимедиа (табл. 11.5).

Таблица 11.5. Битовые последовательности

Спецификация Описание
BIT [n] Битовая последовательность фиксированной
длины. Аргумент n устанавливает длину после-
довательности в битах. Если аргумент отсутствует
(или установлен в 1), то тип данных используется
для создания полей логического типа (Да/Нет).
Особенность типа данных фиксированной длины
в том, что попытка записать в поле этого типа зна-
чения меньшей длины, чем указано в аргументе n,
приведет к ошибке
BIT VARYNG [n] Битовая последовательность переменной длины.
Максимальное значение битовой последователь-
ности указывается в аргументе n
BINARY LARGE OBJECT [n], Тип данных предназначен для хранения больших
или сокращенно объектов. Например, файлов мультимедиа и изо-
BLOB [n] бражений

За описание значений даты и времени (datetime) отвечает пять типов


данных. Дата представляется в формате общепринятого в большинстве
стран мира григорианского календаря (табл. 11.6).
204  Глава 11. Знакомимся с SQL

Таблица 11.6. Тип данных дата и время

Спецификация Описание
DATE Тип данных включает три поля:
YEAR (год) – от 0001 до 9999;
MONTH (месяц) – от 01 до 12;
DAY (день) – от 01 до 31.
Формат записи: «yyyy–mm–dd».
Полное число позиций, требуемых для отображе-
ния даты (вместе с разделителями), – 11
TIME [(n)] Тип данных включает три поля:
HOUR (часы), MINUTE (минуты), SECOND (секун-
ды). Если аргумент точности (n) не определен, то
полное число позиций (вместе с разделителями)
равно 8, а формат записи: «hh:mm:ss». Если вы
укажете аргумент точности, то получите возмож-
ность работать с долями секунд
TIMESTAMP [(n)] Метка даты-времени, представляющая собой
комбинацию типов данных DATE и TIME
TIME WITH TIME ZONE Тип данных аналогичен TIME плюс два дополни-
тельных значения, характеризующих смещение
от Гринвичского меридиана в часах TIMEZONE_
HOUR и минутах TIMEZONE_MINUTE. Из-за учета
временной зоны количество позиций увеличива-
ется с 8 до 14
TIMESTAMP WITH TIME ZONE Метка даты-времени плюс смещение от Гринвича.
Число позиций для отображения даты, времени и
временной зоны максимальное – не менее 25

Значения даты и времени допускается задавать литералами в оди-


нарных кавычках, перед значением следует указать название типа, на-
пример: TIMESTUMP '2018-11-21 12:00:00'.
Интервал (interval) представляет собой производную от типа дан-
ных дата-время и предназначен для описания промежутка времени
между двумя временными отсчетами. Стандарт SQL различает две ка-
тегории интервалов: год-месяц (year-month) и день-время (day-time).
Как можно догадаться по названию, первая разновидность интервалов
оперирует сравнительно большими значениями год YEAR и месяц MONTH.
Вторая категория интервалов обладает меньшим диапазоном, но в ка-
Типы данных SQL  205

честве компенсации может похвастаться точностью до долей секунды.


В диапазон интервала день-время входят такие значения, как день DAY,
час HOUR, минута MINUTE и секунда SECOND. Синтаксических конструкций
для определения интервала несколько, в самом общем виде достаточно
рассмотреть следующий вариант:
INTERVAL start (p) [TO end (q)]

где: «start» и «end» – YEAR, MONTH, HOUR, MINUTE и SECOND. Явного опреде-
ления параметров «p» и «q» обычно не требуется, в этом случае в них
передается значение по умолчанию – 2. Двойка является минималь-
ным значением для «p», а верхняя ограничивающая планка зависит от
конк­ретной реализации СУБД. Например, мы планируем задать стол-
бец таблицы, предназначенный для хранения временного интервала до
10 000 лет, тогда в команде SQL появится следующая строка:

INTERVAL YEAR (4)

Цифра 4 скажет SQL о том, что в столбце таблицы могут храниться


значения временного интервала до 4 значащих цифр – диапазон от 0
до 9999.
Параметр «q» используется только в тех случаях, когда точность ин-
тервала задается в секундах, тогда «q» определит точность интервала
до долей секунды. По умолчанию q=2, это означает, что мы учитываем
только две значащие цифры перед запятой. Если мы намерены хранить
значение времени с максимальной точностью (до 4 знаков после запя-
той) – присвоим q значение 6:
INTERVAL MINUTE TO SECOND(6)

Для определения конкретного значения в формате типа данных ин-


тервал следует воспользоваться следующим синтаксисом:
INTERVAL '12:54' HOUR TO MINUTE

Как вы догадались – это интервал, равный 12 часам 54 минутам.


С интервалами можно проводить операции сложения и вычитания,
кроме того, интервал можно умножить или разделить на вещественное
число. В операциях с интервалами могут использоваться типы данных
дата-время, например:
DATE '2015-01-01' + INTERVAL '0005-1'
206  Глава 11. Знакомимся с SQL

Операция прибавляет к дате интервал в пять лет и один месяц. В ре-


зультате сложения мы получим новую дату: DATE '2020-02-01'.

Непредопределенные типы
Большинство нестандартных, или, как их еще называют, непредо-
пределенных (non-predefined) типов данных вошло в состав SQL срав-
нительно недавно. В SQL:1999 появилась спецификация коллекции
(collection type) и массива (array), а в SQL:2003 к стандарту добавилось
мультимножество (multiset). Кроме того, стандарт признал право на су-
ществование таких типов, как последовательности, пользовательский
тип, тип данных XML, JSON и ссылочный тип (рис. 11.2).
Основная особенность непредопределенных типов в том, что даже в
действующем стандарте SQL их называют типами данных, не соответ-
ствующими SQL (non-predefined and non-SQL types). Несоответствий
много, но первое, что бросается в глаза, – нарушение требования к
атомарности данных, которое предписывает, чтобы в одной ячейке
таблицы хранилось одно-единственное неделимое значение. И дей-
ствительно, массив, мультимножество и последовательность тяжело
рассматривать как атомарный тип, и если такой тип данных опреде-
ляет колонку таблицы, то мы сразу сталкиваемся с проблемами нор-
мализации данных.
Указанное противоречие появилось из-за стремления разработчи-
ков стандарта расширить возможности реляционных БД по хране-
нию данных и в первую очередь разрешить хранить в БД сложные
объекты, дабы позволить разработчикам создавать объектно-реля-
ционные БД.

Массив
Синтаксическая конструкция по определению массива выглядит сле-
дующим образом:
тип_данных ARRAY [n];

В качестве типа данных может выступать любой допустимый в стан-


дарте тип данных, параметр n описывает число элементов в массиве.
Как видите, стандартный SQL предусматривает лишь задание одномер-
ного массива, определение массивов большей размерности не преду­
смотрено.
INT ARRAY[10];
Типы данных SQL  207

Внимание!
Отсчет элементов в массиве SQL начинается с 1, а не с 0, как в большинстве языков
программирования!

Множество и мультимножество
Множество SET и мультимножество MULTISET отличаются друг от друга
лишь тем, что множество не допускает повтора значений, а мультимно-
жество допускает.
Для задания множества (мультимножества) следует указать тип под-
лежащих хранению данных:
тип_данных MULTISET

Последовательность
Последовательность строится средствами конструктора типа ROW и
представляет собой пары <имя_поля> <тип_данных>. В сконструирован-
ную последовательность может входить несколько пар. Для демонстра-
ции возможностей последовательностей воспользуемся следующим
примером: допустим, что в таблице DEMOTABLE мы собираемся хранить
фамилию, имя и отчество человека в одном столбце FIO. В таком случае
последовательность ROW позволит нам разделить столбец на три части
(листинг 11.1).

Листинг 11.1. Пример использования последовательности

CREATE TABLE DEMOTABLE


(DEMOTABLE_KEY INTEGER PRIMARY KEY,
FIO ROW (SNAME VARCHAR(20),
FNAME VARCHAR(15),
LNAME VARCHAR(15)),
BDAY DATETIME);

Пользовательский тип
Предопределенные типы данных далеко не всесильны и зачастую
не в состоянии охватить все потребности проектируемой БД. В подоб-
ных случаях стандарт предусматривает возможность проектирования
пользовательских типов данных (user-defined types), описание кото-
рых должно сохраняться в системном каталоге. При создании нового
типа данных следует опираться на уже существующие типы.
208  Глава 11. Знакомимся с SQL

Объявленная стандартом SQL:2003 синтаксическая конструкция


определения пользовательского типа весьма громоздкая, мы остано-
вимся на несколько сокращенном варианте:
CREATE TYPE имя типа
[UNDER имя супертипа]
AS тип данных
[DEFAULT] значение
[[NOT] FINALL]

В простейшем случае для создания пользовательского типа «корот-


кая строка» можно воспользоваться следующей конструкцией:
CREATE TYPE SHORT_STRING_TYPE AS CHAR(10)

Стандарт не ограничивает сложности пользовательского типа дан-


ных, что теоретически позволяет нам объявлять достаточно замысло-
ватые структуры (листинг 11.2).

Листинг 11.2. Создание родительской структуры ADDRESS_TYPE

CREATE TYPE ADDRESS_TYPE AS


(ZIPCODE CHAR(6),
CITYNAME VARCHAR(20) NOT NULL,
STREET VARCHAR(20) NOT NULL,
HOME VARCHR(3) NOT NULL)
NOT FINALL

Необязательное ключевое слово FINALL указывает, что пользователь-


ский тип не может иметь подтипов, соответственно, NOT FINALL пред-
полагает, что мы можем создавать дочерние типы данных. Выше был
приведен пример родительского типа данных, специализирующегося
на хранении адреса (почтовый индекс, город, улица и дом). А теперь
подумаем о том, как добавить к нему номер телефона (листинг 11.3).

Листинг 11.3. Создание дочерней структуры ADDRESSEX_TYPE

CREATE TYPE ADDRESSEX_TYPE


UNDER ADDRESS_TYPE
AS
(PHONENUM CHAR(11))
FINALL
Константы  209

Пример демонстрирует, что дочерний подтип данных в состоянии не


только унаследовать родовые характеристики родительского типа дан-
ных, но и дополнить их своими.
Вполне естественно, что возможности пользовательских типов дан-
ных определяются особенностями диалекта SQL. В некоторых СУБД
пользовательские типы пока вообще не поддерживаются, в других от-
личаются от стандарта, в третьих сильно упрощены.

Другие типы
Ссылочный тип (reference types, REF) может применяться при опре-
делении переменных и параметров. Значение ссылки REF может ука-
зывать на строку в типизированной таблице (таблице, описанной на
основе какого-то структурированного типа данных).
Язык XML (Extensible Markup Language) более подробно будет рас-
смотрен немного позднее (см. главу 19), поэтому мы пока ограничим-
ся лишь пояснением, что XML представляет собой язык наращиваемой
разметки, позволяющий описывать структурированные данные.
Тип JSON представляет собой текстовый формат обмена данными,
основанный на JavaScript.
Подводя итоги разговора о дополнительных типах данных SQL, сле-
дует отметить, что в рамках стандарта появились типы данных, проти-
воречащие ряду фундаментальных требований к реляционной модели.
Это указывает на стремление совершенствовать концепцию реляцион-
ных баз данных, внедряя в нее возможности объектно-ориентирован-
ного подхода (см. главу 22).

Замечание
Практически в каждой из СУБД имеются специфичные для нее типы данных, не
имеющие аналогов в стандарте. В качестве характерного примера стоит привести
PostgreSQL, в котором реализованы экзотические типы, предназначенные для хра­
нения пространственных и геометрических данных (BOX, CIRCLE, LINE и т. д.).

Константы
Для числовых типов данных определены константы в виде последова-
тельности цифровых символов с необязательным заданием знака числа
и десятичной точкой:
- 1000.5
210  Глава 11. Знакомимся с SQL

Для определения строковой константы следует воспользоваться оди-


нарными кавычками:
'Иван Иванович Иванов'

При назначении даты и времени лучше всего руководствоваться требо-


ваниями ISO. Дата описывается в формате yyyy-mm-dd, время – [Link].

Преобразование данных
Существование многочисленных типов данных подразумевает возмож-
ность взаимного преобразования значений из одного формата в дру-
гой. В большинстве СУБД поддерживается две разновидности преоб-
разования типов данных: неявное (implicit type conversions) и явное
(explicit type conversions). Неявное преобразование осуществляется
автоматически, без вмешательства разработчика. Например, в MySQL
вполне допустим подход, предложенный в листинге 11.4.

Листинг 11.4. Пример неявного преобразования в MySQL

SELECT 2+'2';
-> 4

В нашем примере MySQL автоматически конвертирует литерал '2' в


число и возвратит результат сложения. Но в этом случае, по крайней
мере, присутствует некоторая логика, чего нельзя сказать о следующем
примере (листинг 11.5).

Листинг 11.5. Демонстрация недостатка неявного преобразования в MySQL

SELECT 'Hello'+2;
-> 2

Попытка «сложить» абсолютно несовместимые величины (текст и


целочисленное значение) не вызовет у MySQL никаких эмоций, и сер-
вер возвратит число 2, хотя логичнее было бы генерировать исключи-
тельную ситуацию. Таким образом, можно сделать вывод, что неявное
преобразование типов далеко не всегда станет вашим надежным по-
мощником, и его можно применять только в тех случаях, когда вы од-
нозначно уверены в типах исходных данных.
Преобразование данных  211

В основу явного преобразования положено выражение CAST.


CAST <исходные данные> AS <целевой тип данных>
Функция способна преобразовать к типу CHARACTER все типы данных,
работающих с датой и временем (листинг 11.6).

Листинг 11.6. Функция CAST в инструкции SELECT

SELECT DNNUM, CAST(DNDATE AS CHAR(24)) AS DNDATE_TXT


FROM DELIVERYNOTE
Надо понимать, что функция CAST() не всесильна и обладает рядом
ограничений, обусловленных логикой и здравым смыслом (табл. 11.7).
Для обозначения типов данных применялись следующие аббревиатуры:
 EN = Exact Numeric,
 AN = Approximate Numeric,
 C = Character (Fixed- или Variable-length, или character large object),
 VC = строка Character переменной длины,
 CL = Character Large Object,
 D = Date,
 T = Time,
 T = Timestamp,
 YM = Year-Month Interval,
 DT = Day-Time Interval,
 BO = Boolean,
 UDT = пользовательский тип,
 BL = Binary Large Object,
 RT = ссылочный тип,
 CT = коллекция,
 RW = последовательность.
Таблица 11.7. Допустимые преобразования типов данных

Исходный тип Целевой тип данных


данных
EN AN VC C D T TS YM DT BO UDT CL BL RT CT RW

Exact Numeric + + + + ? ? ? + ?

Approximate
+ + + + ? + ?
Numeric

Character + + + + + + + + + + ? + ?
212  Глава 11. Знакомимся с SQL

Исходный тип Целевой тип данных


данных
EN AN VC C D T TS YM DT BO UDT CL BL RT CT RW

Date + + + + ? + ?

Time + + + + ? + ?

Timestamp + + + + + ? + ?

Year-Month
? + + + ? + ?
Interval

Day-Time Interval ? + + + ? + ?

Boolean + + + ? + ?

User Defined
? ? ? ? ? ? ? ? ? ? ? ? ? ?
Type

Binary Large
? + ?
Object

Reference type ? ? ? ? ? ? ? ? ? ? ? ? ? ?

Collection type ?

Row types ?

Само собой разумеется, что далеко не все типы данных допускают


взаимную конвертацию своих значений. Например, метку времени
TIMESTUMP не представить в виде интервала INTERVAL, а такой экзоти-
ческий тип данных, как последовательность ROW, не всегда можно пре-
образовать даже в другую последовательность. Поэтому в описании
стандарта SQL определен перечень допустимых преобразований типов
данных (табл. 11.7). Символом «+» в таблице обозначен тот случай, когда
преобразование реально и в результате его осуществления мы не те-
ряем точности данных, если преобразование возможно при стечении
определенных условий, то оно отмечено символом «?». Пустая ячейка
свидетельствует о невозможности корректной трансформации.

Операторы
В SQL, как, впрочем, и в любых других языках программирования, су-
ществует стандартный набор операторов, применяемых для осуществ­
ления математических, логических операций, операций сравнения
и т. п.
Операторы  213

Операция присваивания
В SQL операция присваивания обычно осуществляется с помощью
оператора «=» (реже «:=»). Этот оператор широко применяется в теле
инструкции SELECT (листинг 11.7).

Листинг 11.7. Узнаем число записей в таблице и сохраняем в переменной @X

SELECT @X:=COUNT(*) FROM SUPPLIERS;

Арифметические операторы
Если речь идет о числовых типах данных, то с ними могут осуществ­
ляться следующие стандартные арифметические операции:
 «+» сложения;
 «–» вычитания;
 «*» умножения;
 «/» деления.
Кроме того, в ряде диалектов SQL можно встретить операторы:
 «DIV» целочисленного деления, например 7 DIV 2; -- результат 3;
 «%» (MOD) остатка от деления, например 7 % 2; -- результат 1.
Еще раз подчеркнем, что, за небольшим исключением, в качестве
операндов должны выступать только числа. Технически, если вы допус­
каете неявное приведение типов, то арифметические операции можно
осуществлять и со строковыми данными, при условии что они содер-
жат числовые значения. Кроме того, арифметические операторы могут
использоваться при работе с такими типами данных, как дата, время и
интервал (табл. 11.8).
Таблица 11.8. Операторы, применимые с датой, временем и интервалами

Операнд Оператор Операнд Результат


Datetime - Datetime Interval

Datetime + или - Interval Datetime

Interval + Datetime Datetime

Interval + или - Interval Interval

Interval * или / Numeric Interval

Numeric * Interval Interval


214  Глава 11. Знакомимся с SQL

Логические операторы
Язык SQL поддерживает стандартный перечень логических опера-
ций:
 AND – логическое умножение («И»);
 OR – логическое сложение («ИЛИ»);
 NOT – логическое отрицание («НЕ»).
Ряд диалектов поддерживает оператор:
 XOR – исключение «ИЛИ».
В табл. 11.9 представлены результаты основных операций логическо-
го «И» и «ИЛИ».

Таблица 11.9. Таблица основных логических операций

Операция AND TRUE FALSE NULL

TRUE TRUE FALSE NULL

FALSE FALSE FALSE FALSE

NULL NULL FALSE NULL

Операция OR TRUE FALSE NULL

TRUE TRUE TRUE TRUE

FALSE TRUE FALSE NULL

NULL TRUE NULL NULL

Операция XOR TRUE FALSE NULL

TRUE FALSE TRUE NULL

FALSE TRUE FALSE NULL

NULL NULL NULL NULL

Есть особенность и у операции отрицания NOT. Если оператор NOT,


примененный к истине, возвращает ложь – NOT (TRUE) = FALSE, а ко лжи,
наоборот, – NOT (FALSE) = TRUE, то операция отрицания неизвестности
вернет неизвестность NOT (UNKNOWN) = UNKNOWN.
Операторы  215

Операторы сравнения
В результате выполнения операторы сравнения (отношения) возвра-
щают булевы значения TRUE или FALSE (табл. 11.10) .
Таблица 11.10. Операторы сравнения

Оператор Операция
< Меньше
> Больше
<= Меньше или равно
>= Больше или равно
= Проверка равенства
<=> Не равно, в том числе неопределенности NULL
!=, <> Проверка неравенства

Внимание!
Осуществляя операции сравнения, учитывайте, что среди сравниваемых значений
может оказаться неопределенность NULL.
Замечание
При желании в таблицу операторов сравнения можно добавить специфичные реля­
ционные операторы IS NULL и IS NOT NULL, осуществляющие проверку равенства
и неравенства NULL.

Проверка на неопределенность NULL


В диалектах SQL различных производителей обычно предусмотрено
несколько способов проверки значения на неопределенность.
Синтаксис проверки выглядит следующим образом:
<значение> IS [NOT] NULL

Простой пример проверки предложен в листинге 11.8.

Листинг 11.8. Проверка на неопределенность с помощью IS NULL

SELECT NULL IS NULL, 1 IS NULL;


-> 1 0

Кроме того, часто встречается функция ISNULL(). Функция возвраща-


ет значение 1, если ее аргумент не определен (листинг 11.9).
216  Глава 11. Знакомимся с SQL

Листинг 11.9. Проверка на неопределенность с помощью ISNULL

SELECT ISNULL(NULL), ISNULL(1);


-> 1 0

Конкатенация строк
Операция конкатенации (соединения) строк обычно осуществляется
с помощью оператора «+», но, как всегда, существуют исключения. На-
пример, в диалектах SQL, применяемых в InterBase и FireBird, строки
соединяются оператором двойной вертикальной черты «||», например:
TXT='Hello, '||'InterBase!';.

Встроенные функции
Классический SQL вооружен сравнительно небольшим набором встро-
енных функций (табл. 11.11).
Таблица 11.11. Основные функции SQL

Функция Описание
BIT_LENGTH(битовая строка) Функция позволяет выяснить длину стро-
ки в битах
САSТ(значение AS тип данных) Функция преобразования исходного зна-
чения к новому типу данных. Допустимые
варианты конвертации типов данных
представлены в табл. 11.7
CHAR_LENGTH(символьная строка) Возвращает длину строки в символах
CURRENT_DATE Функция возвращает текущую дату
CURRENT_TIME(точность) Функция возвращает текущее время с
определенной точностью
CURRENT_TIMESTAMP(точность) Функция информирует о дате и времени с
указанной точностью
LOWER(строка) Преобразование текстовой строки к верх-
нему регистру
POSITION(подстрока IN строка) Позволяет выяснить позицию, с которой
начинается вхождение подстроки в строку
SUBSTRING(cтрокa FROM n FOR Возвращает часть строки, начиная с n-го
длина) символа с указанной длиной
Резюме  217

Функция Описание
TRANSLATE(строка USING функция) Преобразование строки с использовани-
ем указанной функции
TRIM(LEADING | TRAILING | BOTH Удаление из строки всех первых (LEADING),
символ FROM строка) последних (TRAILING) или первых и по-
следних (BOTH) символов. Например:

TRIM(LEADING '#' BOTH ' ###Моск­


ва') удалит все символы '#' из строки
' ###Москва'
UPPER(строка) Преобразование всех символов строки к
верхнему регистру

Резюме
Структурированный язык запросов SQL появился на свет вместе с ре-
ляционными базами данных в конце 70-х годов XX века. Это один из
немногих языков, которому за очень короткий промежуток времени
удалось добиться высокого статуса стандарта. На сегодняшний день
действующим стандартом языка реляционных баз данных является
SQL:2016, но, к сожалению, ни одна из имеющихся на рынке коммерчес­
ких СУБД не в состоянии похвастаться абсолютным соответствием не
только SQL:2016, но и его предшественникам. Большинство компаний,
работающих на рынке программного обеспечения, уже давно идут сво-
им путем, развивая свои собственные диалекты SQL.
Неформально язык SQL можно разбить на несколько подъязыков:
подъязык определения данных, манипулирования данными, ограниче-
ния доступа к данным, управления курсором и управления транзакци-
ями.

Вопросы для самопроверки


1. Когда вышел первый стандарт языка SQL?
2. Какая версия стандарта SQL является актуальной на сегодня?
3. Для решения каких задач предназначен SQL?
4. Что имеется в виду, когда говорят, что SQL предназначен для ра-
боты с 3-значной логикой?
5. Какие достоинства и недостатки, на ваш взгляд, есть у SQL?
218  Глава 11. Знакомимся с SQL

6. Дайте классификацию предопределенных типов данных в SQL.


7. Какие типы данных SQL предназначены для работы с:
a) текстом;
b) числовыми значениями;
c) датой и временем;
d) булевыми значениями;
e) большими объектами (например, файлами мультимедиа)?
8. Какие операторы поддерживает SQL?

Вам также может понравиться