Язык структурных запросов SQL

advertisement
Министерство образования Российской Федерации
Томский политехнический университет
__________________________________________________________________
УТВЕРЖДАЮ
Директор ИДО
_____________А.Ф. Федоров
“____” ____________ 2004 г.
БАЗЫ ДАННЫХ
Методические указания к курсовому проектированию
для студентов специальности 220400 “Программное обеспечение
вычислительной техники и автоматизированных систем”
Института дистанционного образования
Томск 2004
УДК 681.324.016
Базы данных: методические указания к курсовому проектированию для
студентов
специальности
220400
“Программное
обеспечение
вычислительной техники и автоматизированных систем” ИДО / Сост. А.А.
Пономарев. Том. политех. ун-т –Томск, 2004. – 100 с.
Методические указания рассмотрены и рекомендованы к изданию
методическим семинаром кафедры автоматики и компьютерных систем "30"
октября 2003 г.
Зав. кафедрой, профессор, д.т.н. _______________Г.П. Цапко
Аннотация
Методические указания к курсовому проектированию по курсу “Базы
данных” предназначены для студентов специальности 220400 “Программное
обеспечение вычислительной техники и автоматизированных систем” и
представляют собой рассмотрение реляционной модели данных (РМД),
основ языка запросов SQL и языка программирования PERL для реализации
проекта базы данных и разработки web - интерфейса конечного пользователя.
Курсовое проектирование выполняются с использованием СУБД MySQL.
2
Оглавление
Моделирование баз данных средствами Erwin ................................. 4
Методические указания по изучению языка SQL .............................. 9
ЗАПУСК MYSQL ...................................................................................................................................... 10
ВВОД ЗАПРОСОВ .................................................................................................................................... 14
ЗАПРОСЫ НА СОЗДАНИЕ И ИСПОЛЬЗОВАНИЕ БАЗЫ ДАННЫХ .......................................... 19
I. ПРОСТЫЕ ЗАПРОСЫ НА ЯЗЫКЕ SQL .......................................................................................... 25
II. ИСПОЛЬЗОВАНИЕ ФУНКЦИЙ ..................................................................................................... 29
III. ЗАПРОСЫ, ИСПОЛЬЗУЮЩИЕ СОЕДИНЕНИЯ ...................................................................... 30
IV. ГРУППИРОВАНИЕ ........................................................................................................................... 32
V. ПОСТРОЕНИЕ ВНЕШНЕГО СОЕДИНЕНИЯ .............................................................................. 33
VI. ОПЕРАТОРЫ МАНИПУЛИРОВАНИЯ ДАННЫМИ. УДАЛЕНИЕ ДАННЫХ .................... 37
VII. ОПЕРАТОРЫ МАНИПУЛИРОВАНИЯ ДАННЫМИ. ВСТАВКА ДАННЫХ ...................... 37
VIII. ОПЕРАТОРЫ МАНИПУЛИРОВАНИЯ ДАННЫМИ. ОБНОВЛЕНИЕ ДАННЫХ ........... 38
Методические указания по изучению языка PERL .......................... 40
ТИП ДАННЫХ В PERL ........................................................................................................................... 41
ПЕРЕМЕННЫЕ ......................................................................................................................................... 43
СКАЛЯРНЫЕ ПЕРЕМЕННЫЕ ............................................................................................................. 43
МАССИВЫ ............................................................................................................................................. 43
ХЭШИ...................................................................................................................................................... 45
УСЛОВИЯ .................................................................................................................................................. 45
ОПЕРАТОРЫ УПРАВЛЕНИЯ ЦИКЛОМ ........................................................................................... 46
ФОРМИРОВАНИЕ PERL-СКРИПТА И ЕГО ВЫЗОВ ИЗ HTML-ФОРМЫ ................................ 50
ОСНОВНЫЕ ЧАСТИ PERL СКРИПТА............................................................................................... 50
ОБЕСПЕЧЕНИЕ ДОСТУПА ПОЛЬЗОВАТЕЛЯ ЧЕРЕЗ HTML- ФОРМУ К БД НА MYSQL .. 56
Учебная литература ............................................................................ 63
3
ВВЕДЕНИЕ
Большинство современных СУБД построено на реляционной модели
данных. Для получения информации из отношений (таблиц) базы данных в
качестве языка манипулирования данными в теоретическом плане
используются три абстрактных языка:
 язык реляционной алгебры;
 язык реляционного исчисления на кортежах;
 язык реляционного исчисления на доменах.
Реляционные системы способны работать на более высоком уровне.
Все операции с данными реализуются программой, называемой DBMS
(система управления базой данных). Обращаться к ней можно только с
помощью операторов языка высокого уровня, хотя некоторые продукты попрежнему поддерживают работу в терминах своих собственных языков.
В качестве практического языка работы с данными в середине 70-х гг.
фирмой IBM разработан язык структурных запросов SQL, ставший
впоследствии стандартом de-facto при работе с базами данных.
Наметившийся в настоящее время переход к крупным корпоративным СУБД
типа Oracle, Informix, Sybase, DB2, Progress делает актуальным изучение
языка SQL как в практическом плане, так и чисто теоретически, поскольку в
основе элементов языка SQL лежат положения теории отношений, теории
множеств и логики.
Моделирование баз данных средствами Erwin
Для создания логических и физических моделей данных с помощью
CASE (средств разработки информационных систем) в учебном курсе
предполагается использование технологии IDEF X и ее реализация в ПО
ERwin.
Система ERwin поддерживает прямое и обратное моделирование баз
данных. При прямом моделировании схема базы данных описывается в
прямом виде с использованием диаграммы сущность-связь. Сущности на
диаграмме представляются прямоугольниками. Каждый прямоугольник
может иметь различные визуальные атрибуты. Каждой сущности должно
быть присвоено уникальное имя. Имена сущностей необходимо задавать в
единственном числе. Это определяется тем, что система всегда оперирует
отдельными экземплярами сущности. При этом отдельные экземпляры
сущности рассматриваются как объекты, а сущности – как класс объектов.
Если сущности были описаны при моделировании в BPwin, то их можно
просто импортировать в ERwin (рис. 1).
4
Рис. 1. Пример диаграммы с созданными сущностями
Следующий этап создания модели состоит в задании атрибутов для
каждой сущности. При задании типа атрибута имеется возможность
использовать домены (рис. 2,3). Домен – это абстрактный пользовательский
тип, который присваивается любому физическому типу данных. При этом
каждый домен может иметь свои значения по умолчанию и правила проверки
вводимых данных (рис. 4,5). ERwin предоставляет возможность
документировать все действия по созданию собственных типов данных. С
использованием концепции домена обеспечивается переносимость базы
данных на различные аппаратные платформы.
5
Рис. 2. Создание нового домена
Рис. 3. Указание свойств нового домена
Рис. 4. Значение по умолчанию для нового домена
6
Рис. 5. Использование домена для указания типа данных атрибуту
Связи на диаграмме представляются линиями, идущими от одной
сущности (таблицы) к другой. Каждой связи присваивается уникальное имя.
Связанные таблицы разделяют на родительские и дочерние. Родительские
таблицы отображаются прямоугольниками с прямыми углами, дочерние – со
скругленными.
После указания всем атрибутам формата данных (рис. 5) необходимо
созданную логическую модель преобразовать в физическую. Для этого
необходимо в меню “Tools” выбрать “Derive New Model”, где в качестве
Target Databases указать “ODBC/Generic” (для использования в СУБД
MySQL), см. рис. 6. Наша модель (см. рис 1) будет преобразована к виду,
представленному на рис. 7.
Далее, выбрав в меню “Tools/Forward Engineer/Shema Generation”
(см. рис. 8) и задав необходимые настройки, получим в меню Preview код на
языке SQL для реализации схемы БД в СУБД MySQL.
7
Рис. 6. Преобразование логической структуры в физическую
Рис. 7. Физическая модель с указанием формата данных
8
Рис. 8. Генерация кода SQL
Полученный код можно использовать для реализации БД в СУБД
MySQL. Ниже рассмотрены основные этапы реализации проектов БД в
указанной СУБД.
Методические указания по изучению языка SQL
Предлагаемые методические указания по изучению языка SQL
содержат набор тем, выполнение которых позволит слушателям получить
начальные навыки по работе с базами данных и формированию запросов на
языке SQL. Каждая тема предлагает последовательное изучение конструкций
операторов языка SQL по мере их усложнения.
Общая схема выполнения заданий по каждой теме следующая:
ставится содержательная задача, предлагается запись запроса на языке SQL,
дается результат запроса. Далее необходимо с использованием
инструментальных средств работы с SQL подготовить предлагаемый запрос
на языке SQL и убедиться в правильности получения решения. При
необходимости поясняются конструкции языка SQL и делаются другие
замечания методического характера, способствующие усвоению материала.
Изучение языка предполагается проводить на ядре MySQL - набор
подпрограмм, которые использовались в высокотребовательном окружении
много лет, в то время как MySQL все еще находится в разработке, но уже
предоставляет богатый и полезный функциональный набор таких программ.
MySQL - это система управления базами данных. База данных
представляет собой структурированную совокупность данных. Эти данные
9
могут быть любыми: от простого списка предстоящих покупок до перечня
экспонатов картинной галереи или огромного количества информации в
корпоративной сети. Для записи, выборки и обработки данных, хранящихся в
компьютерной базе данных, необходима система управления базой данных,
каковой и является программное обеспечение (ПО) MySQL. Поскольку
компьютеры замечательно справляются с обработкой больших объемов
данных, управление базами данных играет центральную роль в вычислениях.
Реализовано такое управление может быть по-разному: как в виде отдельных
утилит, так и в виде кода, входящего в состав других приложений.
MySQL - это система управления реляционными базами данных. В
реляционной базе данных данные хранятся не все скопом, а в отдельных
таблицах, благодаря чему достигается выигрыш в скорости и гибкости.
Таблицы связываются между собой при помощи отношений, благодаря чему
обеспечивается возможность объединять при выполнении запроса данные из
нескольких таблиц. Язык SQL как часть системы MySQL можно
охарактеризовать как язык структурированных запросов плюс наиболее
распространенный стандартный язык, используемый для доступа к базам
данных.
ПО MySQL является системой клиент-сервер, которая содержит
многопоточный SQL-сервер, обеспечивающий поддержку различных
вычислительных машин, баз данных, а также несколько различных
клиентских программ и библиотек, средства администрирования и широкий
спектр программных интерфейсов (API).
Методические указания представляют собой обучающий курс по
MySQL: демонстрируется использование клиентской программы mysql для
создания несложной базы данных и работы с ней. Утилита mysql (иногда
называемая также “терминальным монитором”, или просто “монитором”)
представляет
собой
интерактивную
программу,
позволяющую
подсоединяться к MySQL-серверу, запускать запросы и просматривать
результаты. Программа mysql может работать и в пакетном режиме; для
этого необходимо записать все запросы в файл, а затем передать его
содержимое на исполнение mysql.
Запуск MySQL
Управление сервером обычно осуществляется из командной строки.
Запуск в Windows 95/98/2000 осуществляется через сеанс DOS выполнением
следующей команды:
D:\usr\local\Mysql\bin>mysqld --standalone
Эта команда запустит демон mysql в фоновом режиме. В Windows
95/98 не предусмотрен запуск mysqld в виде службы. В Windows 2000 демон
mysql запускается в виде службы.
10
Можно осуществить запуск winmysqladmin.exe, в этом случае все
настройки перечисляются в файле my.ini
При запуске mysqld можно указывать следующие опции:
-?, --help
Справка
-b, --basedir=[path]
Путь к каталогу, в котором установлен mysql
-h, --datadir [homedir]
Путь к каталогу, в котором хранятся базы данных
-l, --log=[filename]
Имя журнала транзакций
-L, --language=[language] Язык по умолчанию (обычно English)
-P, --port=[port]
Порт для соединения
--skip-grant-tables
Игнорировать таблицы привилегий. Это дает
любому ПОЛНЫЙ доступ ко всем таблицам. Не
следует предоставлять обычным пользователям
разрешений на запуск mysqld
--skip-name-resolve
Позволяет предоставлять доступ только тем
хостам, чьи IP-адреса указаны в таблицах
привилегий. Ипользуется для более высокого
уровня защиты
--skip-networking
Использовать
подключения
только
через
интерфейс localhost
-V, --version
Вывести информацию о версии
Наличие в статусной строке иконки светофора с активным зеленым
цветом указывает на то, что сервер запущен (рис. 9).
Рис. 9. Приложение winmysqladmin запущено
Если же активен красный цвет, то необходимо запустить сервер, как
показано на рис. 10, нажав на иконку правой клавишей мышки.
Рис. 10. Активизация сервера MySQL
Теперь можно попытаться войти в сервер. В случае если
предполагается управление сервером через консоль, то необходимо
использовать команду mysql. Изначально существует единственный
пользователь, которому предоставляется право входа - root, который не
имеет пароля. Первое, что нужно сделать - войти под именем root,
зарегистрировать нового пользователя и установить для него пароль.
Команда mysql может использовать следующие опции:
-?, --help
Справка
-h,--hostname=[hostname] Имя сервера mysql
11
-u, --user=[user]
Имя пользователя для доступа к mysql
-p, --password=[password] Пароль пользователя для доступа к mysql
-P, --port=[port]
Порт для соединения с сервером
-V, --version
Информация о версии
Примечание. Команды mysqld и mysql имеют еще некоторые опции,
но в данный момент они особого интереса не представляют.
Запуск из сеанса ДОС осуществляется, как показано ниже (в указанном
случае осуществляется подключение к БД MySQL – рис. 11,12).
Рис. 11. Запуск консоли MYSQL
Рис. 12. Успешный запуск консоли
Если Вы это получили, значит, Вы успешно вошли в консоль mysql,
которая используется для администрирования сервера. Просмотр списка БД,
доступных на сервере, осуществляется командой SHOW DATABASES.
Командой USE MYSQL; выбираем текущую БД, где MYSQL - имя БД.
12
При подключении к серверу с помощью mysql обычно нужно ввести
имя пользователя MySQL и в большинстве случаев пароль. Если сервер
запущен не на том компьютере, с которого Вы вошли в систему, необходимо
также указать имя хоста. Параметры соединения (а именно соответствующее имя хоста, пользователя и пароль) Вы сможете узнать у
администратора. Получив соответствующие параметры, подсоединиться к
серверу можно следующим образом:
shell> mysql -h host -u user -p
Enter password: ********
Символы ******** обозначают Ваш пароль; введите его, когда mysql
выведет на экран запрос Enter password: Shell – это ДОС - оболочка.
Если все сработает, то на экране должна появиться информация и
метка командной строки mysql>, как показано на рис. 4.
В некоторых вариантах установки MySQL возможно подсоединение к
запущенному на локальном хосте серверу без ввода имени пользователя
(пользователь anonymous). Если ваша система настроена именно так,
подсоединиться к серверу Вы сможете, запустив mysql без параметров:
shell> MySQL
После установки соединения можно в любой момент отключиться от
сервера, набрав в командной строке mysql> команду QUIT:
mysql> QUIT
Bye
Большая часть приведенных ниже примеров построена с учетом того,
что соединение с сервером уже установлено. Это видно по наличию в них
командной строки mysql>.
Указанные операции можно выполнить, используя специализированное
программное обеспечение, например MySQL-Front, в котором также
существует
механизм,
обеспечивающий
наделение
пользователей
определенными правами (см. рис. 13, 14).
13
Рис. 13. Запуск MySQL-front
Рис. 14. Редактирование прав пользователя
Ввод запросов
Подсоединитесь к серверу, как было описано выше. Таким образом,
никакая база выбрана не будет, но это не страшно. На данном этапе нам
гораздо важней разобраться с созданием запросов, нежели сразу усложнять
себе жизнь созданием таблиц, загрузкой в них данных и извлечением их
оттуда. В этом разделе разъясняются основные принципы ввода команд; на
примере нескольких запросов Вы можете поближе познакомиться с работой
mysql.
Ниже приведена простая команда, запрашивающая у сервера
информацию об его версии и текущей дате. Введите ее в командной строке
mysql> и нажмите Enter:
mysql> SELECT VERSION(), CURRENT_DATE;
+--------------+--------------+
| VERSION()
| CURRENT_DATE |
+--------------+--------------+
| 3.22.20a-log | 1999-03-19
|
+--------------+--------------+
1 row in set (0.01 sec)
mysql>
14
Этот запрос иллюстрирует следующие особенности mysql:
 Команда обычно состоит из SQL-выражения, за которым следует
точка с запятой. (Из этого правила есть и исключения - команды без
точки с запятой. Одним из них является упомянутая выше команда
QUIT, остальные мы рассмотрим позднее.)
 Когда пользователь вводит команду, mysql отправляет ее серверу
для выполнения и выводит на экран сначала результаты, а затем - новую
строку mysql>, что означает готовность к выполнению новых команд.
 mysql выводит результаты работы запроса в виде таблицы (строк и
столбцов). В первой строке этой таблицы содержатся заголовки
столбцов, а в следующих строках - собственно результаты. Обычно
заголовками столбцов становятся имена, полученные из таблиц базы.
Если же извлекается не столбец таблицы, а значение выражения (как это
происходит в приведенном выше примере), mysql дает столбцу имя
запрашиваемого выражения.
 mysql сообщает количество возвращаемых строк и время
