Министерство образования Российской Федерации Томский политехнический университет __________________________________________________________________ УТВЕРЖДАЮ Директор ИДО _____________А.Ф. Федоров “____” ____________ 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