выполнения запроса, что позволяет в некоторой степени составить
представление о производительности сервера. Эти значения обычно
весьма впечатляют, так как представляют обычное (а не машинное)
время, кроме того, на них оказывает влияние загрузка сервера и скорость
работы сети (для сокращения размеров листингов в остальных примерах
этой глаВы строка "rows in set" удалена).
Для ввода ключевых слов можно использовать любой регистр символов.
Приведенные ниже запросы абсолютно идентичны:
mysql> SELECT VERSION(), CURRENT_DATE;
mysql> select version(), current_date;
mysql> SeLeCt vErSiOn(), current_DATE;
А это - еще один запрос. В нем демонстрируется использование mysql в
качестве несложного калькулятора:
mysql> SELECT SIN(PI()/4), (4+1)*5;
+-------------+---------+
| SIN(PI()/4) | (4+1)*5 |
+-------------+---------+
|
0.707107 |
25 |
+-------------+---------+
Все команды, представленные выше, были относительно короткими и
состояли из одной строки. В одну строку можно поместить и несколько
команд. Но каждая из них должна заканчиваться точкой с запятой:
mysql> SELECT VERSION(); SELECT NOW();
+--------------+
| VERSION()
|
+--------------+
| 3.22.20a-log |
+--------------+
+---------------------+
| NOW()
|
15
+---------------------+
| 1999-03-19 00:15:33 |
+---------------------+
Втискивать все команды в одну строку совсем не обязательно, так что
создание длинных команд, занимающих несколько строк, никаких проблем
не вызывает. Для mysql признаком завершения выражения является точка с
запятой, а не конец строки (другими словами, mysql принимает команды без
форматирования: строки с командами собираются, но не исполняются до тех
пор, пока программа не обнаружит точку с запятой).
Вот пример несложного выражения, занимающего несколько строк:
mysql> SELECT
-> USER()
-> ,
-> CURRENT_DATE;
+--------------------+--------------+
| USER()
| CURRENT_DATE |
+--------------------+--------------+
| joesmith@localhost | 1999-03-18
|
+--------------------+--------------+
Обратите внимание на то, как изменилась метка командной строки (с
mysql> на ->) после ввода первой строки этого запроса. Таким образом
программа mysql показывает, что завершенного выражения она пока что не
получила и ожидает его полного ввода. Эта метка очень полезна, так как
предоставляет весьма ценную информацию о состоянии программы. С ее
помощью всегда можно узнать, чего ждет mysql.
Если Вы решите отменить исполнение набираемой команды, наберите
\c:
mysql> SELECT
-> USER()
-> \c
mysql>
Обратите внимание на метку: после ввода команды \c она снова
принимает вид mysql>, показывая, что программа mysql перешла в режим
ожидания указаний.
В этой таблице приведены все возможные варианта вида метки
командной строки и соответствующие им состояния mysql:
Метка
Значение
mysql>
Ожидание новой команды
->
Ожидание следующей строки многострочной команды
'>
Ожидание следующей строки, сбор строкового выражения,
начинающегося с одиночной кавычки (')
">
Ожидание следующей строки, сбор строкового выражения,
начинающегося с двойной кавычки ('')
Обычно многострочные команды получаются случайно, когда хочешь
создать обычную команду, но забываешь поставить завершающую точку с
запятой. В таком случае mysql ожидает продолжения:
16
mysql> SELECT USER()
->
Если с Вами произошло подобное (Вы думаете, что завершили
команду, но программа выдает только метку ->), то mysql, вероятнее всего,
ждет точки с запятой. Не обратив внимание на метку командной строки,
можно довольно долго ждать выполнения команды, не понимая в чем дело. А
достаточно лишь поставить точку с запятой, завершив команду, которую
mysql и выполнит:
mysql> SELECT USER()
-> ;
+--------------------+
| USER()
|
+--------------------+
| joesmith@localhost |
+--------------------+
Метки '> и "> используются при сборе строк. В MySQL строки можно
заключать как в одинарные ('), так и в двойные ('') кавычки (можно,
например, написать 'hello' или "goodbye"), к тому же, mysql позволяет
вводить строковые выражения, состоящие из нескольких строчек текста.
Метка '> или "> обозначает, что Вы ввели строку, открывающуюся символом
кавычек (') или (''), но еще не ввели завершающую строковое выражение
закрывающую кавычку.
Это, конечно, нормально, если Вы собираетесь создать большое
строковое выражение из нескольких строчек. Но это не слишком частый
случай. Гораздо чаще оказывается, что Вы просто забыли поставить
закрывающую кавычку. Например:
mysql> SELECT * FROM my_table WHERE name = "Smith AND age < 30;
">
Если ввести команду SELECT, нажать Enter и подождать результатов,
ничего не произойдет. Тут-то и нужно обратить внимание на метку
командной строки, выглядящую вот так: ">. Это значит, что mysql ждет
ввода завершающей части строки. (Теперь заметили ошибку в команде? В
строке "Smith нет закрывающей кавычки.)
Что делать в этом случае? Проще всего было бы отменить команду.
Однако теперь просто набрать \c нельзя, так как mysql примет эти символы за
часть собираемой строки. Вместо этого нужно ввести закрывающие кавычки
(тем самым дав mysql понять, что строка закончилась) и лишь затем набрать
\c:
mysql> SELECT * FROM my_table WHERE name = "Smith AND age < 30;
"> "\c
mysql>
Метка командной строки снова примет вид mysql>, показывая
готовность mysql к выполнению команд.
17
Знать значение меток '> и "> необходимо, так как при вводе
незавершенной строки все последующие строки будут игнорироваться
MySQL, включая строку с командой QUIT. Это может основательно сбить с
толку, особенно если не знать, что для отмены команды перед
соответствующей последовательностью символов необходимо поставить
закрывающую кавычку.
18
Запросы на создание и использование базы данных
Создать базу данных, при условии наличия необходимых прав, можно
следующим образом:
mysql> CREATE DATABASE your_base;
При создании базы данных она автоматически не выбирается; выбирать
ее нужно отдельно. Текущей базу можно cделать с помощью следующей
команды:
mysql> USE your_base
Database changed
Создавать базу нужно только однажды, но выбирать ее приходится в
каждом сеансе работы с mysql. Делать это можно с помощью команды USE,
представленной выше. А можно выбирать базу и из командной строки при
запуске mysql. Для этого достаточно лишь ввести ее имя после параметров
соединения, которые нужно вводить в любом случае. Например:
shell> mysql -h host -u user -p your_base
Enter password: ********
Обратите внимание: в вышеприведенной команде your_base не
является паролем. Ввести пароль в командной строке после параметра -p
можно без пробела (например, -pmypassword, а не -p mypassword). Впрочем,
пароль в командной строке все равно лучше не вводить, так как таким
образом его могут и подсмотреть.
Эти операции, также как и другие, описанные в этом руководстве,
доступны для использования в программе MySQL-Front (см. рис. 15).
Рис. 15. Создание БД в среде MySQL-front
19
После задания активной БД можно с помощью средств,
предоставляемых программой, изменять структуру БД, вводить данные,
задавать ключевые поля. Помимо этого можно в специально отведенном окне
напрямую вводить инструкции, используя синтаксис языка SQL, как
показано на рис. 16:
Рис. 16. Использование синтаксиса SQL
Будем исходить из того, что стоит задача реализовать базу данных
поставщиков, деталей, изделий и поставок, таблицы которой описаны
следующим образом (рис. 17):
Ï Î ÑÒÀÂÙ ÈÊ [S]
í î ì åð ï î ñòàâù èêà
ÄÅÒÀËÜ [P]
[Snum]
í àçâàí èå ï î ñòàâù èêà [Snam]
ñòàòóñ
[St]
ãî ðî ä ðàçì åù åí èÿ
[Ci]
âû ï î ëí èë
í î ì åð äåòàëè [Pnum]
í àçâàí èå äåòàëè [Pnam]
âåñ
[We]
öâåò
[Co]
ãî ðî ä õðàí åí èÿ [Ci]
âêëþ ÷åí à â
Ï Î ÑÒÀÂÊÀ [SPJ]
í î ì åð ï î ñòàâù èêà [Snum] (FK)
[Jnum]
í î ì åð äåòàëè
[Pnum] (FK)
í àçâàí èå èçäåëèÿ
[Jnam]
í î ì åð èçäåëèÿ
[Jnum] (FK)
î áåñï å÷åí î äàòà ï î ñòàâêè
ãî ðî ä ï ðî èçâî äñòâà [Ci]
[Dt]
êî ëè÷åñòâî
[Qt]
ÈÇÄÅËÈÅ [J]
í î ì åð èçäåëèÿ
Рис. 17. Концептуальная модель учебной базы данных
Структура новой таблицы определяется при помощи команды CREATE
TABLE (см. Приложение С) и в нашем случае имеет вид
CREATE TABLE `j` (
`Jnum` varchar(6) NOT NULL default '',
`Jnam` varchar(20) default NULL,
20
`Ci` varchar(20) default NULL,
PRIMARY KEY (`Jnum`)
) TYPE=MyISAM;
CREATE TABLE `p` (
`Pnum` varchar(6) NOT NULL default '',
`Pnam` varchar(20) default NULL,
`Co` varchar(20) default NULL,
`We` int(11) default NULL,
`Ci` varchar(20) default NULL,
PRIMARY KEY (`Pnum`)
) TYPE=MyISAM;
CREATE TABLE `s` (
`Snum` varchar(6) NOT NULL default '',
`Snam` varchar(20) default NULL,
`St` int(11) default NULL,
`Ci` varchar(20) default NULL,
PRIMARY KEY (`Snum`)
) TYPE=MyISAM;
CREATE TABLE `spj` (
`Snum` varchar(6) NOT NULL default '',
`Pnum` varchar(6) NOT NULL default '',
`Jnum` varchar(6) NOT NULL default '',
`Qt` int(11) default NULL,
PRIMARY KEY (`Snum`,`Pnum`,`Jnum`)
) TYPE=MyISAM;
Создав таблицу, нужно позаботиться об ее заполнении. Для этого
предназначены команды LOAD DATA и INSERT.
Так как Вы начинаете работу с пустой таблицей, заполнить ее будет
проще всего, если создать текстовый файл, содержащий по строке на каждую
вводимую строку таблицы, а затем загрузить его содержимое в таблицу
одной командой.
Создайте текстовый файл с именем `data.txt', содержащий по одной
записи в каждой строке (значения столбцов должны быть разделены
символами табуляции и даны в том порядке, который был определен
командой CREATE TABLE). Незаполненным полям (например, неизвестный
статус или город) можно присвоить значение NULL. В текстовом файле это
значение представляется символами \N.
Загрузить файл `data.txt' в таблицу можно с помощью следующей
команды:
mysql> LOAD DATA LOCAL INFILE "data.txt" INTO TABLE S;
В результате получим заполненную таблицу.
Snum
Snam
St Ci
S1
Smit
20 Лондон
Маркер конца строки и символ, разделяющий значения столбцов,
можно специально задать в команде LOAD DATA, но по умолчанию
21
используются символы табуляции и перевода строки. Воспринимая их,
команда сможет корректно прочитать файл `data.txt'.
При добавлении одиночных записей используется команда INSERT. В
самом простом варианте ее применения необходимо задать значения каждого
столбца в том порядке, в каком они были перечислены в команде CREATE
TABLE. Предположим, появилось новое оборудование. Соответствующую
запись в таблицу J можно внести с помощью команды INSERT примерно так:
mysql>insert into J (Jnum, Jnam, Ci) values ('J1','Жесткий
диск','Париж');
или
mysql>insert into J values ('J1','Жесткий диск','Париж');
В случае если Вы вставляете данные во все поля таблицы, то их
перечислять не обязательно.
Обратите внимание на то, что здесь строковые выражения и даты
представлены в виде ограниченных кавычками строк. Кроме того, в команде
INSERT отсутствующие данные можно прямо заменять на NULL.
Пользоваться эвфемизмом \N, как в команде LOAD DATA, нужды нет.
Этот пример наглядно показывает, что если бы с самого начала все
данные вносились в базу при помощи нескольких команд INSERT, а не
одной команды LOAD DATA, то набирать пришлось бы гораздо больше
текста.
Общие инструкции для использования этих операторов приведены
ниже.
INSERT INTO
Вставляет данные в таблицу
Синтаксис:
INSERT INTO table [(column_name, ...)] VALUES (expression,...) ||
INSERT INTO table [(column_name, ...)] SELECT ...
LOAD DATA INFILE
Команды для чтения
текстового файла
данных
из
Синтаксис:
LOAD DATA INFILE syntax
Пример:
LOAD DATA INFILE Customer.tab' INTO TABLE Customer
Для записи в текстовый файл используйте
SELECT ... INTO OUTFILE 'customer.tab' fields terminated by
',' enclosed by '"' escaped by '\\' lines terminated by '\n' .
“fields terminated by”
Имеет значение по умолчанию \t
22
“fields [optionally] enclosed by”
Имеет значение по умолчанию "
“fields escaped by”
Имеет значение по умолчанию '\\'
Имеет значение по умолчанию '\n'
“fields terminated by” и “lines terminated by” могут быть больше чем
одним символом.
Если “fields terminated by” и “fields enclosed by” являются пустыми
строками, то размер строки будет фиксированным, т.е. будет производиться
чтение полей одной длины.
С фиксированными значениями NULL для размера строки будут
выводиться пустые строки.
Если указаны “optionally” в “enclosed by” и Вы не используете
фиксированный размер строк, только строки с этим символом будут
включены в команду SELECT ... INTO.
Если “escaped by” не пусто, то следующие символы будут снабжены
префиксом “escaped by”, ASCII 0 и первым символом из “fields terminated
by”, “fields enclosed by” и “lines terminated by”.
Если использован REPLACE, новая строка заменит все строки, которые
имеют тот же самый уникальный ключ. Если использован IGNORE, строки
будут пропущены, если там уже существует запись с идентичным
уникальным ключом. Если ни один из вышеупомянутых параметров не
используется, будет выдана ошибка, и остальная часть textfile будет
игнорироваться, если найден дублирующий ключ.
Некоторые ситуации, которые не поддерживаются LOAD DATA
INFILE:
Фиксированные размеры строк (“FIELDS TERMINATED BY” и
“FIELDS ENCLOSED BY” являются пустыми) и поля BLOB.
Разделитель, являющийся префиксом другого разделителя.
“FIELDS ESCAPED BY” пустое и данные содержат один или несколько
разделителей.
Все строки читаются в таблицу. Если строка имеет слишком мало
полей, остальная часть полей в таблице устанавливается в значения по
умолчанию.
По соображениям безопасности textfile должен находиться в каталоге
баз данных или быть читаемым всеми.
Если “FIELDS ENCLOSED BY” не пустое, то NULL читается как
значение NULL. Если “FIELDS ESCAPED” не пустое, то \N тоже читается
как значение NULL. Когда запрос LOAD DATA выполнен, Вы можете
получить следующую строку информации, используя функцию C API
mysql_info():
“lines terminated by”
@result{Records: 1 Deleted: 0 Skiped: 0 Warnings: 0}
23
Переменная Warnings увеличивается с каждым столбцом, который не
может быть сохранен без потери точности для каждого столбца, который не
получал значение из строки текста при чтении (это случается, если строка
слишком короткая), и для каждой строки, которая имеет большее количество
данных, чем может вписываться в данные столбцы.
Вы должны иметь права доступа select и insert в таблице user для
использования этой команды. После выбора способа заполнения необходимо
воспользоваться операторами языка для достижения необходимого
содержания таблиц базы данных. В нашем случае предполагается получить
следующее содержание:
Таблица поставщиков (S)
Hомеp_поставщика
Фамилия
Рейтинг Гоpод
S1
Смит
20
Лондон
S2
Джонс
10
Париж
S3
Блейк
30
Париж
S4
Кларк
20
Лондон
S5
Адамс
30
Афины
Таблица деталей (P)
Номер детали
Название
Цвет
Вес
Гоpод
P1
Гайка
Красный
12
Лондон
P2
Болт
Зеленый
17
Париж
P3
Винт
Голубой
17
Рим
P4
Винт
Красный
14
Лондон
P5
Кулачок
Голубой
12
Париж
P6
Блюм
Красный
19
Лондон
Таблица поставок (SPJ)
Номер поставщика
Номер детали
Дата поставки
Количество
S1
P1
02/01/95
300
S1
P2
04/05/95
200
S1
P3
05/12/95
400
S1
P4
06/15/95
200
S1
P5
07/22/95
100
S1
P6
08/13/95
100
S2
P1
03/03/95
300
S2
P2
06/12/95
400
24
S3
P2
04/04/95
200
S4
P2
03/23/95
200
S4
P4
06/17/95
300
S4
P5
08/22/95
400
Замечания. В целях большей наглядности, при записи запроса на
языке SQL, для создания полей таблиц использованы обозначения на
русском языке.
После того как таблицы БД созданы и наполнены данными,
необходимо создать запросы согласно исходному заданию (см. Приложение
A).
I. Простые запросы на языке SQL
Запрос на языке SQL формируется с использованием оператора Select.
Оператор Select используется:
для выборки данных из базы данных;
для получения новых строк в составе оператора Insert;
для обновления информации в составе оператора Update.
В общем случае оператор Select содержит следующие семь
спецификаторов, расположенных в операторе в следующем порядке:
 спецификатор Select;
 спецификатор From;
 спецификатор Where;
 спецификатор Group by;
 спецификатор Having;
 спецификатор Order by.
Обязательными являются только спецификаторы Select и From. Эти два
спецификатора составляют основу каждого запроса к базе данных, поскольку
они определяют таблицы, из которых выбираются данные, и столбцы,
которые требуется выбрать.
Спецификатор Where добавляется для выборки определенных строк
или указания условия соединения. Спецификатор Order by добавляется для
изменения порядка получаемых данных. Спецификатор Into temp
добавляется для сохранения этих результатов в виде таблицы с целью
выполнения последующих запросов. Два дополнительных спецификатора
оператора Select - Group by (спецификатор группирования) и Having
(спецификатор условия выборки группы) - позволяют выполнять более
сложные выборки данных. В следующих упражнениях рассмотрены
некоторые аспекты языка (в запросах для наглядности использованы другие
обозначения: исходя из смысла данных; при реализациях необходимо
использовать настоящие имена полей, см. рис. 9).
25
Упражнения
1. Выбор всех строк и столбцов таблицы.
Пример
Выдать полную информацию о поставщиках:
Select * from S
Результат: таблица S в полном объеме.
2. Измение порядка следования столбцов.
Пример
Выдать таблицу S в следующем порядке: фамилия, город, рейтинг,
номер_поставщика:
Select фамилия, город, рейтинг, номер_поставщика from S
Результат: таблица S в требуемом порядке.
3. Выбор заданных столбцов.
Пример
Выдать номера всех поставляемых деталей:
Select номер_детали from SPJ
Результат: столбец номер_детали таблицы SPJ.
4. Выбор без повторения.
Пример
Выдать номера всех поставляемых деталей, исключая дублирование:
Select distinct номер_детали from SPJ
Результат:
номер_детали
P1
P2
P3
P4
P5
P6
5. Использование в запросах констант и выражений.
Пример
Select номер_детали, "вес в граммах", вес*454 from P
Результат:
P1 вес в граммах=5448
----------------------------------------P6 вес в граммах=8226
6. Выборка подстрок.
Пример
26
Выдать сокращение фамилий до двух букв и рейтинг поставщика:
Select фамилия[1,2], рейтинг from S
Результат:
Фами
Рейт
лия
инг
См
20
Дж
10
Бл
30
Кл
20
Ад
30
7. Ограничение в выборке.
Пример
Выдать номера всех поставщиков, находящихся в Париже, с рейтингом
больше 20:
Select номер_поставщика from S where город="Париж" and
рейтинг>20
Результат:
номер_поставщика
S3
8. Выборка с упорядочиванием.
Пример
Выдать номера поставщиков, находящихся в Париже в порядке
убывания рейтинга:
Select номер_поставщика from S where город="Париж" order by
рейтинг desc
Результа
т:
номер_поставщ
ика
рейт
инг
S3
30
S2
10
9. Упорядочивание по нескольким столбцам.
Пример
Выдать список поставщиков, упорядоченных по городу, в пределах
города - по рейтингу.
Select * from S order by 4, 3
Результат:
Hомеp_поставщика
Фамилия
Рейтинг
Гоpод
S5
Адамс
30
Атенс
S1
Смит
20
Лондон
S4
Кларк
20
Лондон
S2
Джонс
10
Париж
S3
Блейк
30
Париж
10. Фраза between.
Пример.
27
Выдать информацию о деталях, вес которых лежит в диапазоне от 16
до 19:
Select номер_детали, название, вес from P where вес between 16 and 19
Результат:
номер_детали
название
вес
P2
Болт
17
P3
Винт
17
P6
Блюм
19
11. Фраза in ( not in ).
Пример
Выдать детали, вес которых равен 12, 16 или 17:
Select Номер_детали, Название, Вес from P where Вес in (12, 16, 17)
Результ Номер_детали
Название
Вес
ат:
P1
Гайка
12
P2
Болт
17
P3
Винт
17
P5
Кулачок
12
12. Выбор по шаблону.
Для запросов с поиском по шаблону, основанных на поиске подстрок в
полях типа CHARACTER, используются ключевые слова LIKE и MATCHES.
СИМ
ЗНАЧЕНИЕ
ВОЛ
LIKE
%
заменяет последовательность символов;
-
заменяет любой одиночный символ;
\
отменяет специальное назначение следующего
за ним символа.
MAT
CHES
*
заменяет последовательность символов;
?
заменяет любой одиночный символ;
[]
служит для замены одиночного символа или
символа из диапазона;
\
отменяет специальное назначение следующего
за ним символа.
Примеры
28
Выбрать список деталей, начинающихся с буквы "Б":
Select номер_детали, название, вес from P where название like "Б%"
Результ номер_детали
название
вес
ат:
P5
Болт
12
P6
Блюм
19
Выдать список фамилий поставщиков, начинающихся с букв [В-Н]:
Select фамилия from S where фамилия matches "В-Н"
Результат:
фамилия
Джонс
Блейк
Кларк
Подготовьте запрос и проверьте полученный результат.
II. Использование функций
1. Агрегатные функции.
count - число значений в столбце;
sum - сумма значений по столбцу;
avg - среднее значение в столбце.
Примеры
Выдать общее количество поставщиков:
Select count (*) from S
Результат: 5.
Подготовьте запрос и проверьте полученный результат.
Выдать общее количество поставщиков, поставляющих в настоящее
время детали:
Select count ( distinct номер_поставщика ) from SPJ
Результат: 4.
Подготовьте запрос и проверьте полученный результат.
Выдать количество поставок для детали P2:
Select count (*) from SPJ where номер_детали='P2'
Результат: 4.
Подготовьте запрос и проверьте полученный результат.
Выдать общее количество поставляемых деталей 'P2':
Select sum (количество) from SPJ where номер_детали='P2'
Результат: 1000.
Подготовьте запрос и проверьте полученный результат.
Выдать средний, минимальный и максимальный объем поставок для
поставщика S1 с соответствующим заголовком:
Select avg(количество) average,
29
min(количество) minimum,
max(количество) maximum
from SPJ where номер_поставщика='S1'
Резул
average
ьтат:
minimu
m
216.6
ma
ximum
100
400
Подготовьте запрос и проверьте полученный результат.
2. Временные функции.
day - день месяца;
current - текущая дата;
month - значение месяца.
3. Другие функции.
length - размер в байтах символьной строки (поля таблицы);
hex - 16-й код выражения;
round - округленное значение выражения;
trunc - обрезание значения выражения.
III. Запросы, использующие соединения
1. Простое эквисоединение.
Пример
Выдать все комбинации информации о поставщиках и деталях,
расположенных в одном городе:
Select S.*,P.* from S, P where S.город=P.город
Результат:
н_пост фам-я рейтинг S.город н_дет назв
цвет
вес P.город
S1
Смит
20
Лондон P1
Гайка красный 12 Лондон
S1
Смит
20
Лондон P4
Винт красный 14 Лондон
S1
Смит
20
Лондон P6
Блюм красный 19 Лондон
S2
Джонс 10
Париж P2
Болт зеленый 17 Париж
...
...
...
...
...
...
...
... ...
2. Эквисоединение с дополнительным условием.
Пример
Выдать все комбинации информации о поставщиках и деталях,
расположенных в одном городе, опустив поставщиков с рейтингом = 20:
Select S.номер_поставщика, p.номер_детали, рейтинг
from S, P
where S.город=P.город and S.рейтинг<>20
Результат:
Hомеp_поставщика
Номер_детали Рейтинг
S2
P2
10
30
S2
S3
S3
P5
P2
P5
10
30
30
3. Соединение таблицы с ней самой.
Пример
Выдать все пары поставщиков из одного города:
Select one.номер_поставщика, two.номер_поставщика
from S one, S two
where one.город = two.город and
one.номер_поставщика < two.номер_поставщика
Результат
Hомеp_поставщика
Номер_поставщика
S1
S4
S2
S3
:
Подготовьте запрос и проверьте полученный результат.
4. Соединение трех таблиц.
Пример
Выдать все пары названий городов таких, в которых поставщик,
находящийся в первом из этих городов, поставляет деталь, хранимую в
другом городе:
Select distinct S.город, P.город
from S, SP, P
where S.номер_поставщика = SPJ.номер_поставщика
and
SPJ.номер_детали = SPJ.номер_детали
Результат
S.город
P.город
Лондон
Лондон
Лондон
Париж
Лондон
Рим
Париж
Лондон
Париж
Париж
:
31
IV. Группирование
1. Оператор group by.
Оператор group by группирует таблицу, представленную фразой from, в
группы таким образом, чтобы в каждой группе все строки имели одно и то
же значение поля, указанного во фразе group by. Далее, к каждой группе
перекомпанованной таблицы (а не к каждой строке исходной таблицы)
применяется фраза select, в результате чего каждое выражение во фразе select
принимает единственное значение для группы.
Пример
Выдать для каждой поставляемой детали ее номер и общий объем
поставок, за исключением поставок поставщика S1:
Select номер_детали, sum( количество)
from SPJ
where номер_поставщика
group by номер_детали
Результа
т:
Hомеp_поставщи
ка
(Su
m)
P1
300
P2
800
P4
300
P5
400
2. Оператор having.
Оператор having играет ту же роль для групп, что и фраза where для
строк, и используется для того, чтобы исключать группы, точно так же, как
where используется для исключения строк. Выражение во фразе having
должно принимать единственное значение для группы.
Пример
Выдать номера деталей, поставляемых более чем одним поставщиком:
Select номер_детали
from SPJ
group by номер_детали
having count(*) > 1
Результа
т:
Номер_дета
ли
P1
P2
32
P4
P5
V. Построение внешнего соединения
В простом соединении результат содержит только комбинации строк из
тех таблиц, которые удовлетворяют условиям соединения. Строки, которые
не удовлетворяют условиям соединения, отбрасываются. Во внешнем
соединении результат содержит комбинации строк из тех таблиц, которые
удовлетворяют условиям соединения, а также строки, которые были бы
отброшены при простом соединении этих таблиц, даже если в подчиненной
таблице не найдена ни одна соответствующая строка. Строки главной
таблицы, для которых не найдено в подчиненной таблице ни одной
соответствующей строки, получают значения, состоящие из одних Nullзначений для каждого столбца.
Существует четыре основных типа внешних соединений:
простое внешнее соединение;
простое внешнее соединение с третьей таблицей;
внешнее соединение простого соединения с третьей таблицей;
внешнее соединение внешнего соединения с третьей таблицей.
1. Простое соединение.
Пример
Select S.номер_поставщика, S.фамилия, SPJ.количество
from S, SPJ
where S.номер_поставщика=SPJ.номер_поставщика
Резул
Hомеp_поставщика
Фамилия
Количество
S1
Смит
300
S1
Смит
200
S1
Смит
400
S1
Смит
200
S1
Смит
100
S1
Смит
100
S2
Джонс
300
S2
Джонс
400
ьтат:
33
S3
Блейк
200
S4
Кларк
200
S4
Кларк
300
S4
Кларк
400
2. Простое внешнее соединение двух таблиц.
Пример
Select S.номер_поставщика, S.фамилия, SPJ.количество
from S, outer SPJ
where S.номер_поставщика=SPJ.номер_поставщика
Добавление ключевого слова outer перед именем таблицы SP
превращает ее в подчиненную таблицу. Результатом этого внешнего
соединения будет получение сведений обо всех поставщиках, независимо от
того, делали ли они поставки.
34
Результат:
Hомеp_поставщика
Фамилия
Количество
S1
Смит
300
S1
Смит
200
S1
Смит
400
S1
Смит
200
S1
Смит
100
S1
Смит
100
S2
Джонс
300
S2
Джонс
400
S3
Блейк
200
S4
Кларк
200
S4
Кларк
300
S4
Кларк
400
S5
Адамс
3. Внешнее соединение простого соединения с третьей таблицей.
Пример
select S.номер_поставщика, S.фамилия, SPJ.номер_детали,
P.название, P.цвет, P.вес
from S, outer(SPJ, P)
where S.номер_поставщика = P.номер_поставщика
and
SP.номер_детали =SPJ.номер_детали
and
цвет in ("Красный", "Зеленый")
Оператор select выполняет сначала простое соединение таблиц SP и P, а
затем этот оператор выполняет внешнее соединение как комбинирование
этой информации с данными из главной таблицы S.
Результат:
Hомеp_пост Фамилия Номер_дет Название Цвет
Вес
S1
Смит
P1
Гайка
Красный 12
S1
Смит
P2
Болт
Зеленый 17
S1
Смит
P4
Винт
Красный 14
S1
Смит
P6
Блюм
Красный 19
S2
Джонс
P1
Гайка
Красный 12
S2
Джонс
P2
Болт
Зеленый 17
S3
Блейк
P2
Болт
Зеленый 17
S4
Кларк
P2
Болт
Зеленый 17
S4
Кларк
P4
Винт
Красный 14
S5
Адамс
4. Внешнее соединение внешнего соединения с третьей таблицей.
Пример
35
select S.номер_поставщика, S.фамилия, SP.номер_детали,
P.название, P.цвет, P.вес
from S, outer(SP, outer P)
where S.номер_поставщика = SP.номер_поставщика
and
SP.номер_детали = P.номер_детали
and
цвет in ("Красный", "Зеленый")
Оператор select сначала выполняет внешнее соединение таблиц SP и P,
затем - внешнее соединение как комбинирование этой информации с
данными из главной таблицы S.
Результат:
Hомеp_пост Фамилия Номер_дет Название Цвет
Вес
S1
Смит
P1
Гайка
Красный 12
S1
Смит
P2
Болт
Зеленый 17
S1
Смит
P3
NULL
NULL
NULL
S1
Смит
P4
Винт
Красный 14
S1
Смит
P5
NULL
NULL
NULL
S1
Смит
P6
Блюм
Красный 19
S2
Джонс
P1
Гайка
Красный 12
S2
Джонс
P2
Болт
Зеленый 17
S3
Блейк
P2
Болт
Зеленый 17
S4
Кларк
P2
Болт
Зеленый 17
S4
Кларк
P4
Винт
Красный 14
S4
Кларк
P5
NULL
NULL
NULL
S5
Адамс
NULL
NULL
NULL
NULL
5. Внешнее соединение двух таблиц с третьей.
Пример
Select S.номер_поставщика, S.фамилия, s.город,
SP.количество, P.название, P.город
from S, outer SP, outer P
where S.номер_поставщика = SP.номер_поставщика
and
S.город = S.город
При выполнении четвертого типа внешнего соединения связи по
соединению допускаются только между главной таблицей и подчиненной.
Результат:
Hомеp_пост Фамилия Город_пост Кол-во
Название Город_дет
S1
Смит
Лондон
300
Гайка
Лондон
S1
Смит
Лондон
300
Винт
Лондон
S1
Смит
Лондон
300
Блюм
Лондон
...
...
...
...
...
...
36
S2
S2
S2
...
S4
S4
S4
S5
Джонс
Париж
300
Болт
Джонс
Париж
300
Кулачок
Джонс
Париж
400
Болт
...
...
...
...
Кларк
Лондон
400
Гайка
Кларк
Лондон
400
Винт
Кларк
Лондон
400
Блюм
Адамс
Всего выборка содержит 34 строки.
Подготовьте запрос и проверьте полученный результат.
Париж
Париж
Париж
...
Лондон
Лондон
Лондон
VI. Операторы манипулирования данными. Удаление данных
Общая форма оператора удаления:
delete from таблица [where предикат]
1. Удаление единственной записи.
Пример
Удалить сведения о поставщике S1:
delete from S where номер_поставщика='S1'
Результат: таблица S с отсутствующей строкой о поставщике S1.
Подготовьте запрос и проверьте полученный результат.
2. Удаление множества записей.
Пример
Удалить сведения обо всех поставщиках из Лондона:
delete from S
where город='Лондон'
Результат: таблица S с отсутствующими строками о поставщиках из
Лондона.
Подготовьте запрос и проверьте полученный результат.
3. Удаление всех строк таблицы.
Пример
delete from S
Подготовьте запрос и проверьте полученный результат.
VII. Операторы манипулирования данными. Вставка данных
Общая форма оператора вставки:
Insert into таблица [(поле [,поле]...)]
values ( константа [,константа]...)
1. Вставка единственной записи.
Пример
Вставить новую поставку с номером поставщика S2, номером детали
P4 и количеством 1000 на дату "30 ноября 1995 г.":
Insert into SPJ values ('S2', 'P4', '1995-11-30', 1000)
37
Результат: таблица SPJ с добавленной строкой о поставке поставщиком
S2 детали P4.
Подготовьте запрос и проверьте полученный результат.
2. Вставка множества записей.
Пример
Восстановить таблицу S:
Insert into S values ('S1', 'Смит', 20, 'Лондон');
Insert into S values ('S2', 'Джонс', 10, 'Париж');
Insert into S values ('S3', 'Блейк', 30, 'Париж');
Insert into S values ('S4', 'Кларк', 20, 'Лондон');
Insert into S values ('S5', 'Адамс', 30, 'Афины')
Результат: восстановленная таблица S.
3. Перечисление имен столбцов.
Допускается не задавать значения для каждого столбца, а перечислить
имена столбцов после имени таблицы, а потом предоставить значения только
для тех столбцов, имена которых указаны.
Пример
Вставить строку о новом поставщике, занеся лишь номер поставщика,
фамилию и город:
Insert into S(номер_поставщика, фамилия, город)
values ('S6', 'Боб', 'Нью-Йорк')
Результат: добавленная строка в таблице S.
4. Вставка множества записей как результата подзапроса.
Пример
Для каждой поставляемой детали получить ее номер и общий объем
поставки, сохранить результат в базе данных:
Create table temp
(номер_детали char(6),
объем поставки smallint);
Insert into temp (номер_детали,обьем_поставки)
Select номер_детали, sum(количество)
from SPJ
group by номер_детали
Результат: Сформированная таблица temp, данные в которую занесены
как результат указанного оператора.
VIII. Операторы манипулирования данными. Обновление
данных
Общая форма оператора обновления:
Update таблица
set поле=выражение [,поле=выражение]...[where предикат]
1. Обновление единственной записи.
38
Пример
Изменить цвет детали P2 на желтый, увеличить ее вес на 5 и
установить значение города "неопределен":
Update P set цвет='желтый',
вес=вес+5,
город=NULL
where номер_детали='P2'
Результат: Таблица S c внесенными изменениями.
Подготовьте запрос и проверьте полученный результат.
2. Обновление множества записей.
Пример
Удвоить рейтинг всех поставщиков в Лондоне:
Update S set рейтинг=2*рейтинг
where город='Лондон'
Результат: Таблица S с увеличенным рейтингом для поставщиков из
Лондона.
Подготовьте запрос и проверьте полученный результат.
39
Методические указания по изучению языка PERL
PERL (Practical Extraction and Report Language — практический язык
извлечений и отчетов), применяется также для обработки потоков
информации. Изначально предполагалось, что он будет использоваться в ОС
Unix, но в дальнейшем Perl стали переносить на другие платформы, и сейчас
он существует в самых разных версиях — для Unix, Windows, MS-DOS, OS/2,
MacOS, Amiga, Atari ST, VMS, Plan 9 и др.
Его синтаксис унаследован в первую очередь от С, в него добавлены
расширенные средства для работы со строками, регулярными
выражениями, ассоциативными массивами и т. д. Это интерпретируемый
язык, изначально созданный
для
Unix-систем,
сейчас
его
интерпретаторы доступны для большинства популярных архитектур, что
делает особенно легким перенос приложений. Было бы неверно говорить о
Perl, как исключительно о средстве разработки CGI. Встроенные в язык
возможности,
великолепная
переносимость,
огромное
количество
существующих библиотек делают его исключительно удобным средством
для системного администрирования, сетевого программирования, обработки
текстов и т.п.
Perl-программа (скрипт) состоит из последовательности деклараций и
предложений. Единственно, что должно быть обязательно декларировано, это форматы отчетов и подпрограммы (функции). Все необъявленные
переменные, массивы, имеют значение 0, или null. Perl имеет свободный
формат, комментарии начинаются с символа '#' и продолжаются до конца
строки. Декларации могут использоваться в любом месте программы, так же
как и предложения (statements), но действуют они только в фазе компиляции
программы. Обычно их помещают или в начале, или в конце программы.
Декларация подпрограмм позволяет использовать имя подпрограммы как
списковый оператор, начиная с момента декларирования.
Например, следующая команда отладчика использует функцию print
для того, чтобы вывести на экран сообщение Hello World:
DB<1> print "Hello World\n"; <ENTER>
Hello World
DB<2>
Используя отладчик с помощью команды р, можно вывести на экран
любое выражение. Для упрощения набора в отладчике можно опускать точку
с запятой в конце выражения, поскольку отладчик добавит ее для вас.
Наконец, отладчик всегда переходит на новую строку для новой команды.
Следующий код иллюстрирует использование команды р - <ENTER>:
DB<2> р "Hello World\n" <ENTER>
40
Hello World
DB<3>
Или, например:
DB<4>Print (test . 1)
#выведет test1
DB<5>Print (‘test’ . 1)
#выведет test1
DB<6>
Как можно видеть, всякий раз, когда Вы набираете команду отладчика,
счетчик отладчика увеличивается на единицу, что находит отражение в его
строке DB. Читая дальше эту главу, Вам, вероятно, стоит запустить отладчик,
чтобы иметь возможность набирать в нем примеры и работать с языком Perl
интерактивно.
Примечание: Для того чтобы ввести выражение из многих строк в
отладчик (debugger), необходимо использовать символ продолжения <\> в
конце каждой строки, иначе отладчик сообщит о синтаксической ошибке.
Следующая
команда
иллюстрирует
использование
символа
продолжения при работе с отладчиком:
DB<6> for ($i = 0; $i < 10; $i++) { \ <ENTER>
cont: print $i; \ <ENTER>
cont: } <ENTER>
0123456789
DB<7>
В этом случае для вывода чисел от 0 до 9 использовался цикл for.
Для проверки работоспособности Perl в среде web создайте в
директории d:\usr\cgi-bin файл test.pl с таким содержанием:
#!/usr/local/perl/bin/perl
print "Content-type: text/plain\n\n";
print 5+5;
Обратите внимание на первую строчку в скрипте. В нашем случае она
указывает Apache, что Perl расположен в d:\usr\local\perl\bin\perl.exe. Вы
указывайте свой путь.
Тип данных в PERL
Типы данных используются в программах при объявлении
переменных. Тип данных определяет то множество значений, которые может
принимать переменная, а также набор операций, которые программа может
выполнять с ней. В языке Perl данные могут быть числом или строкой
символов. Одно значение называется скалярной величиной, или просто
скаляром. Ниже приведены примеры скалярных значений, которые
используются в языке Perl:
41
Десятичные: 127, или 127.0, или 1.27Е2;
Шестнадцатеричные: Ox7F, или 0x7f ;
Восьмеричные: 0177 (первый знак указывает, что используется
восьмеричное число).
Строка: "Hello World\n", или 'Hello World'.
Например, следующая команда использует отладчик Perl для
того,чтобы вывести число 0177 восьмеричной системы, соответствующее
числу 127 десятичной:
DB<4> р 0177 <ENTER>
127
Perl переводит данные в свой внутренний формат. Когда Perl печатает
восьмеричные или шестнадцатеричные значения, он сначала переводит их в
десятичный формат, как было показано.
Примечание: Как Вы узнаете, скрипт Perl позволяет использовать
функцию printf для того, чтобы выводить значения в вызываемом формате, в
таком как восьмеричный или шестнадцатеричный.
В качестве внутреннего представления всех чисел используется формат
с плавающей запятой двойной точности (double). Иными словами, среди
внутренних форматов нет целочисленного. Тем не менее, в большинстве
случаев Вы можете не обращать на это внимания, и Perl сделает все сам как
надо. Например, если Вы используете величины в контексте, где только
целочисленные значения имеют смысл, Perl сам автоматически усечет число.
Примечание: Если Вы пишите программу на С и используете
целочисленное деление с усечением целых чисел автоматически, то,
программируя на языке Perl, надо не забыть выполнить усечение вручную,
используя функцию int().
Следующая команда иллюстрирует, как Perl обрабатывает числа целого
типа и с плавающей запятой:
print 6 & 3; # выведет 2
print 6.9 & 3.1 #
print 7 / 2 # выведет 2.3333 не целое
print int(7/3) # выведет 2
Точно так же, как Perl преобразует числа с плавающей запятой в
целые числа: когда скрипт использует целочисленные значения, он
преобразует числа в строки и наоборот, когда такое преобразование имеет
смысл. Например, если скрипт использует числа в контексте, где только
строки имеют смысл, например, при соединении строк, он конвертирует
числа в строки. Аналогичным образом, если требуется использовать строки
там, где только числа имеют смысл, то Perl конвертирует их в числа. Работая
со скриптами Perl, обычно не надо беспокоиться о внутреннем представлении
скалярных величин. Perl поддерживает также концепцию булевых значений,
но не имеет для их описания специального типа. Как и в С, численное
42
значение рассматривается истинным, если оно не равно нулю.
Дополнительно строковое значение рассматривается как истинное, если оно
не равно '' или '0'. Некоторые булевы операторы, такие как <>> (больше),
возвращают единицу в качестве значения <истинно> и нуль - в качестве
<ложно>. Тем самым, ваш скрипт должен просто рассматривать ненулевые
величины как строчного типа, так и числового в качестве булева значения
<истинно>. Скрипты Perl могут группировать скалярные величины вместе и
создавать список (list). Если скрипт хранит список в какой-то переменной, то
эта переменная становится массивом (array).
Переменные
Скалярные переменные
Как отмечалось, скалярная переменная может содержать единственное
значение. В языке Perl имена скалярных переменных всегда начинаются со
знака ($). В еле дующем выражении скалярной переменной $age
присваивается значение 35, а переменной $name строковое значение <Bob>.
Затем используется функция print для вывода значения каждой из
переменных:
$age = 35;
$name = 'Bob';
print ($name,'is',$age);
Если Вы сохраните эти выражения в файле под именем SCALAR.PL, то
сможете запустить программу следующим образом:
C:\PERL> Perl SCALAR.PL <ENTER>
Результат:
Bob is 35
Массивы
Как было сказано выше, массиВы представляют собой переменные,
принимающие в качестве значения список из скалярных величин.
Следующий текст программы на языке Perl иллюстрирует объявление
переменных типа массив и их инициализацию:
@days = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
print(@days);
# выведет 'SunMonTueWedThuFriSat'
print($days[4]);
# выведет 'Thu'
@weekdays=@days[1..5];
значение ('Mon','Tue','Wed','Thu','Fri')
@emptylist = ();
#
пустой список
Ссылка на переменные типа <массив> обычно начинается со знака @ и
сопровождается значениями в квадратных скобках ([ ]). Как и в
программировании на языке С, индексами массивов для скриптов всегда
являются переменные целого типа, которые обычно начинаются с нулевого
значения. Третье выражение ($days[4]) служит примером массива, который
ссылается на скалярное значение. Поскольку он содержит только один
43
элемент, результирующее значение представляет собой скаляр. Если
использовать знак $ вместо знака @, то скрипт будет ссылаться на скалярную
величину. Это замечание является очень важным. Квадратные скобки
указывают, что скрипт ссылается на массив. Знак $, в свою очередь, означает
ссылку на скалярную величину.
Инициализация массива @weekdays осуществляется путем выборки
части массива @days. В предыдущем примере массив @days использовался
без индекса. Когда индекс опущен, Perl ссылается на весь массив.
Аналогичным образом в предыдущем примере массив @days
инициализировался списком литералов. Кроме того, что массиву могут
присваиваться в качестве значений литералы, скрипт может также
присваивать массивам значения переменных или даже других массивов, как
показано ниже:
@stuff = ($age, $name)
@FriendsOfMine = ('Joe','Mary', @FriendsOfYours);
В следующем примере используются части массивов:
@weekend = @days[0,6] ;
# результат
('Sun','Sat')
print (@days[1..5,0,6]); # выведет 'MonTueWedThuFriSunSat'
Если скрипт использует переменную типа массив в контексте скаляра,
то значением служит число элементов массива. Скалярным контекстом
является такой контекст, где только скалярные значения имеют смысл.
Например, следующее выражение использует скалярный контекст для
массива stuff для того, чтобы определить число элементов, содержащееся в
массиве. Если число элементов больше (или равно) двум, то скрипт выдает
сообщение и заканчивает исполнение:
(@stuff >= 2) || die "Too much stuff! \n";
Функция die служит директивой языку Perl закончить выполнение и
выдать при этом указанное сообщение. Если сообщение не содержится, то
функция просто заканчивает выполнение скрипта. Perl также поддерживает
специальную конструкцию $#-переменная, которая возвращает последнее
значение индекса в массиве. Например, выражение for использует
переменную $[ для того, чтобы определить начальное значение индекса
массива, и $# для определения последнего из элементов массива. При этом с
помощью выражения for выводятся значения каждого из элементов:
for ($i =$[; $i <= $#stuff; $i++)
{
print $stuff[$i];
}
Записанный цикл for можно заменить следующим эквивалентным
выражением:
Print @stuff;
44
Хэши
Хэш это такой массив, который состоит из пар ключ-значение, весь
хеш обозначается %имя, к отдельным элементам доступ $хеш {скалярное
выражение} конструируется хеш так:
$my_hash{1}="doom";
$my_hash{'quake'}="www.idsoftware.com";
$my_hash{1+2}=100;
Хеш может быть также сконструирован из массива с четным числом
элементов где пары превращаются в ключ-значение
%hash=(1,20,2,100);#аналогично $hash{1}=20;$hash{2}=100;
удаление из хеша осуществляется операцией delete:
delete $hash{1};
есть функции выдающие ключи и значения соответственно.
%hash=(1,20,2,100,3,'doom').
Условия
Последовательность
простых
предложений,
ограниченная
функциональными ограничителями, называется блоком. В Perl это может
быть целый файл, последовательность предложений в операторе eval{} или
чаще всего это множество простых предложений, ограниченных круглыми
скобками {}.
Существуют следующие виды сложных предложений:
if (EXPR) BLOCK
if (EXPR) BLOCK else BLOCK
if (EXPR) BLOCK elsif (EXPR) BLOCK ... else BLOCK
LABEL
LABEL
LABEL
LABEL
LABEL
while (EXPR) BLOCK
while (EXPR) BLOCK continue BLOCK
for (EXPR; EXPR; EXPR) BLOCK
foreach VAR (LIST) BLOCK
BLOCK continue BLOCK
Обратите внимание, что сложные предложения описаны в термах
блоков, а не предложений, как в языках C или Pascal. Поэтому необходимо
всегда использовать круглые скобки для обозначения блока.
if (EXPR) BLOCK - Вычисляется логическое выражение EXPR и если
true блок выполняется.
Пример 1:
$var =1;
if ($var == 1)
{ print $var,"\n";
}
Результат: 1.
45
if (EXPR) BLOCK else BLOCK2 BLOCK иначе - BLOCK2.
Пример 2:
Если EXPR=true, выполняется
$var =2;
if ($var == 1)
{ print "\$var = 1\n";
}
else
{ print "\$var не равно 1\n";
}
Результат: $var не равно 1.
if (EXPR1) BLOCK1 elsif (EXPR2) BLOCK2 ... else BLOCK
Если EXPR1=true, выполняется BLOCK1, иначе, если EXPR2=true,
выполняется BLOCK2, иначе .., иначе BLOCK.
Пример 3:
$var = 1;
if ($var == 0)
{ print "\$var = 0\n";
}
elsif ($var == 1)
{ print "\$var = 1\n";
}
else
{ print "Не известное \$var\n";
}
Результат: $var = 1.
Цикл while выполняет BLOCK до тех пор, пока EXPR = true. Метка
LABEL не обязательна и состоит из идентификатора, завершающегося
символом ':'. Метка необходима при использовании внутри блока цикла
управляющих операторов next, last и redo. Если метка все же отсутствует, то
эти операторы ссылаются к началу ближайшего цикла. Блок после continue
выполняется всегда перед тем как вычисляется логическое выражение EXPR.
Это подобно EXPR3 в предложении for, поэтому в этом блоке удобно
изменять счетчики и флаги цикла, даже если применяется оператор next.
Операторы управления циклом
next - подобен continue в С. Переходит к началу текущего цикла, т.е.
повторяет итерацию.
Пример 4:
M1:
46
while ($i < 6)
{
++$i;
#
next M1 if
++$i;
#
}
continue
{
print "$i "; #
}
Увеличиваем счетчик на 1
$i < 3; # Переходим в начало если $i < 3
иначе увеличиваем счетчик еще раз на 1
Печатаем $i
Результат: 1 2 4 6.
last - подобен оператору break в языке С. Немедленно прерывает
цикл. Блок continue пропускается.
Пример 5:
M1:
while ($i < 6)
{
++$i;
# Увеличиваем счетчик на 1
last M1 if $i > 3; # Выход из цикла если $i > 3
++$i; # иначе увеличиваем счетчик еще раз на 1
}
continue {
print "$i "; # Печатаем $i
}
Результат: 2 4.
redo - начать новый цикл, не вычисляя EXPR и не выполняя continue
блок.
Пример 6:
M1:
while ($i < 6)
{
++$i;
# Увеличиваем счетчик на 1
redo M1 if $i == 3; # Далее пропустить для $i = 3
++$i; # иначе увеличиваем счетчик еще раз на 1
}
continue {
print "$i "; # Печатаем $i
}
Результат: 2 5 7.
Цикл for
LABEL for (EXPR1; EXPR2; EXPR3) BLOCK
47
Оператор for полностью аналогичен оператору for в С. Перед началом
цикла выполняется EXPR1, если EXPR2 = true, выполняется блок, затем
выполняется EXPR3.
Пример 7:
for ($i = 2; $i < 5; ++$i)
{
print $i, " ";
}
print "\nПосле цикла i = $i\n";
Результат:
234
После цикла i = 5.
Цикл foreach.
LABEL foreach VAR (LIST) BLOCK
Переменной VAR присваивается поочередно каждый элемент списка
LIST и выполняется блок. Если VAR опущено, то элементы присваиваются
встроеной переменной $_. Если в теле блока изменять значение VAR, то это
вызовет изменение и элементов списка так как VAR фактически указывает на
текущий элемент списка. Вместо слова foreach можно писать просто for - это
слова синонимы.
Пример 8:
@месяц = ("январь","февраль","март"); # Создали массив
foreach $i (@месяц)
{
print $i," ";
# Печать $i
}
Результат: январь февраль март.
Пример 9:
@месяц = ("январь","февраль","март");#Создали массив
foreach $i (@месяц)
{
$i = uc($i); # Перевели в верхний регистр
}
print @месяц;
Результат: ЯНВАРЬФЕВРАЛЬМАРТ.
Пример 10:
for $i (3,5,7)
{
print "$i ";
}
Результат: 3 5 7.
В следующей таблице рассмотрены базовые операции и синтаксис
языка PERL.
48
Таблица. Базовые операции языка Perl
Операции
Описание
Пример
+-*/%
Арифметические
print
2*7+4/(8%3);
print int(127/15); #целая часть
**
Возведение в степень print 2**16;
++ -Инкремент-декремент $i++;
& | ^ ~ << >>
Побитовые
$x=3;$y=4;
print
$x|$y;
print $x&$y;
== !=(≠) < > <= >= Числовые
операции if($x==9){print "Ok!";}
<=>
сравнения
Eq(=); ne(≠); lt(<);строковые
операции if($game eq 'doom'){print "You
gt(>); le(<=); ge(=>);сравнения
are doomer!\n";}
cmp()
|| (AND); &&(OR); Логические
if(($x==9)||($game
eq
!(NOT)
'doom')){print "hello you!\n";}
?:
Условный оператор
$i = 1;
Этот оператор работает $i > 1 ? print "больше" : print
так же как и в С. Если "меньше";
выражение перед '?'
истинно,
тоРезультат: меньше
выполняется аргумент
перед ':' - иначе после
':'.
,
.
x
Последовательное
вычисление
Конкатенация
Повторение
$x=10,$y=20;
$x='http://'.'www.uic.nnov.ru';
$x='1234'x5;
#$x='12341234123412341234'
с if($url=~/http/){print "HTTP";}
Сопоставление
образцом
!~
То же, но с отрицанием if($url!~/http/){print
"No
HTTP";}
= += -= *= /= %= **= Присваивание
$x+=$y;
|= &= ^= ~= <<= >>=
.= x=
Как видно из представленного описания, в Perl существует большое
количество средств организации циклов и возможно выполнение большого
количества разнообразных операций. Выбирайте конкретные реализации, по
своему вкусу, исходя из предложенной задачи. Далее рассматривается вопрос
взаимосвязи СУБД MySQL и языка программирования.
=~
49
Формирование Perl-скрипта и его вызов из Html-формы
Perl - язык для извлечения и представления данных. Сначала
предполагалось использовать его для обработки документов, но очень скоро
границы его применения значительно расширились: от решения вопросов
администрирования систем до написания cgi-скриптов и создания
интерфейсов к базам данных.
В данном руководстве рассмотрены приемы для реализации клиент
серверного взаимодействия. Подробно описаны этапы создания Perlпрограмм. Приведены примеры работающих приложений.
Этапы создания скрипта
1. Создать форму для вызова скрипта.
2. Создать сам скрипт.
3. Отладить скрипт. Проверить отсутствие ошибок (если это
возможно, лучше проверить все возможные пути выполнения программы).
4. Поместить скрипт на сервер и не забыть дать ему права на
выполнение.
5. Связать скрипт с формой, вставив его имя в параметр action тэга
form.
Например:
<form method=post action="/cgi-bin/scriptname.pl">
6. Убедиться, что скрипт правильно работает вместе с формой.
Основные части Perl скрипта
В общем случае любой Perl-скрипт состоит из четырех ключевых
частей это:
1. Настройка. Первая часть скрипта обязательно запускает
интерпретатор и устанавливает переменные, используемые в теле скрипта.
Для запуска интерпретатора необходимо знать правильный путь к
программе.
2. Чтение входных данных. Эта часть "считывает" и сохраняет в
переменных входные данные в удобной для обработки форме. Эта часть
обычно неизменна во всех скриптах.
3. Обработка входных данных. Эта часть соответствующим образом
обрабатывает введенные данные. Она может быть простой (около пяти строк)
или очень сложной (более тысячи строк), в зависимости от выполняемой
задачи.
4. Вывод результатов. Пользователь обычно ожидает какого-либо
ответа на свои действия. Эта часть достаточно проста в реализации.
50
Пример скрипта с формой
Шаг 1 - Создание формы
Создадим для простоты форму, содержащую всего одно поле и
позволяющую пользователю зарегистрировать его имя. Напишем в редакторе
следующий текст:
<html>
<head>
<title>Test Form</title>
</head>
<body>
<form method=post action"cgi-bin/testform.pl">
<b>Введите Ваше имя: </b>
<input name="user_name" value="" size=20>
<input type="submit" value="Зарегистрировать">
</form>
</body>
</html>
Сохраните файл на диске под именем form.html.
При создании формы могут использоваться следующие атрибуты:
Action - как раз и задает тот URL, который будет и обрабатывать
форму, если он опущен, то текущий URL документа (а он может быть
сгенерирован нашим скриптом).
Method - задает метод GET или POST.
Enctype - обычно не задается для форм, он - application/x-www-formUrlencoded - по умолчанию и поддерживается всеми CGI-скриптами. Но
если Вы уж очень хотите, чтобы браузер послал вам данные в другом
формате (например text/plain), то можете указать этот тип кодировки, только
потом не жалуйтесь, что ваш скрипт не может разделить поля или вообще не
работает, когда пользователь ввел какой-то спецсимвол.
Name - задается для JavaScript, чтобы обращаться к форме по имени, а
не по номеру (для CGI не играет никакой роли, как внутреннее значение для
браузера).
Target - может определять, в какой фрейм отправить полученую
информацию. Имеет значение во фреймосодержащих документах. Прозрачен
для CGI обработки данных.
OnSubmit - определяет JavaScript - обработчик активизации формы.
Применяется для проверки JavaScript'ом правильности заполнения.
51
Форма может содержать элементы. Элементы имеют имена, которые
используются для кодирования пар имя=значение. Некоторые Элементы не
передаются CGI, а используются JavaScript для управления, например
кнопки. Некоторые поля передаются только в тех случаях, когда в них что-то
выбрано, например списки и переключатели. Остальные поля передаются
всегда, даже когда они пустые.
Например:
<FORM action="http://localhost/cgi-bin/test.cgi"
Your Name:<INPUT name="Name"><BR>
E-Mail:<INPUT name="Email"><BR>
Кто ты:<INPUT type="checkbox" name="doomer" value="Yes">
<INPUT type="submit" value="Send Form!">
</FORM>
E-Mail:
Кто ты:
Send Form!
Допустим, Вы ввели имя Alex и адрес alex@acs.ru,при этом выбрали
переключатель. После нажатия кнопки будет отправлен вот такой запрос:
http://www.acs/cgi-bin/test.cgi?Name=Alex&Email=alex@acs.ru&doomer=Yes
Если же Вы не выбрали переключатель, то запрос будет таким:
http://www.acs/cgi-bin/test.cgi?Name=Alex&Email=alex@acs.ru
как видите элемент doomer не вошел в строку запроса.
Если оставить поля редактирования пустыми:
http://www.doom/cgi-bin/test.cgi?Name=&Email=
Эти элементы (Name и Email) присутствуют и сообщают, что они пустые.
Шаг 2 - Создание скрипта
Предложенный ниже скрипт принимает введенные данные, сохраняет
их в файле и показывает сообщение, содержащее ссылку на файл с
сохраненным именем. Наберите в редакторе текст программы и сохраните в
файле testform.pl в каталоге cgi-bin вашего web-сервера. Убедитесь, что
первая строка программы содержит правильный путь к программеинтерпретатору. Убедитесь также, что путь к выходному файлу является
корректным путем к области хранения документов web-сервера. В
заключение исправьте URL на адрес вашего сервера.
#!/usr/local/perl/bin/perl# <-- ПРОВЕРЬТЕ ЭТО
# Чтение введенных в форме данных (данный пример рассматривает
#случай, когда была осуществлена передача одного поля формы.)
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
52
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value
=~
s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",
hex($1))/eg;
$value =~ s/<!--(.|\n)*-->//g;
$input{$name} = $value;
}
# Сохранение введенного имени в файл
$targetfile = "/usr/local/www/names.html"; # <-- ПРОВЕРЬТЕ
ЭТО
#Открывается указанный файл для записи
open (NAMEFILE, ">>$targetfile");
#Вводятся принятые данные
print NAMEFILE "<h3>Имя: ",$input{'user_name'},"</h3>\n";
#Ввод HTML тэга
print NAMEFILE "<p><hr><p>\n";
#Закрытие файла
close (NAMEFILE);
#Вывод тела формы
print "Content-Type: text/html\n\n";
#Вывод ссылки на файл с сохраненными данными
print "<h3>Спасибо, что заполнили форму</h3>\nНажмите ";
print '<a href="http://localhost/names.html">сюда</a>';
print ", чтобы увидеть введенные данные.\n";
Шаг 3 - Тестирование скрипта
Проверив скрипт визуально на наличие - отсутствие ошибок ";" в
конце строк, наличие непарных скобок и кавычек и т.п., запустите скрипт для
проверки прямо из командной строки, перейдя предварительно в каталог cgibin. Вот некоторые примеры того, как это делается:
d:\usr\local\perl\perl.exe testform.pl
Если в скрипте содержатся ошибки, то Вы увидите сообщение типа
syntax error at testform.pl line 18, near "open"
Execution of testform.pl aborted due to compilation errors.
В этом случае проверьте текст около указанной строки. Помните, что
причина ошибки может быть выше на несколько, иногда достаточно много
строк. Исправленный скрипт сохраните и тестируйте так до тех пор, пока он
не выдаст корректных выходных данных.
Шаг 4 - Тестирование скрипта с формой
Если скрипт работает сам по себе, Вы можете оттестировать его с
формой:
1. Убедитесь, что web-сервер запущен.
2. Запустите ваш браузер.
53
3. Наберите URL по которому находится ваша форма (обратите
внимание, что строка должна начинаться с http://, а не с file://. В нашем
случае http://localhost/form.html
4. Введите ваше имя в поле формы и нажмите кнопку
"Зарегистрировать".
5. Вы должны увидеть сообщение вроде этого:
Это и есть страница, сгенерированная скриптом "на лету". Если Вы
получили сообщение об ошибке сервера, проверьте правильность
расположения скрипта и правильность значения параметра action в тэге form.
6. Если Вы видите правильно сгенерированную страницу, нажмите на
ссылку. Вы должны будете увидеть новую страницу, созданную скриптом
примерно в таком виде:
Если Вы не видите этого, проверьте правильность пути в переменной
$targetfile и правильность URL в предпоследней строке скрипта. В противном
случае форма и скрипт правильно работают вместе. Вы успешно создали
первое web-приложение.
54
Для изучения различных переменных создайте скрипт следующего
содержания:
#!/usr/local/perl/bin/perl
#vars.cgi
sub urldecode{
#очень полезная функция декодировани
local($val)=@_;
#запроса,будет почти в каждой вашей CGIпрограмме
$val=~s/\+/ /g;
$val=~s/%([0-9A-H]{2})/pack('C',hex($1))/ge;
return $val;
}
print "Content-Type: text/html\n\n";
print "<HTML><HEAD><TITLE>CGI-Variables</TITLE></HEAD>\n";
print "<BODY>\n";
print "Enter here something:<ISINDEX><BR>\n";
print "Your request is:$ENV{'REQUEST_STRING'}<BR>\n";
print
"Decoded
request
is:urldecode($ENV{'REQUEST_STRING'})<BR>\n";
print "<HR>\n";
print "Variables:<BR>\n";
print
"<I><B>REQUEST_METHOD</B></I>=$ENV{'REQUEST_METHOD'}<BR>\n";
print
"<I><B>QUERY_STRING</B></I>=$ENV{'QUERY_STRING'}<BR>\n";
print
"<I><B>CONTENT_LENGTH</B></I>=$ENV{'CONTENT_LENGTH'}<BR>\n";
print
"<I><B>CONTENT_TYPE</B></I>=$ENV{'CONTENT_TYPE'}<BR>\n";
print
"<I><B>GATEWAY_INTERFACE</B></I>=$ENV{'GATEWAY_INTERFACE'}<BR>\n
";
print "<I><B>REMOTE_ADDR</B></I>=$ENV{'REMOTE_ADDR'}<BR>\n";
print "<I><B>REMOTE_HOST</B></I>=$ENV{'REMOTE_HOST'}<BR>\n";
print "<I><B>SCRIPT_NAME</B></I>=$ENV{'SCRIPT_NAME'}<BR>\n";
print
"<I><B>SCRIPT_FILENAME</B></I>=$ENV{'SCRIPT_FILENAME'}<BR>\n";
print "<I><B>SERVER_NAME</B></I>=$ENV{'SERVER_NAME'}<BR>\n";
print "<I><B>SERVER_PORT</B></I>=$ENV{'SERVER_PORT'}<BR>\n";
print
"<I><B>SERVER_PROTOCOL</B></I>=$ENV{'SERVER_PROTOCOL'}<BR>\n";
print
"<I><B>SERVER_SOFTWARE</B></I>=$ENV{'SERVER_SOFTWARE'}<BR>\n";
print "<I><B>HTTP_ACCEPT</B></I>=$ENV{'HTTP_ACCEPT'}<BR>\n";
print
"<I><B>HTTP_USER_AGENT</B></I>=$ENV{'HTTP_USER_AGENT'}<BR>\n";
print "<I><B>HTTP_HOST</B></I>=$ENV{'HTTP_HOST'}<BR>\n";
print "<HR>\n";
print "All enviroment:<BR>\n";
foreach $env_var (keys %ENV){
print "<I>$env_var=$ENV{$env_var}</I><BR>\n";
55
}
print "</BODY></HTML>\n";
Расположите его в директории cgi-bin вашего сервера. Его вызов
осуществляется через explorer:
HTTP://LOCALHOST/CGI-BIN/VAR.CGI
Обеспечение доступа пользователя через HTML- форму к БД
на MySQL
Приложение должно реализовать основные операции по работе с БД:
просмотр, обновление, добавление, изменение, удаление данных.
Для организации взаимодействия наших Perl-программ с СУБД MySQL
необходимо, чтобы в поставку Perl входил модуль DBI. Поскольку модуль в
основном ничего сам не делает, а перекладывает все операции по
взаимодействию с базами данных на соответствующий им драйвер, то
требуется установка библиотеки DBD-Mysql (драйвер к БД MySQL для
модуля DBI). По мнению автора и разработчика модуля, «DBI — это APIинтерфейс для организации доступа к базам данных из Perl-программ.
Спецификация DBI API определяет набор функций, переменных и правил,
используемых для прозрачного интерфейса с базами данных».
Концепция драйверов баз данных весьма удобна, поскольку в своем
Perl-приложении Вы используете стандартные для DBI вызовы, которые
затем переадресуют модули соответствующему драйверу, а тот, в свою
очередь, уже напрямую будет взаимодействовать с БД, не требуя от вас
изучения технических особенностей каждой конкретной СУБД. Таким
образом, существуют драйверы DBD::Sybase, DBD::Oracle, DBD::Informix
и т.д. (рис. 18, 19).
Рис. 18. Архитектура DBI
56
Рис. 19. Поток данных через интерфейс DBI
Для упрощения исходного кода во второй части Perl программы
(чтения входных данных), для передачи большого количества информации из
разных полей зачастую используются уже созданные библиотеки,
существенно упрощающие написание исходного кода. Так, в нашем случае
для предыдущей работы исходный текст был бы заменен на:
#!/usr/local/perl/bin/perl
#Подключение необходимой библиотеки "cgi-lib.pl";
require 'cgi-lib.pl';
&ReadParse(*input);
После выполнения этой подпрограммы с использованием библиотеки
cgi-lib и функции &ReadParse(*input); можно обращаться к введенным
данным, используя обращение следующего вида: $input{'name'}, где name
– имя поля, в котором осуществлялся ввод данных в форме HTML.
Пример:
Использование в скрипте следующей конструкции:
print "<I><B>Имя</B></I>=$input{'name'}<BR>\n";
выведет на экран введенное в HTML-форме в поле 'name' содержимое.
Основным заданием данной работы будет создание HTML-форм для
ввода, просмотра, изменения, добавления данных в БД и разработки CGIпрограмм на Perl в целях обработки этой формы и последующего
размещения документа в базе данных. Напомним, что CGI (Common Gateway
Interface) — протокол, механизм или формальное соглашение между Webсервером и отдельной программой. Сервер кодирует входные данные,
например HTML-формы, а программа CGI декодирует их и генерирует поток
выходных данных. В спецификации протокола ничего не сказано о какомлибо определенном языке программирования. Поэтому программы,
соответствующие этому протоколу, могут быть написаны практически на
любом языке — на C, C++, Visual Basic, Delphi, Tcl, Python или, как в нашем
случае, на Perl. Взаимодействие приложений MySQL и Perl предлагается
осуществлять с помощью вебсервера Apache.
Все программы, написанные на Perl, после отладки должны быть
расположены в директории
/cgi-bin/bd_name_num/ из домашней
57
директории
вебсервера,
а
Html-документы
в
директории
www/bd_name_num, где bd_name_num - имя базы данных и номер
варианта. Это необходимо учитывать при указании пути для вызова своего
исполняемого файла из Html-формы, например, использование конструкции
вида
<form action=/cgi-bin/ bd_name_num/example.pl method=get>,
обеспечит запуск необходимого файла из директории /cgi-bin/
bd_name_num/.
Для того чтобы PERL мог выводить данные в HTML-форме
пользуйтесь конструкцией
# Вывод http-заголовка
print "Content-type: text/html\n\n";
после которой можно выводить любые данные на форму с использованием
тэга print, как в предыдущей работе:
print "<h3>Спасибо, что заполнили форму</h3>\n Нажмите ";
Для выполнения любых операций с БД посредством программ,
написанных на PERL, необходимо произвести подключение с серверу
MYSQL следующей конструкцией в составе программы:
# Подключение к базе
$dbh = DBI->connect("DBI:mysql:database=$database",
$opt_user,$opt_password) ||
die "Can't connect: $DBI::errstr\n";
После подключения к БД можно выполнять любые операции с ней,
которые разрешены учетной записью, с которой было совершено
подключение.
В случае использования в запросах переменных, заданных
пользователем заранее, неизвестные данные помечаются знаком вопроса (?) и
передаются в том же порядке командой execute:
#подготовка запроса
$sth = $dbh->prepare(
insert into table1 (name,tel,adr) values (?,?,?)
) || die "Can't prepare statement: $DBI::errstr";
#выполнение запроса
$sth->execute("$name","$tel","$adr");
Для заполнения ниспадающего списка содержимым БД (например
список должен содержать значения name таблицы J) используйте следующую
конструкцию:
#формирование ниспадающего списка
print "<SELECT name = Jname>\n";
58
#подготовка запроса
$sth = $dbh->prepare("SELECT jnam FROM J");
#выполнение запроса
$sth->execute;
#заполнение списка содержимым
while (@line = $sth->fetchrow_array())
{ print "<OPTION>$line[0]</OPTION>\n";}
$sth->finish;
Для вывода на экран содержимого запроса используйте конструкцию вида
$query = "select * from table_name";
$sth = $dbh->prepare($query);
$sth->execute();
$cols=$sth->{NUM_OF_FIELDS};
#Формирование таблицы и её заголовка
print "<table width=70% align=center cellspacing=0 cellpadding=1
border=1>";
print "<tr valign=middle align=center>";
@fieldname=@{ $sth->{NAME}};
for($i=0;$i<$cols;$i++)
{
print "<td><b>$fieldname[$i]</b></td>\n";
}
print "</tr>";
#Заполнение таблицы содержимым, исходя из запроса
while (my $ref=$sth->fetchrow_arrayref())
{
print "<tr align=center>";
for($i=0;$i<$cols;$i++)
{
print "<td>",$ref->[$i],"</td>";
}
print "<tr>\n";
}
print "</table><hr>";
Для того чтобы организовать возможность выполнения различных
запросов с одной формы, существует несколько механизмов.
Первый состоит в том, что при формировании страницы HTML
можно указать формирование нескольких форм в рамках этой страницы,
например:
<body>
################################################################
<form action=/cgi-bin/simple1.cgi method=get>
<input type=text name=id1 width=70><p>
<input type=text name=id2 width=70><p>
<input
type=submit
value=Отправить><input
type=reset
value="очистить">
</form>
################################################################
59
<form action=/cgi-bin/simple2.cgi method=get>
Обновить: <input type=text name=form2_pole1 width=70><p>
<input
type=submit
value=Отправить><input
type=reset
value="очистить">
</form>
</body>
Таким образом, используя этот код, можно с одной страницы вызывать
две различные управляющие программы, указанные после тэга action
соответствующей формы (simple1.cgi, simple2.cgi).
Второй способ заключается в использовании условия if, например:
if($input{'send'} eq 'Добавить')
{print "<B>Добавление</B><BR>\n";}
else
{print "<B>Удаление</B><BR>\n";}
Также для этой задачи можно использовать различные метки,
указатели, скрытые поля и т.д.
Пример. Подключение к БД MySQL из perl с использованием модуля
DBI.
Файл Main.pl
#!/usr/local/perl/bin/perl.exe
# Подключаем модуль DBI для работы с MySQL(далее БД)
# Модуль можно подключить командами use или require.
use DBI;
# Выносим данные, необходимые для подключения к
#отдельный файл(mysql.pl).
require 'mysql.pl';
# Вывод http-заголовка
print "Content-type: text/html\n\n";
# Подключение к базе
$dbh = DBI->connect("DBI:mysql:database=$database",
$opt_user,$opt_password) ||
die "Can't connect: $DBI::errstr\n";
print "<h3>Список таблиц БД $database</h3>\n ";
$query = "SHOW TABLES";
# подготовка запроса
$sth = $dbh->prepare($query);
# Выполнение запроса
$sth->execute;
while ($line = $sth->fetchrow_arrayref)
{
#Печатается результат запроса
print "$$line[0] <BR>\n"
}
$query = "select * from spj";
MySQL,
в
# подготовка запроса
60
$sth = $dbh->prepare($query);
$sth->execute();
$cols=$sth->{NUM_OF_FIELDS};
#Формирование таблицы результатов и наименования столбцов
print "<table width=70% align=center cellspacing=0 cellpadding=1
border=1>";
print "<tr valign=middle align=center>";
@fieldname=@{ $sth->{NAME}};
for($i=0;$i<$cols;$i++)
{
print "<td><b>$fieldname[$i]</b></td>\n";
}
print "</tr>";
#Заполняется содержимое таблицы
while (my $ref=$sth->fetchrow_arrayref())
{
print "<tr align=center>";
for($i=0;$i<$cols;$i++)
{
print "<td>",$ref->[$i],"</td>";
}
print "<tr>\n";
}
print "</table>";
#Отключение от базы
$rc = $sth->finish;
$rc = $dbh->disconnect;
Формирование ниспадающего списка
print "<SELECT name=column>\n";
# заполняем список таблиц
$sth = $dbh->prepare("show tables");
$sth->execute;
while (@line = $sth->fetchrow_array()) {
print "
<OPTION>$line[0]</OPTION>\n";
}
$sth->finish;
print "</P>\n";
Файл mysql.pl.
В данном файле содержатся данные, необходимые для подключения к
базе данных. Вынесение их в отдельный файл позволяет при смене какихлибо параметров подключения (например, смене пароля или имени базы
данных) сделать изменение только в одном файле:
#!/usr/local/perl/bin/perl
# Имя пользователя БД
61
$opt_user="root";
# Пароль доступа к БД
$opt_password="";
# Имя базы
$database="xxx";
В данном примере выполнено подключение к БД, а также осуществлен
вывод результатов двух различных запросов. Запросы объявляются в
скалярную переменную, все остальные действия аналогичные, что позволяет
использовать данный макет для всех перечисленных манипуляций с БД,
меняя лишь, в зависимости от конечной задачи, вариант SQL запроса к БД.
62
Учебная литература
1. Дейт К. Введение в системы баз данных. – Москва – Киев:
Диалектика, 1998.
2. Хансен Г., Хансен Дж. Базы данных. Разработка и управление. – М.:
“Бином”, 1999.
3. Диго С.М. Проектирование и использование баз данных. – М.:
Финансы и статистика, 1995.
4. Ульман Дж. ОсноВы систем баз данных. – М.: Финансы и статистика,
1983.
5. Джексон Г. Проектирование реляционных баз данных для
использования с микро-ЭВМ. – М.: Мир, 1991.
6. Грабер М. Введение в SQL. – М.: Лори, 1996.
7. Грофф Дж., Вайнберг П. SQL. Полное руководство. – Киев: BHV,
1999.
8. Поль Дюбуа. Применение MySQL и Perl в web-приложениях. –
Москва, С-Петербург, Киев: Вильямс. – 2002.
9. Поль Дюбуа. MySQL. –Москва, С-Петербург, Киев: Вильямс. – 2002.
Дополнительная литература
10. Атре Ш. Структурный подход к организации баз данных. – М.:
Финансы и статистика, 1983.
11. Тиори Т., Фрай Дж. Проектирование структур баз данных: В 2-х кн.
– М.: Мир, 1985.
12. Васкевич Д. Стратегии клиент/сервер. – Киев: Диалектика, 1996.
13. Ахаян Р., Горев А., Макашарипов С. Эффективная работа с СУБД. –
СПб.: Питер, 1997.
14. Дейт К. Руководство по реляционной СУБД DB/2. – М.: Финансы и
статистика, 1988.
63
ПРИЛОЖЕНИЕ А
Курсовой проект состоит из 3-х частей. Задачей выполнения первых
двух является освоение базовых операций реляционной алгебры, а также их
реализация средствами языка SQL. Выполнение третьей работы показывает
освоение студентом средств разработки интерфейсов к созданным БД.
Вариант контрольной работы определяется последней цифрой номера
зачетной книжки студента.
Задание 1
Используя инструмент моделирования Erwin, необходимо разработать
структуру БД согласно варианту индивидуального задания. На ее основе
необходимо получить код на языке SQL для реализации БД в СУБД MySQL
(см. рис. 8). С помощью языка SQL создать запросы к СУБД для создания
БД, предметная область, которой определяется вариантом контрольного
задания. Набор таблиц, ограничения атрибутов и их необходимость
определяются студентом самостоятельно, исходя из задач, которые должна
решать готовая БД. Также должна быть представлена концептуальная модель
БД (см. рис. 7). На диаграмме в квадратных скобках должны быть указаны
физические имена таблиц и столбцов, которые должны использоваться в
операторах. Ограничения на атрибуты указанных сущностей должны быть
выбраны самостоятельно, исходя из семантики данных. Выбор всех
сущностей и связей между ними должен быть обоснован. При определении
связей необходимо обосновывать вид связи, ее мощность, обязательность.
Работа должна быть представлена на бумажном носителе и в виде текстового
файла (созданного в текстовых редакторах, таких как Notepad (Блокнот),
Bred2r, Decoder и др., которые не добавляют к набираемому тексту
управляющих символов). Данный файл должен быть готовым для
интерпретации в СУБД MySQL, и в последующем он будет использоваться
при выполнении лабораторных работ. Файл должен содержать набор
операторов SQL для создания БД.
Варианты контрольных заданий
Информационная система "Библиотека" (типовое задание)
Разработать систему, помогающую обслуживать библиотеку. Система
должна предусматривать режимы ведения системного каталога,
отражающего перечень областей знаний, по которым имеются книги в
библиотеке. Внутри библиотеки области знаний в систематическом каталоге
могут иметь уникальный внутренний номер и полное наименование. Каждая
книга может содержать сведения из нескольких областей знаний. Каждая
книга в библиотеке может присутствовать в нескольких экземплярах. В
библиотеке ведется картотека читателей.
64
На каждого читателя в картотеку заносятся следующие сведения:
 фамилия, имя, отчество;
 домашний адрес;
 телефон (будем считать, что у нас два телефона - рабочий и
домашний);
 дата рождения.
Каждому читателю присваивается уникальный номер читательского
билета.
Каждый читатель может одновременно держать на руках не более 5-ти
книг. Читатель не должен одновременно держать более одного экземпляра
книги одного названия.
Каждая книга, хранящаяся в библиотеке, характеризуется следующими
параметрами:
 уникальным шифром;
 названием;
 фамилией автора (может отсутствовать);
 фамилиями соавторов (могут отсутствовать);
 местом издания (город);
 издательством;
 годом издания;
 количеством страниц;
 количеством экземпляров книги в библиотеке.
Каждая книга в библиотеке может присутствовать в нескольких
экземплярах. Каждый экземпляр имеет следующие характеристики:
 уникальный инвентарный номер;
 шифр книги, который совпадает с уникальным шифром из описания
книг;
 присутствие в библиотеке.
В случае отсутствия данного экземпляра книги должны быть записаны
следующие сведения:
 номер билета читателя, который взял книгу;
 дата выдачи книги;
 дата возврата.
Каждый экземпляр книги может находиться на руках только у одного
читателя.
Предусмотреть следующие ограничения на информацию в системе:
1. Не может быть информации о соавторах, если нет информации об
авторе. Книга может не иметь ни автора, ни соавтора.
2. В библиотеке должны быть записаны читатели не моложе 17 лет.
3. В библиотеке присутствуют книги, изданные начиная с 1960 по
текущий год.
4. Каждый читатель может держать на руках не более 5-ти книг.
65
5. Каждый читатель при регистрации в библиотеке должен дать
телефон для связи (он может быть рабочим или домашним).
6. Каждая область знаний может содержать ссылки на множество книг,
но каждая книга может относиться к различным областям.
Вариант 1. Информационная система “Транспортная компания”.
Вы проектируете информационную систему для транспортной
компании, которая занимается перевозками грузов внутри страны и имеет
контакты с зарубежными компаниями, осуществляющими перевозки за
рубежом. Одной из основных задач, решаемых вашей системой, является
составление расписания движения автотранспорта.
Вариант 2. Информационная система “Поликлиника”.
Вам необходимо построить информационно-справочную систему для
поликлиники. В поликлинике работают участковые врачи и специалисты.
Расписание работы врачей стабильно и задано на неделю. В расписании
указаны часы приема и кабинет. В одном кабинете могут работать разные
врачи, но только в разное время. В поликлинике существуют специальные
процедурные кабинеты, где заранее расписано допустимое расписание
проведения процедур, в эти кабинеты пациенты должны направляться или
записываться самостоятельно. В поликлинике ведется учет предоставленных
услуг, каждый больной имеет право на некоторое число бесплатных услуг,
если он имеет медицинскую страховку. При превышении лимита услуги
могут предоставляться за плату.
Вариант 3. Информационная система “Компьютер”.
Ваша организация занимается сборкой и продажей компьютеров. У Вас
имеются несколько сборочных цехов и несколько филиалов по приему
заказов и продаже готовых изделий. Вы продаете как готовые модели по
образцам, так и компьютеры индивидуальной сборки. Изделия поставляются
заказчику в основном прямо из сборочных цехов. Однако несколько типовых
моделей имеются в каждом филиале по приему заказов. Между филиалами и
цехами установлена телекоммуникационная связь. Ваша информационная
система предназначена для оформления заказов на изготовление
индивидуальных моделей и учет продажи готовых деталей. Вы не имеете
права принимать заказ, не обеспеченный имеющимися деталями на складе (в
цеху). У Вас должен вестись учет произведенных работ; за конкретные
компьютеры отвечают цеха, в которых была произведена сборка и настройка
компьютера. Для постоянных клиентов в Вашей организации предусмотрены
скидки.
66
Вариант 4. Информационная система “Международный автобус”.
Ваша фирма занимается продажей билетов на междугородние
автобусы, которые отходят с разных автовокзалов и имеют различные
маршруты. Ваша фирма имеет несколько филиалов по продаже билетов,
часть из них расположена прямо на автовокзалах, а часть - в других районах
города. Вы продаете билеты не только на текущие рейсы, но и заранее. У Вас
существует возможность возврата билетов.
Вариант 5. Информационная система “Туристическая компания”.
Ваша фирма занимается организацией туристского обслуживания. У
Вас имеется несколько постоянных маршрутов, для которых комплектуются
туристские группы. Заранее известны сроки каждого маршрута. Однако при
наборе группы ниже некоторого количества человек Ваша деятельность
становится нерентабельной. Ваши клиенты после заказа и оплаты маршрута
имеют право от него отказаться, но при этом теряют некоторую страховую
сумму.
Вариант 6. Информационная система “Промтоварный магазин”.
Ваша фирма занимается торговлей промышленными товарами. В
Вашем распоряжении имеется один склад и 5 магазинов. Кроме того,
организовано еще несколько выносных торговых мест на одного человека в
ряде чужих магазинов. Товаровед каждого магазина или торговой точки
может заказывать товары на складе, однако он несет ответственность за
неэффективность заказов (возврат непроданного товара или неэффективное
использование торгового места наказывается). Вам необходимо решать
задачи учета продаж по всем магазинам и торговым местам, осуществлять
анализ эффективности продаж товаров и эффективности работы магазинов и
отдельных сотрудников.
Вариант 7. Информационная система “Рекламная компания”.
Ваша фирма занимается предоставлением рекламных услуг. Вы имеете
несколько договоров с транспортными агентствами, с метро и с
муниципальными органами по установке рекламы на транспорте и на улицах
города. У вашей фирмы заключен ряд договоров на эфирное время на радио
и на телевидении. В фирме работают несколько агентств, расположенных в
разных городах. В каждом городе, кроме стационарного приемного пункта,
работают ряд рекламных агентов, которые имеют права от имени агентства
заключать договоры на предоставление рекламных услуг. В фирме работают
дизайнеры, которые непосредственно формируют внешний вид рекламы.
67
Вариант 8. Информационная система “Типография”.
Ваша фирма занимается издательством. В ее владении имеется
типография и ряд периодических изданий. В периодических изданиях
имеются возможности размещения рекламы. В типографии издаются кроме
книг и журналов малотиражные издания типа буклетов.
Вариант 9. Информационная система “Провайдер интернет”.
Ваша фирма занимается предоставлением провайдерских услуг в
рамках сети Интернет. Она обслуживает клиентов с подключением через
модем как на общий телефонный канал, также и через выделенную линию. В
рамках обслуживания возможно ведение рекламы в Интернет.
Вариант 10. Информационная система “Программные системы”.
Ваша фирма занимается разработкой программных систем. Вы имеете
один офис, но большинство Ваших разработчиков работают дома, сдавая в
определенные сроки свою работу ответственному разработчику - сотруднику
формы. Вам необходимо планировать как разработку, так внедрение и
обслуживание разработанных ранее систем.
Вариант 11. Информационная система "Апгрейд ПК".
Ваша фирма занимается ремонтом и upgrade персональных
компьютеров. У вас есть один стационарный цех и несколько приемных
пунктов. В приемных пунктах работают, кроме приемщиков, дежурные
мастера, которые могут выполнять срочный ремонт. Вы принимаете заказы,
которые выполняются у Вас в фирме стационарно, или можете высылать
ваших мастеров к заказчикам для диагностики и устранения неисправностей
на месте. В распоряжении фирмы имеется 2 микроавтобуса, которые могут
забирать аппаратуру и доставлять заказы не место. Заказчики могут
доставлять и забирать технику самостоятельно. За транспортные услуги
взимается дополнительная плата. В одном из приемных пунктов приемщик
дополнительно может быть одновременно транспортным диспетчером.
Вариант 12. Информационная система Магазин "Топ-Книга".
Ваша фирма занимается поставкой книг. Имеется центральный склад и
несколько торговых точек. Вы имеете дело с несколькими поставщиками. У
Вас можно осуществить заказ книг. Конкретными заказами, в зависимости от
категории книги, занимается конкретный исполнитель из персонала. Вы
обладаете информацией по авторам, издательствам.
68
Вариант 13. Информационная система "Автомастерская".
Ваша фирма занимается ремонтом автомобилей. Вы предоставляете
несколько видов услуг. В Ваши задачи входит контроль поставки запчастей и
ремонтных материалов. А также необходимо учитывать КТУ (коэффициент
трудового участия) каждого работника в каждом заказе для расчета
заработной платы. Постоянным клиентам предоставляется скидка.
Вариант 14. Информационная система "Обеспечение учебного
процесса".
Задано расписание занятий групп, в котором указаны следующие
параметры:
 день недели (занятия в субботу не проводятся);
 номер пары (занятия только для дневных факультетов, ограничить
допустимый номер пары);
 фамилия преподавателя (выбирается из специальной таблицы,
содержащей список преподавателей с указанием их должностей и ученых
степеней);
 название дисциплины (выбирается из таблицы дисциплин на
семестр);
 тип занятий (выбирается из допустимого списка типов занятий:
лекция, лабораторные работы, упражнения, курсовой проект);
 номер группы (выбирается из списка групп, который хранится в
отдельной таблице)/
По каждой дисциплине определено количество лабораторных работ,
которое требуется выполнить в данном семестре, количество домашних
заданий по упражнениям и наличие курсового проекта. В расписании на
одной и той же паре в один и тот же день недели у одной группы не может
быть нескольких различных занятий. В расписание занятий должны быть
внесены все запланированные занятия на данный семестр для всех групп.
Для каждого студента ведется электронный журнал, в котором занесены
данные о сдаче студентом всех лабораторных, домашних заданий и курсовых
проектов. При планировании домашних заданий отводить на каждое задание
две календарные недели.
Вариант 15. Информационная система "Железнодорожная
станция".
Необходимо разработать информационную систему, обслуживающюю
пассажиров и реализующую возможность продажи и получения информации
о тех или иных составах. Система не привязана к конкретной станции, с
любой станции можно купить билет на любой состав, как следующий через
эту станцию, так и не следующий, но внесённый в систему. Система
предусматривает возможность покупки билета на одно и то же место, если
69
пассажир следует с промежуточной станции, а не со станции отправления
состава или до промежуточной станции. Продажа билетов осуществляется от
текущей даты и на 30 дней вперёд, для чего имеется таблица “Даты
отправления составов”. В системе ведётся картотека купленных билетов. По
прохождении времени прибытия состава на станцию назначения билеты,
проданные на этот состав, удаляются из картотеки. Также удаляется и состав
из таблицы “Даты отправления составов”.
На каждый билет в картотеку заносятся следующие сведения:
 ФИО пассажира.
 Номер состава.
 Номер вагона.
 Номер места.
 Дата отправления состава со станции следования.
 Станция следования пассажира – станция посадки.
 Станция назначения пассажира – конечная станция для пассажира.
 Дата отправления пассажира.
 Тип вагона (плацкартный, купейный или сидячий).
 Время отправления пассажира.
 Время следования пассажира.
 Время прибытия пассажира.
 Цена билета.
Каждому билету присваивается уникальный номер, так как на одно
место может быть продано несколько билетов для пассажиров, следующих
через непересекающиеся станции. Как только покупается билет, место,
указанное в билете, вносится в список занятых мест на всём протяжении
станций от станции следования пассажира до станции назначения.
Соответственно с прибытием состава на место назначения удаляются все
занятые места, связанные с этим составом.
Каждое занятое место характеризуется следующими параметрами:
 Номером билета.
 Названием станции.
 Номером состава.
 Номером вагона.
 Номером места.
 Датой отправления состава со станции следования.
Каждому составу соответствует уникальный номер, а также следующие
параметры:
 Промежуточные станции следования состава.
 Конечная станция состава.
 Время отправления состава.
 Время следования состава.
70
 Время прибытия состава.
 Дни недели, по которым отправляются составы.
Для обеспечения целостности системы имеется таблица “Станции”, в
которой перечислены названия всех станций следования составов. Названия
станций являются уникальными. Предусмотрены следующие ограничения на
информацию в системе:
1. В плацкартном вагоне 60 мест. В купейном и сидячем –
соответственно 40 и 100.
2. Время прибытия и отправления пассажира, а также тип вагона в
билете должны строго соответствовать реальному времени и типу вагона
состава, на который продан билет. Цена билета высчитывается как сумма цен
билетов между всеми станциями следования.
3. Через одну станцию может проходить несколько составов, и каждый
состав, естественно, проходит за время следования несколько станций.
4. На одно и то же место может быть куплено несколько билетов, если
станции следования пассажиров, купивших эти билеты, не пересекаются.
5. За один день может отправиться только один состав с одинаковым
номером.
6. Билеты продаются от текущей даты и до 30 дней вперёд.
Вариант 16. Информационная система "Отдел кадров".
Вам необходимо спроектировать информационную систему,
отражающую информацию о сотрудниках вашей компании, такую, как
фамилия, имя, отчество, домашний адрес, телефон, дата рождения,
должность, дата зачисления, стаж работы, образование, ИНН, номер
пенсионного свидетельства. ИС также может содержать следующую
информацию:
 фамилию, имя, отчество и даты рождения членов семьи каждого
сотрудника, оклад;
 наименование подразделения, количество штатных единиц, фонд
заработной платы за месяц и за год.
Вариант 17. Информационная система "Сервисный центр".
Ваша фирма занимается гарантийным и платным ремонтом бытовой
техники. Ведется база по оказанным услугам – дата обращения, вид техники,
серийный номер, время нахождении техники в ремонте, стоимость (в случае
платного ремонта), контактные данные клиента, мастер, обслуживающий
заказ. С помощью разработанной БД необходимо также рассчитывать
премию работникам от суммы выполненных заказов.
71
Вариант 18. Информационная система "АФИША".
Информационная система содержит сведения о репертуаре различных
театров, месте и времени проведения; названия спектаклей, имена актеров.
Необходимо предусмотреть возможность предварительного заказа билетов.
Вариант 19. Информационная система "Меломан".
Необходимо разработать БД, которая автоматизировала бы процесс
поиска компакт-дисков, кассет в музыкальной коллекции. Главная задача БД
"Меломан" - отслеживание компакт-дисков, кассет и предоставление
пользователю возможности нахождения дисков по исполнителю, названию
песни, а также ввод и удаление старых записей. Пользователь может найти
интересующую его информацию, вводя имя исполнителя, название песни или
альбом.
Вариант 20. Информационная система "Интернет магазин".
Информационная система предполагает организацию виртуальных
витрин различных категорий товаров, просмотр их различных характеристик,
формирование корзины покупателя, организацию доставки выбранных
товаров, автоматическое формирование счета на основании содержимого
корзины покупателя, также возможность оплаты товаров web-money. После
выбора необходимых товаров покупатель может отказаться от некоторых из
них или отложить покупку.
Вариант 21. Информационная система "Оптовая база".
Необходимо разработать ИС, с помощью которой повысилась бы
эффективность работы оптовой базы. Целью работы компании является
быстрая реализация товаров, поставляемых различными поставщиками и/или
производителями (подразумевается продажа товара крупными партиями и по
оптовым ценам, которые увеличивают товарооборот и, как следствие,
прибыль компании). Данная компания специализируется на продаже
продовольственных товаров, а также оказывает услуги по сопровождению и
доставке товара по адресу, указанному клиентом.
Вариант 22. Информационная система "Прокат дисков".
Информационная система должна отражать перечень дисков, которые
могут быть сданы в прокат. У компании имеется несколько филиалов.
Можно заказать любой диск, который находится в любом из филиалов. ИС
должна отражать “историю” любого диска (дату приобретения, сколько раз
72
был в прокате, какое количество дней, какую сумму “заработал”, в каком из
филиалов сдавался большее число раз).
Вариант 23. Информационная система "Гостиница".
Информационная система должна отражать текущее предложение
гостиничных номеров различных категорий. Необходимо предусмотреть
возможность бронирования номеров за 30 дней и возможность
дополнительного сервиса (питания, наличия холодильника, телевизора) в
номерах различных категорий. При размещении групп необходимо
предусмотреть скидки.
Вариант 24. Информационная система "Организация спортивного
мероприятия".
Предметной областью проектируемой информационной системы
является организация и проведение соревнований, т.е. организация работы с
организационным комитетом. БД ориентирована на проведение
индивидуальных соревнований, например по легкой и тяжелой атлетике,
лыжному спорту, плаванию и т.д.
Оргкомитет соревнований выполняет следующие функции:
 организацию расселения спортсменов;
 выбор объектов, на которых будут проводиться соревнования;
 выбор даты и времени проведения соревнований по каждой
конкретной дисциплине;
 организацию судейства соревнований;
 присуждение разряда спортсменам;
 подведение итогов соревнований.
Каждая команда (страна, регион, клуб) выставляет на соревнования
некоторое количество спортсменов. Каждому спортсмену выдается
определенный порядковый номер, который является его идентификатором на
всем протяжении соревнований. Каждый спортсмен занимает на
соревнованиях определенное место, при этом возможна ситуация, при
которой несколько спортсменов занимают одно и то же место. Спортсмены
могут выступать в одной или нескольких дисциплинах. При этом БД должна
содержать информацию о расписании соревнований, т.е. дату и время старта
каждой из дисциплин, а также место её проведения.
Каждое соревнование обслуживается одним или несколькими
арбитрами. Для организаторов также важно организовать систему расселения
спортсменов, т.е. БД должна содержать место проживания и номер телефона
для связи со спортсменом. По итогам соревнований определяется
общекомандное место, в зависимости от количества медалей, завоеванных
командами.
73
Вариант 25. Информационная система "Расписание метро".
Разрабатываемая система должна решать вопрос согласованного
расписания движения электропоездов в зависимости от количества
маршрутов, их протяженности и количества поездов. Предусмотреть
составление расписания в зависимости от времени стоянки и количества
электропоездов на маршруте.
Задание 2
С помощью языка SQL создать запросы к созданной БД для ввода туда
данных различными операторами (insert … values..; load data…from..).
Используя введенные данные, подготовить и реализовать серию запросов,
связанных с выборкой информации и модификацией данных таблиц. Запросы
к БД должны реализовывать:
 ввод данных различными операторами (3 запроса);
 выборку данных из таблиц в указанном порядке (3 запроса);
 вывод результатов, исключая дубликаты (2 запроса);
 использование в запросах констант и выражений (4 запроса);
 использование группировки и упорядочивания (2 запроса);
 использование агрегатных функций, функций даты, строковых
функций (5 запросов).
Запросы должны быть представлены, помимо бумажного носителя, в
виде текстового файла, требования к которому перечислены в задании 1.
Примеры перечисленных запросов приведены в рабочей программе.
Задание 3
Используя в качестве web-сервера сервер Apache и язык
программирования PERL, составить web-приложение, обеспечивающее
выполнение по одному запросу из каждой группы запросов, перечисленных в
задании 2. При создании приложения следует учесть, что дерево директорий
должно быть таким как показано в табл. 1.
Таблица 1
D:\usr\
www
cgi-bin
local
Apache
Apache.exe
Perl
bin
Perl.exe
MySQL
Mysql.exe
База данных должна заполняться средствами, наиболее полно
автоматизирующими этот процесс. При этом не допускается:
74
1) ввод информации об одном объекте разными способами или в
разных местах;
2) ввод одной и той же информации в нескольких местах;
3) ввод информации разрозненно, без поддержания общей структуры
объекта.
Задание должно быть представлено в виде готовых к использованию
файлов и их описанию на бумажном носителе. При этом исполняемые файлы
на языке PERL располагаются в директории \cgi-bin\bd_num, а HTML- файлы
должны быть сконфигурированы для расположения в директории
www\bd_num, где num-номер варианта, это также необходимо предусмотреть
при вызове исполнительных программ из форм HTML. В случае если при
написании исходного кода приложения на языке PERL будут подключаться
библиотеки, то они также должны быть представлены.
75
ПРИЛОЖЕНИЕ Б
Утилита СУБД MYSQL Mysqldump
Программа mysqldump используется для создания дампа содержания
базы данных MySQL. Она пишет инструкции SQL в стандартный вывод. Эти
инструкции SQL могут быть переназначены в файл. Можно резервировать
базу данных MySQL, используя mysqldump, но при этом Вы должны
убедиться, что в этот момент с базой данных не выполняется никаких других
действий.
Программа mysqldump поддерживает следующие параметры (Вы
можете использовать короткую или подробную версию):
Вывести в протокол отладочную информацию. В
-#, --debug=[options]
общем виде 'd:t:o, filename`
-?, --help
Справка
Генерируйте полные инструкции insert (не исключая
-c, --compleat-insert
значений, которые соответствуют значениям столбца
по умолчанию)
-h, --host=[hostname] Соединиться с сервером hostname
Экспорт только схемы информации (исключая
-d, --no-data
данные)
Экспорт только данных, исключая информацию для
-t, --no-create-info
создания таблицы. Противоположность -d
Пароль пользователя, для соединения с сервером
-p,
-MySQL. Обратите внимание, что не должно быть
password=[password]
пробела между -p и паролем
Не буферизовать результаты запроса, дамп выдать
-q, --quick
непосредственно к STDOUT
Имя пользователя. Если не задано, используется
-u, --user=[username]
текущий логин
Вывести подробную информацию относительно
-v, --verbose
различных стадий выполнения mysqldump
-P, --port=[port]
Порт для связи
-V, --version
Информация о версии
Вы можете направить вывод mysqldump в клиентскую программу
MySQL, чтобы копировать базу данных.
Примечание: Вы должны убедиться, что база данных не изменяется в
это время, иначе Вы получите противоречивую копию:
..$ mysqldump -u root -p --opt mysql user>mysql-1.sql
..$ mysqldump -u root mysql>mysql-2.sql
После выполнения этой команды у нас появился файл mysql-1.sql и
mysql-2.sql. Загрузим их в текстовый редактор, чтобы поподробнее изучить
и, возможно, немного поправить.
76
Если пароль был случайно забыт, можно воспользоваться ключом
MYSQLD и ввести --skip-grant-tables, при этом все пароли будут иметь
пустое поле.
77
ПРИЛОЖЕНИЕ С
Синтаксис оператора CREATE TABLE
CREATE
[TEMPORARY]
TABLE
[IF
[(create_definition,...)]
[table_options] [select_statement]
NOT
EXISTS]
tbl_name
create_definition:
col_name type [NOT NULL | NULL] [DEFAULT default_value]
[AUTO_INCREMENT]
[PRIMARY KEY] [reference_definition]
или
PRIMARY KEY (index_col_name,...)
или
KEY [index_name] (index_col_name,...)
или
INDEX [index_name] (index_col_name,...)
или
UNIQUE [INDEX] [index_name] (index_col_name,...)
или
FULLTEXT [INDEX] [index_name] (index_col_name,...)
или
[CONSTRAINT
symbol]
FOREIGN
KEY
[index_name]
(index_col_name,...)
[reference_definition]
или
CHECK (expr)
type:
TINYINT[(length)] [UNSIGNED] [ZEROFILL]
или
SMALLINT[(length)] [UNSIGNED] [ZEROFILL]
или
MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL]
или
INT[(length)] [UNSIGNED] [ZEROFILL]
или
INTEGER[(length)] [UNSIGNED] [ZEROFILL]
или
BIGINT[(length)] [UNSIGNED] [ZEROFILL]
или
REAL[(length,decimals)] [UNSIGNED] [ZEROFILL]
или
DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]
или
FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]
или
DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL]
или
NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL]
или
CHAR(length) [BINARY]
или
VARCHAR(length) [BINARY]
или
DATE
или
TIME
или
TIMESTAMP
или
DATETIME
или
TINYBLOB
или
BLOB
или
MEDIUMBLOB
или
LONGBLOB
или
TINYTEXT
или
TEXT
или
MEDIUMTEXT
или
LONGTEXT
или
ENUM(value1,value2,value3,...)
или
SET(value1,value2,value3,...)
index_col_name:
col_name [(length)]
78
reference_definition:
REFERENCES tbl_name [(index_col_name,...)]
[MATCH FULL | MATCH PARTIAL]
[ON DELETE reference_option]
[ON UPDATE reference_option]
reference_option:
RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
table_options:
TYPE = {BDB | HEAP | ISAM | InnoDB | MERGE | MRG_MYISAM
| MYISAM }
Оператор CREATE TABLE создает таблицу с заданным именем в
текущей базе данных.
Для всех имен баз данных, таблиц, столбцов, индексов и псевдонимов в
MySQL приняты одни и те же правила.
Следует отметить, что эти правила были изменены, начиная с версии
MySQL 3.23.6, когда было разрешено брать в одиночные скобки (')
идентификаторы (имена баз данных, таблиц и столбцов). Двойные скобки (")
тоже допустимы - при работе в режиме ANSI SQL.
Идентификатор Макс.
длинаДопускаемые символы
строки
База данных
64
Любой символ, допустимый в имени
каталога, за исключением (/) или (.)
Таблица
64
Любой символ, допустимый в имени
файла, за исключением (/) или (.)
Столбец
64
Все символы
Псевдоним
255
Все символы
Если нет активной текущей базы данных или указанная таблица уже
существует, то возникает ошибка выполнения команды.
В версии MySQL 3.22 и более поздних имя таблицы может быть
указано как db_name.tbl_name. Эта форма записи работает независимо от
того, является ли указанная база данных текущей.
В версии MySQL 3.23 при создании таблицы можно использовать
ключевое слово TEMPORARY. Временная таблица автоматически удаляется
по завершении соединения, а ее имя действительно только в течение данного
соединения. Это означает, что в двух разных соединениях могут
использоваться временные таблицы с одинаковыми именами без конфликта
друг с другом или с существующей таблицей с тем же именем
(существующая таблица скрыта, пока не удалена временная таблица). В
версии MySQL 4.0.2 для создания временных таблиц необходимо иметь
привилегии CREATE TEMPORARY TABLES.
В версии MySQL 3.23 и более поздних можно использовать ключевые
слова IF NOT EXISTS для того, чтобы не возникала ошибка, если
79
указанная таблица уже существует. Следует учитывать, что при этом не
проверяется идентичность структур этих таблиц.
Каждая таблица tbl_name представлена определенными файлами в
директории базы данных. В случае таблиц типа MyISAM - это следующие
файлы:
Файл
Назначение
tbl_name.frm
Файл определения таблицы
tbl_name.MYD
Файл данных
tbl_name.MYI
Файл индексов
Чтобы получить более полную информацию о свойствах различных
типов столбцов, см. документацию к СУБД.
Если не указывается ни NULL, ни NOT NULL, то столбец
интерпретируется так, как будто указано NULL.
Целочисленный столбец может иметь дополнительный атрибут
AUTO_INCREMENT. При записи величины NULL (рекомендуется) или 0 в
столбец AUTO_INCREMENT данный столбец устанавливается в значение
value+1, где value представляет собой наибольшее для этого столбца
значение
в
таблице
на
момент
записи.
Последовательность
AUTO_INCREMENT начинается с 1. Если удалить строку, содержащую
максимальную величину для столбца AUTO_INCREMENT, то в таблицах типа
ISAM или BDB эта величина будет восстановлена, а в таблицах типа MyISAM
или InnoDB - нет. Если удалить все строки в таблице командой DELETE
FROM table_name (без выражения WHERE) в режиме AUTOCOMMIT, то для
таблиц всех типов последовательность начнется заново.
Примечание: в таблице может быть только один столбец
AUTO_INCREMENT, и он должен быть индексирован. Кроме того, версия
MySQL 3.23 будет правильно работать только с положительными
величинами столбца AUTO_INCREMENT. В случае внесения отрицательного
числа оно интерпретируется как очень большое положительное число. Это
делается, чтобы избежать проблем с точностью, когда числа
''заворачиваются'' от положительного к отрицательному и, кроме того, для
гарантии, что по ошибке не будет получен столбец AUTO_INCREMENT со
значением 0.
Величины NULL для столбца типа TIMESTAMP обрабатываются иначе,
чем для столбцов других типов. В столбце TIMESTAMP нельзя хранить
литерал NULL; при установке данного столбца в NULL он будет установлен в
текущее значение даты и времени. Поскольку столбцы TIMESTAMP ведут
себя подобным образом, то атрибуты NULL и NOT NULL неприменимы в
обычном режиме и игнорируются при их задании. С другой стороны, чтобы
облегчить клиентам MySQL использование столбцов TIMESTAMP, сервер
80
сообщает, что таким столбцам могут быть назначены величины NULL (что
соответствует действительности), хотя реально TIMESTAMP никогда не
будет содержать величины NULL. Это можно увидеть, применив DESCRIBE
tbl_name для получения описания данной таблицы. Следует учитывать, что
установка столбца TIMESTAMP в 0 не равнозначна установке его в NULL,
поскольку 0 для TIMESTAMP является допустимой величиной.
Величина DEFAULT должна быть константой, она не может быть
функцией или выражением. Если для данного столбца не задается никакой
величины DEFAULT, то MySQL автоматически назначает ее. Если столбец
может принимать NULL как допустимую величину, то по умолчанию
присваивается значение NULL. Если столбец объявлен как NOT NULL, то
значение по умолчанию зависит от типа столбца: для числовых типов, за
исключением объявленных с атрибутом AUTO_INCREMENT, значение по
умолчанию равно 0. Для столбца AUTO_INCREMENT значением по
умолчанию является следующее значение в последовательности для этого
столбца.
Для типов даты и времени, отличных от TIMESTAMP, значение по
умолчанию равно соответствующей нулевой величине для данного типа. Для
первого столбца TIMESTAMP в таблице значение по умолчанию представляет
собой текущее значение даты и времени.
Для строковых типов, кроме ENUM, значением по умолчанию является
пустая строка. Для ENUM значение по умолчанию равно первой
перечисляемой величине (если явно не задано другое значение по умолчанию
с помощью директивы DEFAULT).
Значения по умолчанию должны быть константами. Это означает,
например, что нельзя установить для столбца ''даты'' в качестве значения по
умолчанию величину функции, такой как NOW() или CURRENT_DATE.
KEY является синонимом для INDEX.
В MySQL ключ UNIQUE может иметь только различающиеся значения.
При попытке добавить новую строку с ключом, совпадающим с
существующей строкой, возникает ошибка выполнения команды.
PRIMARY KEY представляет собой уникальный ключ KEY с
дополнительным ограничением, т.е. столбцы с данным ключом должны быть
определены как NOT NULL. В MySQL этот ключ называется PRIMARY
(первичный). Таблица может иметь только один первичный ключ PRIMARY
KEY. Если PRIMARY KEY отсутствует в таблицах, а некоторое приложение
запрашивает его, то MySQL может превратить в PRIMARY KEY первый
ключ UNIQUE, не имеющий ни одного столбца NULL.
PRIMARY KEY может быть многостолбцовым индексом. Однако
нельзя создать многостолбцовый индекс, используя в определении столбца
атрибут ключа PRIMARY KEY. Именно таким образом только один столбец
81
будет отмечен как первичный. Необходимо использовать синтаксис
PRIMARY KEY(index_col_name, ...).
Если ключ PRIMARY или UNIQUE состоит только из одного столбца и
он принадлежит к числовому типу, то на него можно сослаться также, как на
_rowid (новшество версии 3.23.11).
Если индексу не назначено имя, то ему будет присвоено первое имя в
index_col_name, возможно, с суффиксами (_2, _3, ...), делающими это
имя уникальным. Имена индексов для таблицы можно увидеть, используя
SHOW INDEX FROM tbl_name. SHOW Syntax.
С помощью выражения col_name(length) можно указать индекс,
для которого используется только часть столбца CHAR или VARCHAR. Это
поможет сделать файл индексов намного меньше.
Индексацию столбцов BLOB и TEXT поддерживают только таблицы с
типом MyISAM. Назначая индекс столбцу с типом BLOB или TEXT, всегда
НЕОБХОДИМО указывать длину этого индекса:
CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
В версии MySQL 3.23.23 и более поздних можно создавать также
специальные индексы FULLTEXT. Они применяются для полнотекстового
поиска. Эти индексы поддерживаются только таблицами типа MyISAM, и
они могут быть созданы только из столбцов VARCHAR и TEXT.
Индексирование всегда выполняется для всего столбца целиком, частичная
индексация не поддерживается. Более подробно эта операция описана в
разделе MySQL section.
Выражения FOREIGN KEY, CHECK и REFERENCES фактически ничего
не делают. Они введены только из соображений совместимости, чтобы
облегчить перенос кода с других SQL-серверов и запускать приложения,
создающие таблицы со ссылками.
Для каждого столбца NULL требуется один дополнительный бит, при
этом величина столбца округляется в большую сторону до ближайшего
байта.
Максимальную длину записи в байтах можно вычислить следующим
образом:
длина записи = 1+
+ (сумма длин столбцов)+
+ (количество столбцов с допустимым NULL + 7)/8+
+ (количество столбцов с динамической длинной).
Опции table_options и SELECT реализованы только в версиях
MySQL 3.23 и выше. Ниже представлены различные типы таблиц:
Тип таблицы Описание
BDB
Таблицы с поддержкой транзакций и блокировкой страниц
HEAP
Данные для этой таблицы хранятся только в памяти
ISAM
Оригинальный обработчик таблиц
82
Таблицы с поддержкой транзакций и блокировкой строк. See
section
MERGE
Набор таблиц MyISAM, используемый как одна таблица. See
section
MRG_MyISA Псевдоним для таблиц MERGE
M
MyISAM
Новый обработчик, обеспечивающий переносимость таблиц в
бинарном виде, который заменяет ISAM. See section
Если задается тип таблицы, который не поддерживается данной
версией, то MySQL выберет из возможных типов ближайший к указанному.
Например, если задается TYPE=BDB и данный дистрибутив MySQL не
поддерживает таблиц BDB, то вместо этого будет создана таблица MyISAM.
Другие табличные опции используются для оптимизации характеристик
таблицы. Эти опции в большинстве случаев не требуют специальной
установки. Данные опции работают с таблицами всех типов, если не указано
иное:
Опция
Описание
AUTO_INCREMENT Следующая величина AUTO_INCREMENT, которую
следует установить для данной таблицы (MyISAM)
AVG_ROW_LENGTH Приближенное значение средней длины строки для
данной таблицы. Имеет смысл устанавливать только
для обширных таблиц с записями переменной длины
CHECKSUM
Следует установить в 1, чтобы в MySQL
поддерживалась проверка контрольной суммы для
всех строк (это делает таблицы немного более
медленными при обновлении, но позволяет легче
находить поврежденные таблицы) (MyISAM)
COMMENT
Комментарий для данной таблицы длиной 60 символов
MAX_ROWS
Максимальное число строк, которые планируется
хранить в данной таблице
MIN_ROWS
Минимальное число строк, которые планируется
хранить в данной таблице
PACK_KEYS
Следует установить в 1 для получения меньшего
индекса. Обычно это замедляет обновление и ускоряет
чтение (MyISAM, ISAM). Установка в 0 отключит
уплотнение ключей. При установке в DEFAULT
(MySQL 4.0) обработчик таблиц будет уплотнять
только длинные столбцы CHAR/VARCHAR
PASSWORD
Шифрует файл `.frm' с помощью пароля. Эта опция
не функционирует в стандартной версии MySQL
DELAY_KEY_WRIT Установка в 1 задерживает операции обновления
E
таблицы ключей, пока не закроется указанная таблица
InnoDB
83
(MyISAM)
ROW_FORMAT
Определяет, каким образом должны храниться строки.
В настоящее время эта опция работает только с
таблицами MyISAM, которые поддерживают форматы
строк DYNAMIC и FIXED
При использовании таблиц MyISAM MySQL вычисляет выражение
max_rows * avg_row_length, чтобы определить, насколько велика
будет результирующая таблица. Если не задана ни одна из вышеупомянутых
опций, то максимальный размер таблицы будет составлять 4Гб (или 2Гб,
если данная операционная система поддерживает только таблицы величиной
до 2Гб). Это делается для того, чтобы (если нет реальной необходимости в
больших файлах), ограничить размеры указателей, что позволит сделать
индексы меньше и быстрее. Если опция PACK_KEYS не используется, то по
умолчанию уплотняются только строки, но не числа. При использовании
PACK_KEYS=1 числа тоже будут уплотняться. При уплотнении двоичных
числовых ключей MySQL будет использовать сжатие префиксов. Это
означает, что выгода от этого будет значительной только в случае большого
количества одинаковых чисел. При сжатии префиксов для каждого ключа
требуется один дополнительный байт, в котором указано, сколько байтов
предыдущего ключа являются такими же, как и для следующего (следует
учитывать, что указатель на строку хранится в порядке "старший-байт-вначале", сразу после ключа, - чтобы улучшить компрессию). Это означает,
что при наличии нескольких одинаковых ключей в двух строках записи все
последующие ''аналогичные'' ключи будут занимать только по 2 байта
(включая указатель строки). Сравним: в обычном случае для хранения
последующих
ключей
требуется
размер_хранения_ключа
+
размер_указателя (обычно 4) байтов. С другой стороны, если все
ключи абсолютно разные, каждый ключ будет занимать на 1 байт больше,
если данный ключ не может иметь величину NULL (в этом случае
уплотненный ключ будет храниться в том же байте, который используется
для указания, что ключ равен NULL).
Если после команды CREATE указывается команда SELECT, то MySQL
создаст новые поля для всех элементов в данной команде SELECT.
Например:
mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (a), KEY(b))
TYPE=MyISAM SELECT b,c FROM test2;
Эта команда создаст таблицу MyISAM с тремя столбцами: a, b и c.
Отметим, что столбцы из команды SELECT присоединяются к таблице
справа, а не перекрывают ее. Рассмотрим следующий пример:
mysql> SELECT * FROM foo;
+---+
| n |
84
+---+
| 1 |
+---+
mysql> CREATE TABLE bar (m INT) SELECT n FROM foo;
Query OK, 1 row affected (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM bar;
+------+---+
| m
| n |
+------+---+
| NULL | 1 |
+------+---+
1 row in set (0.00 sec)
Каждая строка в таблице foo вносится в таблицу bar со своим
значением из foo, при этом в новые столбцы в таблице bar записываются
величины, заданные по умолчанию. Команда CREATE TABLE ... SELECT
не создает автоматически каких-либо индексов. Это сделано преднамеренно,
чтобы команда была настолько гибкой, насколько возможно. Чтобы иметь
индексы в созданной таблице, необходимо указать их перед данной командой
SELECT:
mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;
Если возникает ошибка при копировании данных в таблицу, то они
будут автоматически удалены. Чтобы обеспечить возможность использовать
для восстановления таблиц журнал обновлений/двоичный журнал, в MySQL
во время выполнения команды CREATE TABLE ... SELECT не
разрешены параллельные вставки.
85
Синтаксис оператора ALTER TABLE
ALTER [IGNORE] TABLE tbl_name alter_spec [, alter_spec ...]
alter_specification:
ADD
[COLUMN]
create_definition
[FIRST
|
AFTER
column_name]
или
ADD [COLUMN] (create_definition, create_definition,...)
или
ADD INDEX [index_name] (index_col_name,...)
или
ADD PRIMARY KEY (index_col_name,...)
или
ADD UNIQUE [index_name] (index_col_name,...)
или
ADD FULLTEXT [index_name] (index_col_name,...)
или
ADD [CONSTRAINT symbol] FOREIGN KEY index_name
(index_col_name,...)
[reference_definition]
или
ALTER [COLUMN] col_name {SET DEFAULT literal | DROP
DEFAULT}
или
CHANGE [COLUMN] old_col_name create_definition
[FIRST | AFTER column_name]
или
MODIFY [COLUMN] create_definition [FIRST | AFTER
column_name]
или
DROP [COLUMN] col_name
или
DROP PRIMARY KEY
или
DROP INDEX index_name
или
DISABLE KEYS
или
ENABLE KEYS
или
RENAME [TO] new_tbl_name
или
ORDER BY col
или
table_options
Оператор ALTER TABLE обеспечивает возможность изменять
структуру существующей таблицы. Например, можно добавлять или удалять
столбцы, создавать или уничтожать индексы или переименовывать столбцы
либо саму таблицу. Можно также изменять комментарий для таблицы и ее
тип.
Оператор ALTER TABLE во время работы создает временную копию
исходной таблицы. Требуемое изменение выполняется на копии, затем
исходная таблица удаляется, а новая переименовывается. Так делается для
того, чтобы в новую таблицу автоматически попадали все обновления, кроме
неудавшихся. Во время выполнения ALTER TABLE исходная таблица
доступна для чтения другими клиентами. Операции обновления и записи в
этой таблице приостанавливаются, пока не будет готова новая таблица.
Следует отметить, что при использовании любой другой опции для
ALTER TABLE, кроме RENAME, MySQL всегда будет создавать временную
таблицу, даже если данные, строго говоря, и не нуждаются в копировании
(например, при изменении имени столбца). Для таблиц MyISAM можно
увеличить скорость воссоздания индексной части (что является наиболее
медленной частью в процессе восстановления таблицы) путем установки
переменной myisam_sort_buffer_size достаточно большого значения.
86
Для использования оператора ALTER TABLE необходимы привилегии
ALTER, INSERT и CREATE для данной таблицы.
Опция IGNORE является расширением MySQL по отношению к ANSI
SQL92. Она управляет работой ALTER TABLE при наличии дубликатов
уникальных ключей в новой таблице. Если опция IGNORE не задана, то для
данной копии процесс прерывается и происходит откат назад. Если IGNORE
указывается, тогда для строк с дубликатами уникальных ключей только
первая строка используется, а остальные удаляются.
Можно запустить несколько выражений ADD, ALTER, DROP и CHANGE
в одной команде ALTER TABLE. Это является расширением MySQL по
отношению к ANSI SQL92, где допускается только одно выражение из
упомянутых в одной команде ALTER TABLE.
Опции CHANGE col_name, DROP col_name и DROP INDEX также
являются расширениями MySQL по отношению к ANSI SQL92.
Опция MODIFY представляет собой расширение Oracle для команды
ALTER TABLE.
Необязательное слово COLUMN представляет собой ''белый шум'' и
может быть опущено.
При использовании ALTER TABLE имя_таблицы RENAME TO
новое_имя без каких-либо других опций MySQL просто переименовывает
файлы, соответствующие заданной таблице. В этом случае нет
необходимости
создавать
временную
таблицу.
В
выражении
create_definition для ADD и CHANGE используется тот же синтаксис,
что и для CREATE TABLE. Следует учитывать, что этот синтаксис включает
имя столбца, а не просто его тип.
Столбец можно переименовывать, используя выражение CHANGE
имя_столбца create_definition. Чтобы сделать это, необходимо
указать старое и новое имена столбца и его тип в настоящее время.
Например, чтобы переименовать столбец INTEGER из a в b, можно сделать
следующее:
mysql> ALTER TABLE t1 CHANGE a b INTEGER;
При изменении типа столбца, но не его имени синтаксис выражения
CHANGE все равно требует указания обоих имен столбца, даже если они
одинаковы. Например:
mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
Однако, начиная с версии MySQL 3.22.16a, можно также использовать
выражение MODIFY для изменения типа столбца без переименовывания его:
mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
При использовании CHANGE или MODIFY для того, чтобы уменьшить
длину столбца, по части которого построен индекс (например, индекс по
первым 10 символам столбца VARCHAR), нельзя сделать столбец короче, чем
число проиндексированных символов.
87
При изменении типа столбца с использованием CHANGE или MODIFY
MySQL пытается преобразовать данные в новый тип как можно корректнее.
В версии MySQL 3.22 и более поздних можно использовать FIRST или
ADD ... AFTER имя_столбца для добавления столбца на заданную
позицию внутри табличной строки. По умолчанию столбец добавляется в
конце. Начиная с версии MySQL 4.0.1, можно также использовать ключевые
слова FIRST и AFTER в опциях CHANGE или MODIFY.
Опция ALTER COLUMN задает для столбца новое значение по
умолчанию или удаляет старое. Если старое значение по умолчанию
удаляется и данный столбец может принимать значение NULL, то новое
значение по умолчанию будет NULL. Если столбец не может быть NULL, то
MySQL назначает значение по умолчанию. Опция DROP INDEX удаляет
индекс. Это является расширением MySQL по отношению к ANSI SQL92.
Если столбцы удаляются из таблицы, то эти столбцы удаляются также и из
любого индекса, в который они входят как часть. Если все столбцы,
составляющие индекс, удаляются, то данный индекс также удаляется.
Если таблица содержит только один столбец, то этот столбец не может
быть удален. Вместо этого можно удалить данную таблицу, используя
команду DROP TABLE.
Опция DROP PRIMARY KEY удаляет первичный индекс. Если такого
индекса в данной таблице не существует, то удаляется первый индекс
UNIQUE в этой таблице. (MySQL отмечает первый уникальный ключ
UNIQUE как первичный ключ PRIMARY KEY, если никакой другой
первичный ключ PRIMARY KEY не был явно указан). При добавлении
UNIQUE INDEX или PRIMARY KEY в таблицу они хранятся перед
остальными неуникальными ключами, чтобы можно было определить
дублирующиеся ключи как можно раньше.
Опция ORDER BY позволяет создавать новую таблицу со строками,
размещенными в заданном порядке. Следует учитывать, что созданная
таблица не будет сохранять этот порядок строк после операций вставки и
удаления. В некоторых случаях такая возможность может облегчить
операцию сортировки в MySQL, если таблица имеет такое расположение
столбцов, которое Вы хотели бы иметь в дальнейшем. Эта опция в основном
полезна, если заранее известен определенный порядок, в котором
преимущественно будут запрашиваться строки. Использование данной опции
после значительных преобразований таблицы дает возможность получить
более высокую производительность.
При использовании команды ALTER TABLE для таблиц MyISAM все
неуникальные индексы создаются в отдельном пакете (подобно REPAIR).
Благодаря этому команда ALTER TABLE при наличии нескольких индексов
будет работать быстрее.
88
Начиная с MySQL 4.0, вышеуказанная возможность может быть
активизирована явным образом. Команда ALTER TABLE ... DISABLE
KEYS блокирует в MySQL обновление неуникальных индексов для таблиц
MyISAM. После этого можно применить команду ALTER TABLE ...
ENABLE KEYS для воссоздания недостающих индексов. Так как MySQL
делает это с помощью специального алгоритма, который намного быстрее в
сравнении со вставкой ключей один за другим, блокировка ключей может
дать существенное ускорение на больших массивах вставок.
Применяя функцию C API mysql_info(), можно определить,
сколько записей было скопировано, а также (при использовании IGNORE) сколько записей было удалено из-за дублирования значений уникальных
ключей.
Выражения FOREIGN KEY, CHECK и REFERENCES фактически ничего
не делают. Они введены только из соображений совместимости, чтобы
облегчить перенос кода с других серверов SQL и запуск приложений,
создающих таблицы со ссылками.
Ниже приводятся примеры, показывающие некоторые случаи
употребления команды ALTER TABLE. Пример начинается с таблицы t1,
которая создается следующим образом:
mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10));
Для того чтобы переименовать таблицу из t1 в t2:
mysql> ALTER TABLE t1 RENAME t2;
Для того чтобы изменить тип столбца с INTEGER на TINYINT NOT
NULL (оставляя имя прежним) и изменить тип столбца b с CHAR(10) на
CHAR(20) с переименованием его с b на c:
mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c
CHAR(20);
Для того чтобы добавить новый столбец TIMESTAMP с именем d:
mysql> ALTER TABLE t2 ADD d TIMESTAMP;
Для того чтобы добавить индекс к столбцу d и сделать столбец a
первичным ключом:
mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a);
Для того чтобы удалить столбец c:
mysql> ALTER TABLE t2 DROP COLUMN c;
Для того чтобы добавить новый числовой столбец AUTO_INCREMENT
с именем c:
mysql>
ALTER
TABLE
AUTO_INCREMENT,
ADD INDEX (c);
t2
ADD
c
INT
UNSIGNED
NOT
NULL
Заметьте, что столбец c индексируется, так как столбцы
AUTO_INCREMENT должны быть индексированы; кроме того, столбец c
объявляется как NOT NULL, поскольку индексированные столбцы не могут
быть NULL.
89
При добавлении столбца AUTO_INCREMENT значения этого столбца
автоматически заполняются последовательными номерами (при добавлении
записей). Первый номер последовательности можно установить путем
выполнения команды SET INSERT_ID=# перед ALTER TABLE или
использования табличной опции AUTO_INCREMENT = #.
90
Синтаксис оператора DROP TABLE, DATABASE
DROP TABLE
CASCADE]
[IF
EXISTS]
tbl_name
[,
tbl_name,..]
[RESTRICT
Оператор DROP TABLE удаляет одну или несколько таблиц. Все
табличные данные и определения удаляются, так что будьте внимательны
при работе с этой командой! Действия с БД аналогичны.
Оператор DROP DATABASE удаляет все таблицы в указанной базе
данных и саму базу. Если Вы выполняете DROP DATABASE на базе данных,
символически связанных с другой, то удаляется как ссылка, так и
оригинальная база данных. Будьте очень внимательны при работе с этой
командой.
91
Синтаксис оператора UPDATE
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name
SET col_name1=expr1 [, col_name2=expr2, ...][WHERE
where_definition][LIMIT #]
Оператор UPDATE обновляет столбцы в соответствии с их новыми
значениями в строках существующей таблицы. В выражении SET
указывается, какие именно столбцы следует модифицировать и какие
величины должны быть в них установлены. В выражении WHERE, если оно
присутствует, задается, какие строки подлежат обновлению. В остальных
случаях обновляются все строки. Если задано выражение ORDER BY, то
строки будут обновляться в указанном в нем порядке.
Если указывается ключевое слово LOW_PRIORITY, то выполнение
данной команды UPDATE задерживается до тех пор, пока другие клиенты не
завершат чтение этой таблицы.
Если указывается ключевое слово IGNORE, то команда обновления не
будет прервана, даже если при обновлении возникнет ошибка дублирования
ключей. Строки, из-за которых возникают конфликтные ситуации,
обновлены не будут.
Если доступ к столбцу из указанного выражения осуществляется по
аргументу tbl_name, то команда UPDATE использует для этого столбца его
текущее значение. Например, следующая команда устанавливает столбец
age в значение, на единицу большее его текущей величины:
mysql> UPDATE persondata SET age=age+1;
Значения команда UPDATE присваивает слева направо. Например,
следующая команда дублирует столбец age, затем инкрементирует его:
mysql> UPDATE persondata SET age=age*2, age=age+1;
Если столбец устанавливается в его текущее значение, то MySQL
замечает это и не обновляет его.
Команда UPDATE возвращает количество фактически измененных
строк. В версии MySQL 3.22 и более поздних функция C API
mysql_info() возвращает количество строк, которые были найдены и
обновлены, и количество предупреждений, имевших место при выполнении
UPDATE.
92
Синтаксис оператора DELETE
DELETE [LOW_PRIORITY | QUICK] FROM table_name
[WHERE where_definition]
[ORDER BY ...]
[LIMIT rows]
или
DELETE
[LOW_PRIORITY
|
QUICK]
table_name[.*]
[,table_name[.*] ...]
FROM table-references
[WHERE where_definition]
или
DELETE [LOW_PRIORITY | QUICK]
FROM table_name[.*], [table_name[.*] ...]
USING table-references
[WHERE where_definition]
Оператор DELETE удаляет из таблицы table_name строки,
удовлетворяющие заданным в where_definition условиям, и возвращает
число удаленных записей.
Если оператор DELETE запускается без определения WHERE, то
удаляются все строки. При работе в режиме AUTOCOMMIT это будет
аналогично использованию оператора TRUNCATE. В MySQL 3.23 оператор
DELETE без определения WHERE возвратит ноль как число удаленных
записей.
Если действительно необходимо знать число удаленных записей при
удалении всех строк и если допустимы потери в скорости, то можно
использовать команду DELETE в следующей форме:
mysql> DELETE FROM table_name WHERE 1>0;
Следует учитывать, что эта форма работает намного медленнее, чем
DELETE FROM table_name без выражения WHERE, поскольку строки
удаляются поочередно по одной.
Если указано ключевое слово LOW_PRIORITY, выполнение данной
команды DELETE будет задержано до тех пор, пока другие клиенты не
завершат чтение этой таблицы.
Если задан параметр QUICK, то обработчик таблицы при выполнении
удаления не будет объединять индексы - в некоторых случаях это может
ускорить данную операцию.
Символы .* после имен таблиц требуются только для совместимости с
Access:
DELETE t1,t2 FROM t1,t2,t3 WHERE t1.id=t2.id AND
t2.id=t3.id
или
93
DELETE FROM t1,t2 USING t1,t2,t3 WHERE t1.id=t2.id
AND t2.id=t3.id
В предыдущем случае просто удалены совпадающие строки из таблиц
t1 и t2.
Выражение ORDER BY и использование нескольких таблиц в команде
DELETE поддерживается в MySQL 4.0.
Если применяется выражение ORDER BY, то строки будут удалены в
указанном порядке. В действительности это выражение полезно только в
сочетании с LIMIT. Например:
DELETE FROM somelog
WHERE user = 'jcole'
ORDER BY timestamp
LIMIT 1
Данный оператор удалит самую старую запись (по timestamp), в
которой строка соответствует указанной в выражении WHERE.
Специфическая для MySQL опция LIMIT для команды DELETE
указывает серверу максимальное количество строк, которые следует удалить
до возврата управления клиенту. Эта опция может использоваться для
гарантии того, что данная команда DELETE не потребует слишком много
времени для выполнения. Можно просто повторять команду DELETE до тех
пор, пока количество удаленных строк меньше, чем величина LIMIT.
94
Синтаксис оператора SELECT
Оператор SELECT имеет следующую структуру:
SELECT [STRAIGHT_JOIN]
[SQL_SMALL_RESULT]
[SQL_BIG_RESULT]
[SQL_BUFFER_RESULT]
[SQL_CACHE
|
SQL_NO_CACHE]
[SQL_CALC_FOUND_ROWS] [HIGH_PRIORITY]
[DISTINCT | DISTINCTROW | ALL]
select_expression,...
[INTO
{OUTFILE
|
DUMPFILE}
'file_name'
export_options]
[FROM table_references
[WHERE where_definition]
[GROUP BY {unsigned_integer | col_name |
formula} [ASC | DESC], ...]
[HAVING where_definition]
[ORDER BY {unsigned_integer | col_name |
formula} [ASC | DESC], ...]
[LIMIT [offset,] rows]
[PROCEDURE procedure_name]
[FOR UPDATE | LOCK IN SHARE MODE]]
SELECT применяется для извлечения строк, выбранных из одной или
нескольких таблиц.
select_expression может содержать следующие функции и операторы:
Арифметические действия
Остаток от деления (как в C)
Битовые функции (используется 48
бит)
-С
Мена знака числа
()
Скобки
BETWEEN(A, B, C) (A >= B) AND (A <= C)
BIT_COUNT()
Количество бит
ELT(N, a, b, c, d)
Возвращает a, если N == 1, b, если N
== 2 и т. д. a, b, c, d - строки.
ПРИМЕР:
ELT(3, "First", "Second", "Third",
"Fourth")
вернет "Third"
FIELD(Z, a, b, c)
Возвращает a, если Z == a; b, если
Z == b и т. д., где a, b, c, d строки
+-*/
%
|&
95
ПРИМЕР:
FIELD("Second", "First", "Second",
"Third",
"Fourth")
вернет "Second"
IF(A, B, C)
Если A истина (!= 0 and != NULL), то
вернет B, иначе вернет C
IFNULL(A, B)
Если A не null, вернет A, иначе
вернет B
ISNULL(A)
Вернет 1, если A == NULL, иначе
вернет 0. Эквивалент ('A == NULL')
NOT !
NOT, вернет TRUE (1) или FALSE (0)
OR, AND
Вернет TRUE (1) или FALSE (0)
SIGN()
Вернет -1, 0 или 1 (знак аргумента)
SUM()
Сумма столбца
= <> <= < >= >
Вернет TRUE (1) или FALSE (0)
expr LIKE expr
Вернет TRUE (1) или FALSE (0)
expr NOT LIKE expr Вернет TRUE (1) или FALSE (0)
expr REGEXP expr Проверяет строку на соответствие
регулярному выражению expr
expr NOT REGEXP Проверяет строку на соответствие
expr
регулярному выражению expr
select_expression может также содержать один или большее количество
следующих математических функций:
ABS()
Абсолютное значение (модуль числа)
CEILING()
()
EXP()
Экспонента
FORMAT(nr, NUM) Форматирует число в формат '#, ###, ###.##' с NUM
десятичных цифр
LOG()
Логарифм
LOG10()
Логарифм по основанию 10
MIN(), MAX()
Минимум или максимум соответственно. Должна иметь
при вызове два или более аргумента,
иначе
рассматривается как групповая функция
MOD()
Остаток от деления (аналог %)
POW()
Степень
ROUND()
Округление до ближайшего целого числа
RAND([integer_expr] Случайное число типа float, 0 <= x <= 1.0, используется
)
integer_expr как значение для запуска генератора
SQRT()
Квадратный корень
select_expression может также содержать одну или больше следующих
строковых функций.
CONCAT()
Объединение строк
96
Возвращает 1, если A == a; 2, если A == b... Если
совпадений нет, вернет 0. A, a, b, c, d - строки.
INSERT(org, strt, len, new) Заменяет подстроку org[strt...len(gth)] на new.
Первая позиция строки=1
LCASE(A)
Приводит A к нижнему регистру
LEFT()
Возвращает строку символов, отсчитывая слева
LENGTH()
Длина строки
LOCATE(A, B)
Позиция подстроки B в строке A
LOCATE(A, B, C)
Позиция подстроки B в строке A, начиная с
позиции C
LTRIM(str)
Удаляет все начальные пробелы из строки str
REPLACE(A, B, C)
Заменяет все подстроки B в строке A на подстроку
C
RIGHT()
Получение подстроки справа
RTRIM(str)
Удаляет хвостовые пробелы из строки str
STRCMP()
Возвращает 0, если строки одинаковые
SUBSTRING(A, B, C)
Возвращает подстроку из A, с позиции B до
позиции C
UCASE(A)
Переводит A в верхний регистр
И наконец несколько просто полезных функций, которые тоже можно
применить в select_expression.
CURDATE()
Текущая дата
DATABASE()
Имя текущей базы данных из которой
выполняется выбор
FROM_DAYS()
Меняет день на DATE
NOW()
Текущее
время
в
форматах
YYYYMMDDHHMMSS или "YYYY-MM-DD
HH:MM:SS". Формат зависит от того в каком
контексте используется NOW(): числовом или
строковом
PASSWORD()
Шифрует строку
PERIOD_ADD(P:N)
Добавить N месяцев к периоду P (в формате
YYMM)
PERIOD_DIFF(A, B)
Возвращает месяцы между A и B. Обратите
внимание, что PERIOD_DIFF работает только с
датами в форме YYMM или YYYMM
TO_DAYS()
Меняет DATE (YYMMDD) на номер дня
UNIX_TIMESTAMP([date] Возвращает метку времени unix, если вызвана без
)
date (секунды,
начиная с GMT 1970.01.01
00:00:00). При вызове со столбцом TIMESTAMP
вернет TIMESTAMP.
date может быть также строкой DATE,
INTERVAL(A, a, b, c, d)
97
DATETIME или числом в формате YYMMDD (или
YYYMMDD)
USER()
Возвращает логин текущего пользователя
WEEKDAY()
Возвращает день недели (0 = понедельник, 1 =
вторник, ...)
Групповые функции в операторе select:
Следующие функции могут быть использованы в предложении
GROUP:
AVG() Среднее для группы GROUP
SUM() Сумма элементов GROUP
COUNT( Число элементов в GROUP
)
MIN()
Минимальный элемент в GROUP
MAX() Максимальный элемент в GROUP
98
ПРИЛОЖЕНИЕ D
Подключение к БД MySQL из perl с использованием модуля DBI
#!/usr/local/perl/bin/perl.exe
# Пример работы с модулем DBI.
# Подключаем модуль DBI для работы с MySQL(далее БД)
# Модуль можно подключить командами use или require.
use DBI;
#Выносим данные, необходимые для подключения к MySQL, в отдельный
#файл(mysql.pl).
require 'mysql.pl';
# Вывод http-заголовка
print "Content-type: text/html\n\n";
# Подключение к базе
$dbh
=
DBI->connect("DBI:mysql:database=$database",
$opt_user,$opt_password) ||
die "Can't connect: $DBI::errstr\n";
# Формируем запрос на просмотр имеющихся баз данных
$query = "SHOW TABLES";
# Подготовка запроса
$sth = $dbh->prepare($query);
$sth->execute();
$cols=$sth->{NUM_OF_FIELDS};
#Формирование заголовка таблицы
print "<table width=70% align=center cellspacing=0 cellpadding=1
border=1>";
print "<tr valign=middle align=center>";
@fieldname=@{ $sth->{NAME}};
for($i=0;$i<$cols;$i++)
{
print "<td><b>$fieldname[$i]</b></td>\n";
}
print "</tr>";
#Формирование таблицы
while (my $ref=$sth->fetchrow_arrayref())
{
print "<tr align=center>";
for($i=0;$i<$cols;$i++)
{
print "<td>",$ref->[$i],"</td>";
}
print "<tr>\n";
}
print "</table>";
$query = "select * from tab_name";
# Подготовка запроса
$sth = $dbh->prepare($query);
# Выполнение запроса
99
$sth->execute;
while ($line = $sth->fetchrow_arrayref)
{
# Печатаем результат
print "$$line[0] <BR>\n"
}
# Отключание от базы
$rc = $sth->finish;
$rc = $dbh->disconnect;
В файле mysql.pl содержатся данные, необходимые для подключения
к базе данных. Вынесение их в отдельный файл позволяет при смене какихлибо параметров подключения (например, смене пароля) сделать изменение
только в одном файле.
mysql.pl
#!/usr/local/perl/bin/perl
# Имя пользователя БД
$opt_user="root";
# Пароль доступа к БД
$opt_password="";
# Имя базы
$database="ucheb";
100
Базы данных
Методические указания к курсовому проектированию
Составитель: Алексей Анатольевич Пономарев
Рецензент: Е.А. Кочегурова - к.т.н., доцент каф. АиКС АВТФ
Редактор: Н.Т. Синельникова
Подписано к печати
Формат 60х 84/16. Бумага ксероксная.
Плоская печать. Усл. печ. л. 1,86. Усл. изд. л. 1,68.
Тираж
экз. заказ №
Цена свободная.
ИПФ ТПУ. Лицензия ЛТ №1 от 18. 04 94г.
Типография ТПУ. 634034, Томск, Ленина 30.
101
Download