Назначение языка SQL. SQL - Энциклопедия языков программирования

Язык SQL

Итак, мы в общих чертах познакомились с основными понятиями теории баз данных , установили и настроили для работы MySQL . Теперь самое время научиться манипулировать данными, хранящимися в базах данных . Для этого нам понадобится SQL – структурированный язык запросов. Этот язык дает возможность создавать, редактировать и удалять информацию, хранящуюся в базах данных , создавать новые базы данных и многое другое. SQL является стандартом ANSI (Американский национальный институт стандартов) и ISO (Международная организация по стандартизации).

Немного истории

Первый международный стандарт языка SQL был принят в 1989 г., его часто называют SQL /89 . Среди недостатков этого стандарта выделяют в первую очередь то, что многие важные свойства он устанавливал как определяемые в реализации. Отсюда произошло множество расхождений в реализациях языка разными производителями. Кроме того, высказывались претензии по поводу отсутствия в этом стандарте упоминаний о практических аспектах языка, таких как его встраивание в язык программирования Си.

Следующий международный стандарт языка SQL был принят в конце 1992 г. И стал называться SQL /92 . Он получился гораздо более точным и полным, чем SQL /89 , хотя и не был лишен недостатков. В настоящее время большинство систем почти полностью реализуют этот стандарт. Однако, как известно, прогресс не остановишь, и в 1999 году появился новый стандарт SQL :1999, также известный как SQL3 . SQL3 характеризуется как «объектно-ориентированный SQL » и является основой нескольких объектно-реляционных систем управления базами данных (например, ORACLE8 компании Oracle, Universal Server компании Informix и DB2 Universal Database компании IBM). Этот стандарт является не просто слиянием SQL -92 и объектной технологии. Он содержит ряд расширений традиционного SQL , а сам документ составлен таким образом, чтобы добиться более эффективной работы в области стандартизации в будущем.

Если говорить о MySQL , то она соответствует начальному уровню SQL92, содержит несколько расширений этого стандарта и стремится к полной поддержке стандарта ANSI SQL99, но без ущерба для скорости и качества кода.

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

Основные операторы языка SQL

Функции любой СУБД включают:

  1. создание, удаление, изменение базы данных (БД);
  2. добавление, изменение, удаление, назначение прав пользователя;
  3. внесение, удаление и изменение данных в БД (таблиц и записей);
  4. выборку данных из БД.

К первым двум функциям имеют доступ только администраторы СУБД или привилегированные пользователи. Рассмотрим, как решаются последние две задачи (на самом деле это семь задач).

Прежде чем что-либо делать с данными, нужно создать таблицы, в которых эти данные будут храниться, научиться изменять структуру этих таблиц и удалять их, если потребуется. Для этого в языке SQL существуют операторы CREATE TABLE , ALTER TABLE и DROP TABLE .

Оператор CREATE TABLE

mysql>CREATE TABLE Persons (id INT PRIMARY KEY AUTO_INCREMENT, first_name VARCHAR(50), last_name VARCHAR(100), death_date INT, description TEXT, photo INT, citienship CHAR(50) DEFAULT "Russia"); Пример 10.1. Создание таблицы Persons

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

Показать все базы данных :

mysql>SHOW databases;

Сделать текущей базу данных book и показать все таблицы в ней:

mysql>use book; mysql>show tables;

Показать все столбцы в таблице Persons :

mysql> show columns from Persons;

Оператор DROP TABLE

Оператор DROP TABLE удаляет одну или несколько таблиц. Все табличные данные и определения удаляются, так что при работе с этой командой следует соблюдать осторожность.

Синтаксис:

DROP TABLE имя_таблицы [, имя_таблицы,...]

В версии MySQL 3.22 и более поздних можно использовать ключевые слова IF EXISTS , чтобы предупредить ошибку, если указанные таблицы не существуют.

Опции RESTRICT и CASCADE позволяют упростить перенос программы с других СУБД . В данный момент они не задействованы.

mysql> DROP TABLE IF EXISTS Persons, Artifacts, test; Пример 10.2. Использование оператора DROP TABLE

Оператор ALTER TABLE

Оператор ALTER TABLE обеспечивает возможность изменять структуру существующей таблицы. Например, можно добавлять или удалять столбцы, создавать или уничтожать индексы или переименовывать столбцы либо саму таблицу. Можно также изменять комментарий для таблицы и ее тип.

Синтаксис:

ALTER TABLE имя_таблицы alter_specification [, alter_specification ...]

Можно производить следующие изменения в таблице (все они записываются в alter_specification ):

  • добавление поля:

    ADD определение_столбца

    ADD (определение_столбца, определение_столбца,...)

  • добавление индексов:

    ADD INDEX [имя_индекса] (имя_индексируемого_столбца,...) или ADD PRIMARY KEY (имя_индексируемого_столбца,...) или ADD UNIQUE [имя_индекса] (имя_индексируемого_столбца,...) или ADD FULLTEXT [имя_индекса] (имя_индексируемого_столбца,...)

  • изменение поля:

    ALTER имя_столбца {SET DEFAULT literal | DROP DEFAULT} или CHANGE старое_имя_столбца определение_столбца или MODIFY определение_столбца

  • удаление поля, индекса, ключа:

    DROP имя_столбца DROP PRIMARY KEY DROP INDEX имя_индекса

  • переименование таблицы:

    RENAME новое_имя_таблицы

  • переупорядочение полей таблицы:

    ORDER BY поле

    опции_таблицы

Если оператор ALTER TABLE используется для изменения определения типа столбца, но DESCRIBE имя_таблицы показывает, что столбец не изменился, то, возможно, MySQL игнорирует данную модификацию по одной из причин, описанных в специальном разделе документации. Например, при попытке изменить столбец VARCHAR на CHAR MySQL будет продолжать использовать VARCHAR , если данная таблица содержит другие столбцы с переменной длиной.

Оператор ALTER TABLE во время работы создает временную копию исходной таблицы. Требуемое изменение выполняется на копии, затем исходная таблица удаляется, а новая переименовывается. Это делается для того, чтобы в новую таблицу автоматически попадали все обновления, кроме неудавшихся. Во время выполнения ALTER TABLE исходная таблица доступна для чтения другими клиентами. Операции обновления и записи в этой таблице приостанавливаются, пока не будет готова новая таблица. Следует отметить, что при использовании любой другой опции для ALTER TABLE , кроме RENAME , MySQL всегда будет создавать временную таблицу, даже если данные, строго говоря, и не нуждаются в копировании (например, при изменении имени столбца).

Пример10.3 . Добавим в созданную таблицу Persons поле для записи года рождения человека:

mysql> ALTER TABLE Persons ADD bday INTEGER AFTER last_name; Пример 10.3. Добавление в таблицу Persons поля для записи года рождения человека

Итак, мы научились работать с таблицами: создавать, удалять и изменять их. Теперь разберемся, как делать то же самое с данными, которые в этих таблицах хранятся.

Оператор SELECT

Оператор SELECT применяется для извлечения строк, выбранных из одной или нескольких таблиц. То есть с его помощью мы задаем столбцы или выражения, которые надо извлечь (select_выражения ), таблицы (table_references ), из которых должна производиться выборка, и, возможно, условие (where_definition ), которому должны соответствовать данные в этих столбцах, и порядок, в котором эти данные нужно выдать.

Кроме того, оператор SELECT можно использовать для извлечения строк, вычисленных без ссылки на какую-либо таблицу. Например, чтобы вычислить, чему равно 2*2 , нужно просто написать

mysql> SELECT 2*2;

Упрощенно структуру оператора SELECT можно представить следующим образом:

Квадратные скобки означают, что использование находящегося в них оператора необязательно, вертикальная черта | означает перечисление возможных вариантов. После ключевого слова ORDER BY указывают имя столбца, число (целое беззнаковое) или формулу и способ упорядочения (по возрастанию – ASC , или по убыванию – DESC ). По умолчанию используется упорядочение по возрастанию.

Когда в select_выражении мы пишем «* », это значит выбрать все столбцы. Кроме «* » в select_выражения могут использоваться функции типа max , min и avg .

Пример 10.4 . Выбрать из таблицы Persons все данные, для которых поле first_name имеет значение "Александр" :

Выбрать название и описание (title , description ) артефакта под номером 10:

Оператор INSERT

Оператор INSERT вставляет новые строки в существующую таблицу. Оператор имеет несколько форм. Параметр имя_таблицы во всех этих формах задает таблицу, в которую должны быть внесены строки. Столбцы, для которых задаются значения, указываются в списке имен столбцов (имя_столбца ) или в части SET .

Синтаксис:

    INSERT имя_таблицы [(имя_столбца,...)] VALUES (выражение,...),(...),...

    Эта форма команды INSERT вставляет строки в соответствии с точно указанными в команде значениями. В скобках после имени таблицы перечисляются столбцы, а после ключевого слова VALUES – их значения.

    Например:

    mysql> INSERT INTO Persons (last_name, bday) VALUES ("Иванов", "1934");

    вставит в таблицу Persons строку, в которой значения фамилии (last_name ) и даты рождения (bday ) будут заданы соответственно как «Иванов» и «1934».

    INSERT имя_таблицы [(имя_столбца,...)] SELECT ...

    Эта форма команды INSERT вставляет строки, выбранные из другой таблицы или таблиц.

    Например:

    вставит в таблицу Artifacts в поле «автор» (author ) значение идентификатора, выбранного из таблицы Persons по условию, что фамилия человека Иванов.

    INSERT имя_таблицы SET имя_столбца=выражение, имя_столбца=выражение, ...

    Например:

    mysql> INSERT INTO Persons SET last_name="Петров", first_name="Иван";

    Эта команда вставит в таблицу Persons в поле last_name значение «Петров», а в поле first_name – строку «Иван».

Форма INSERT ... VALUES со списком из нескольких значений поддерживается в версии MySQL 3.22.5 и более поздних. Синтаксис выражения имя_столбца=выражение поддерживается в версии MySQL 3.22.10 и более поздних.

Действуют следующие соглашения.

  • Если не указан список столбцов для INSERT ... VALUES или INSERT ... SELECT , то величины для всех столбцов должны быть определены в списке VALUES() или в результате работы SELECT . Если порядок столбцов в таблице неизвестен, для его получения можно использовать DESCRIBE имя_таблицы .
  • Любой столбец, для которого явно не указано значение, будет установлен в свое значение по умолчанию. Например, если в заданном списке столбцов не указаны все столбцы в данной таблице, то не упомянутые столбцы устанавливаются в свои значения по умолчанию.
  • Выражение expression может относиться к любому столбцу, который ранее был внесен в список значений. Например, можно указать следующее:

    mysql> INSERT INTO имя_таблицы (col1,col2) VALUES(15,col1*2);

    Но нельзя указать:

    mysql> INSERT INTO имя_таблицы (col1,col2) VALUES(col2*2,15);

Мы еще не обсудили три необязательных параметра, присутствующих во всех трех формах команды: LOW_PRIORITY , DELAYED и IGNORE .

Параметры LOW_PRIORITY и DELAYED используются, когда с таблицей работает большое число пользователей. Они предписывают устанавливать приоритет данной операции перед операциями других пользователей. Если указывается ключевое слово LOW_PRIORITY , то выполнение данной команды INSERT будет задержано до тех пор, пока другие клиенты не завершат чтение этой таблицы. В этом случае клиент должен ожидать, пока данная команда вставки не будет завершена, что в случае интенсивного использования таблицы может потребовать значительного времени. В противоположность этому команда INSERT DELAYED позволяет данному клиенту продолжать операцию сразу же, независимо от других пользователей.

Если в команде INSERT указывается ключевое слово IGNORE , то все строки, имеющие дублирующиеся ключи PRIMARY или UNIQUE в этой таблице, будут проигнорированы и не внесены в таблицу. Если не указывать IGNORE , то данная операция вставки прекращается при обнаружении строки, имеющей дублирующееся значение существующего ключа.

Оператор UPDATE

Синтаксис:

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

Если указывается ключевое слово LOW_PRIORITY , то выполнение данной команды UPDATE задерживается до тех пор, пока другие клиенты не завершат чтение этой таблицы.

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

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

mysql> UPDATE Persons SET death_date=death_date+1;

В версии MySQL 3.23 можно использовать параметр LIMIT # , чтобы убедиться, что было изменено только заданное количество строк.

Например, такая операция заменит в первой строке нашей таблицы экспонатов название title на строку «Ламповая ЭВМ»:

mysql> UPDATE Artifacts SET title="Ламповая ЭВМ" Limit 1;

Оператор DELETE

Оператор DELETE удаляет из таблицы имя_таблицы строки, удовлетворяющие заданным в where_definition условиям, и возвращает число удаленных записей.

Если оператор DELETE запускается без определения WHERE , то удаляются все строки.

Синтаксис:

Например, следующая команда удалит из таблицы Persons

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

SELECT * FROM Staff WHERE department

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

ВЫБРАТЬ ВСЕ из Staff ГДЕ clwjiertme"

Вполне понятная команда, жаль только записывается она исключительно на английском. В результате выполнения такого запроса СУБД вернет все записи из таблицы Staff, в которых поле depart* Mit_id равно трем. В нашем примере дан­ный запрос фактически выбирает только программистов из всей базы сотрудников.

Если вы раньше не работали с СУБД, то у вас может возникнуть резонный во­прос: где и как можно выполнить данный запрос? Существует три способа выпол­нения SQL-запросов.

1. Интерактивная среда взаимодействия с СУБД. Для большинства серверов СУБД существуют программы-клиенты (встроенные или поставляемые третьими лицами), в рабочей среде которых можно писать SQL-запросы, вы­полнять их и получать результат. Обычно такие средства используются ад­министраторами баз данных и к РНР-программированию прямого отноше­ния не имеют. Примером клиентской программы для работы с MySQL может послужить программа MySQL Administrator (http: /www.mysgl.coin/ product-s/administratoT/) или очень популярная РНР-система phpMyAdmin (http: / /www. phpmyadi’ln. r»et/itumm jiage/index. php). Для начала работы будет достаточно уже установленного дистрибутива, который имеет консоль­ный интерфейс. В Linux необходимо из командной строки набрать команду mysql, чтобы открылось окно с приглашением для ввода SQL-запросов, а в Windows для запуска того же интерфейса нужно запустить файл mysql. ехе из каталога bin.

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

3. Динамические SQL-запросы. К данному виду относятся такие запросы, i рые при написании приложения не могут быть определены полностью. i» пример, при написании программы для получения списка сотруднике» mt разным подразделениям предприятия программисту не известно, ci"> о в компании будет подразделений и какие сотрудники будут в них входи i„. Конечно, эти данные можно прописать в программе жестко, но при перво же изменении в структуре компании программу можно будет выбросить ил, потребуется переписать. Динамические запросы позволяют создавать поо-граммы, гибкие к изменениям данных. В РНР такие запросы выполняются практически теми же функциями, что и статические, только в них г’»’щег’^в’> ет возможность передавать некоторые параметры.

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

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

1. Определение структуры базы данных. К этому типу относятся запросы, с помощью которых создаются и модифицируются таблицы и индексы. Обыч­но это команды CRE; "Е ТА’ LE, ALI’R ТА’ LE, ‘ ” ’.ТЕ INDEX И др.

2. Манипуляция данными. К этому типу относятся запросы на вставку (дв1*и> ление), удаление или изменение данных в таблицах. Это три основные ко­манды: INSERT. DELETE И UPDATE.

3. Выборка данных Сюда входит только одна команда SELECT. Она не вносит изменения в сами данные, но позволяет получать их из базы. Несмотря на то что для выборки данных используется только одна команда, она имеет очень большие возможности и используется в приложениях очень часто.

4. Управление сервером СУБД. К этому типу в основном относятся запросы для управления пользователями и их правами доступа (например, команда GRANT).

Хорошее знание SQL очень облегчает труд программиста при работе с БД. При­ложения могут быть небольшими, но иметь большой функционал только за счет того, что много задач на себя возьмет SQL.

Как и в любой другой сфере IT, в SQL существуют стандарты — это ANSI SQL. Аббревиатура ANSI расшифровывается как Amrican National Standards Institute (Американский национальный институт стандартов). Однако не в последнюю оче­редь из-за различия в функционале самих СУБД реализации SQL для различных

СУБД все же отличаются друг от друга. На данный момент практически каждая СУБД имеет свой диалект, который обычно не сильно отличается от общего стан­дарта, но имеет свои особенности. Например, с Oracle и PostgreSQL совместим язык PL/SQL, а для работы с MS SQL Server используется T-SQL.

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

PHP и базы данных

Средства эффективного хранения и выборки больших объемов информации внесли огромный вклад в успешное развитие Интернета. Обычно для хранения информации используются базы данных. Работа таких известных сайтов, как Yahoo, Amazon и Ebay, в значительной степени зависит от надежности баз данных, хранящих громадные объемы информации. Конечно, поддержка баз данных ориентирована не только на интересы гигантских корпораций -- в распоряжении web-программистов имеется несколько мощных реализаций баз данных, распространяемых по относительно низкой цене (а то и бесплатно).

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

Глава начинается с подробного описания выборки и обновления данных в MySQL -- вероятно, самой популярной СУБД, используемой в PHP (http://www.mysql.com). На примере MySQL будет показано, как в PHP происходят загрузка и обновление данных в базе; мы рассмотрим базовые средства поиска и сортировки, используемые во многих web-приложениях. Затем мы перейдем к реализованной в PHP поддержке ODBC (Open Data Base Connectivity) -- обобщенного интерфейса, который может использоваться для одновременного соединения с разными СУБД. Поддержка ODBC в PHP будет продемонстрирована на примере соединения и выборки данных из базы данных Microsoft Access. Глава завершается проектом, в котором PHP и СУБД MySQL используются для создания иерархического каталога с информацией об избранных сайтах. При включении в каталог новых сайтов пользователь относит их к одной из стандартных категорий, определяемых администратором сайта.

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

SQL обычно описывается как стандартный язык, используемый для взаимодействия с реляционными базами данных (см. ниже). Однако SQL не является языком программирования, как С, C++ или PHP. Скорее, это интерфейсное средство для выполнения различных операций с базами данных, предоставляющее в распоряжение пользователя стандартный набор команд. Возможности SQL не ограничиваются выборкой данных из базы. В SQL поддерживаются разнообразные возможности для взаимодействия с базой данных, в том числе:

  • определение структуры данных -- определение конструкций, используемых при хранении данных;
  • выборка данных -- загрузка данных из базы и их представление в формате, удобном для вывода;
  • обработка данных -- вставка, обновление и удаление информации;
  • контроль доступа -- возможность разрешения/запрета выборки, вставки, обновления и удаления данных на уровне отдельных пользователей;
  • контроль целостности данных -- сохранение структуры данных при возникновении таких проблем, как параллельные обновления или системные сбои.

Обратите внимание: в определении SQL было сказано, что этот язык предназначен для работы с реляционными базами данных. В реляционных СУБД данные организуются в виде набора взаимосвязанных таблиц. Связи между таблицами реализуются в виде ссылок на данные других таблиц. Таблицу можно представить себе как двухмерный массив, в котором расположение каждого элемента характеризуется определенными значениями строки и столбца. Пример реляционной базы данных изображен на рис. 11.1.

Рис. 11.1. Пример реляционной базы данных

Как видно из рис. 11.1, каждая таблица состоит из строк (записей) и столбцов (полей). Каждому полю присваивается уникальное (в рамках данной таблицы) имя. Обратите внимание на связь между таблицами customer и orders, обозначенную стрелкой. В информацию о заказе включается короткий идентификатор клиента, что позволяет избежать избыточного хранения имени и прочих реквизитов клиента. В изображенной базе данных существует еще одна связь -- между таблицами orders и products. Эта связь устанавливается по полю prod_id, в котором хранится идентификатор товара, заказанного данным клиентом (определяемого полем custjd). Наличие этих связей позволяет легко ссылаться на полные данные клиента и товара по простым идентификаторам. Правильно организованная база данных превращается в мощное средство организации и эффективного хранения данных с минимальной избыточностью. Запомните эту базу данных, я буду часто ссылаться на нее в дальнейших примерах.

Итак, как же выполняются операции с реляционными базами данных? Для этого в SQL существует специальный набор общих команд -- таких, как SELECT, INSERT, UPDATE и DELETE. Например, если вам потребуется получить адрес электронной почты клиента с идентификатором 2001cu (см. рис. 11.1), достаточно выполнить следующую команду SQL:

SELECT cust_email FROM customers WHERE custjd = "2001cu"

Все вполне логично, не правда ли? В обобщенном виде команда выглядит так:

SELECT имя_поля FROM имя_таблицы [ WHERE условие ]

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

SELECT cust_email FROM customers

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

INSERT into products VALUES ("1009pr", "Red Tomatoes", "1.43");

Если позднее эти данные потребуется удалить, воспользуйтесь следующей командой:

DELETE FROM products WHERE prod_id = 1009r";

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

Записывать команды SQL символами верхнего регистра необязательно. Впрочем, я предпочитаю именно такую запись, поскольку она помогает различать компоненты запроса.

Раз вы читаете эту книгу, вероятно, вас интересует вопрос, как же организуется работа с базами данных в среде Web? Как правило, сначала при помощи какого-

либо интерфейсного языка (PHP, Java или Perl) создается соединение с базой данных, после чего программа обращается к базе с запросами, используя стандартный набор средств. Интерфейсный язык можно рассматривать как своего рода «клей», связывающий базу данных с Web. Я перехожу к своему любимому интерфейсному языку -- PHP.

В этой главе…

  • Что такое SQL
  • Заблуждения, связанные с SQL
  • Взгляд на разные стандарты SQL
  • Знакомство со стандартными командами и зарезервированными словами SQL
  • Представление чисел, символов, дат, времени и других типов данных
  • Неопределенные значения и ограничения
  • Использование SQL в системе клиент/сервер
  • SQL в сети

SQL - это гибкий язык, который можно использовать самыми разными способами. Он является самым распространенным инструментом, используемым для связи с реляционной базой данных. В этой главе я объясню, чем является SQL и чем он не является, в частности, чем SQL отличается от компьютерных языков других типов. Затем вы познакомитесь с командами и типами данных, которые поддерживает стандартный SQL. Кроме того, я объясню такие основные понятия, как неопределенные значения и ограничения . И, наконец, будет дан обзор того, как SQL вписывается в среду клиент/сервер, а также в Internet и интранет-сети организаций.

Чем является SQL и чем он не является

Первое, что надо уяснить насчет SQL, - этот язык не является процедурным , как FORTRAN, Basic, С, COBOL, Pascal и Java. Чтобы решить задачу с помощью одного из этих процедурных языков, приходится писать процедуру, которая выполняет одну за другой указанные операции, пока выполнение задачи не будет закончено. Процедура может быть линейной последовательностью или содержать ветвление, но в любом случае программист указывает порядок выполнения.

Иными словами, SQL является непроцедурным языком. Чтобы с его помощью решить задачу, сообщите SQL, что именно вам нужно, как если бы вы говорили с джином из лампы Аладдина. И при этом не надо говорить, каким образом получить для вас то, что вы хотите. Система управления базами данных (СУБД) сама решит, как лучше всего выполнить ваш запрос.

Хорошо. Только что я сказал, что SQL не является процедурным языком. В сущности, это правда. Однако миллионы программистов вокруг (и вы, возможно, один из них) привыкли решать задачи процедурным путем, поэтому в последние годы оказывалось немалое давление, чтобы дополнить SQL некоторыми процедурными возможностями. Поэтому теперь в составе новой версии спецификации SQL, SQL:2003, имеются такие средства процедурного языка, как блоки BEGIN, условные операторы IF, функции и процедуры. Благодаря этим новым средствам, можно хранить программы на сервере с тем, чтобы их могли повторно использовать многие пользователи.

Для иллюстрации того, что я имел в виду, когда говорил "сообщите системе, что именно вам нужно", предположим, что у вас имеется таблица EMPLOYEE с данными о служащих и вы хотите выбрать из нее все строки, соответствующие всем "старшим" работникам. Под "старшими" работниками можно подразумевать каждого, кто старше 40 лет или кто получает более 60000 долларов в год. Нужную вам выборку можно сделать с помощью следующего запроса:

SELECT * FROM EMPLOYEE WHERE AGE >40 OR SALARY >60000;

Этот оператор выбирает из таблицы EMPLOYEE все строки, в которых или значение столбца AGE (возраст) больше 40 или значение в столбце SALARY (зарплата) больше 60000. SQL сам знает, каким образом надо выбирать информацию. Ядро базы данных проверяет базу и принимает для себя решение, каким образом следует выполнять запрос. Все, что от вас требуется, - указать, какие данные вам нужны.

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

В современных реализациях SQL отсутствуют многие простые программные конструкции, которые являются фундаментальными для большинства других языков. В приложениях для повседневной жизни, как правило, требуются хотя бы некоторые из этих конструкций, поэтому SQL на самом деле представляет собой подъязык данных. Даже имея дополнения, появившиеся в SQL вместе со стандартом SQL: 1999 и дополнительные расширения, добавленные в SQL:2003, все равно для создания законченного приложения необходимо использовать вместе с SQL один из программных языков, такой, например, как С.

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

  • С помощью однократного непрограммируемого запроса с консоли компьютера, вводя команду SQL и читая на экране результаты ее выполнения. Консоль - это традиционный термин, означающий компьютерное оборудование, которое выполняет работу клавиатуры и экрана, применяемых в современных ПК. Запросы с консоли пригодны тогда, когда требуется быстрый ответ на конкретный запрос. Для удовлетворения какой-либо текущей потребности вам могут потребоваться такие данные из базы, которые до этого никогда не требовались. Возможно, они вам никогда больше не понадобятся, но сейчас они нужны. Введите с клавиатуры соответствующий SQL-запрос, и через некоторое время на вашем экране появится результат.
  • С помощью программы, которая извлекает из базы данных информацию, а затем создает на основе этих данных отчет, выводимый или на экран, или на печать . Язык SQL можно использовать и так. Сложный запрос SQL, который, возможно, еще пригодится в будущем, можно поместить прямо в программу. Это позволяет многократно использовать его в дальнейшем. Таким образом, формулировка запроса выполняется один раз. Как вставлять код SQL в программы, написанные на другом языке, рассказывается в главе 15.

Язык программирования

SQL (Structured Query Language — Структурированный язык запросов) — язык управления базами данных для реляционных баз данных. Сам по себе SQL не является Тьюринг-полным языком программирования, но его стандарт позволяет создавать для него процедурные расширения, которые расширяют его функциональность до полноценного языка программирования.

Язык был создан в 1970х годах под названием “SEQUEL” для системы управления базами данных (СУБД) System R. Позднее он был переименован в “SQL” во избежание конфликта торговых марок. В 1979 году SQL был впервые опубликован в виде коммерческого продукта Oracle V2.

Первый официальный стандарт языка был принят ANSI в 1986 году и ISO — в 1987. С тех пор были созданы еще несколько версий стандарта, некоторые из них повторяли предыдущие с незначительными вариациями, другие принимали новые существенные черты.

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

SQL создавался как простой стандартизированный способ извлечения и управления данными, содержащимися в реляционной базе данных. Позднее он стал сложнее, чем задумывался, и превратился в инструмент разработчика, а не конечного пользователя. В настоящее время SQL (по большей части в реализации Oracle) остается самым популярным из языков управления базами данных, хотя и существует ряд альтернатив.

SQL состоит из четырех отдельных частей:

  1. язык определения данных (DDL) используется для определения структур данных, хранящихся в базе данных. Операторы DDL позволяют создавать, изменять и удалять отдельные объекты в БД. Допустимые типы объектов зависят от используемой СУБД и обычно включают базы данных, пользователей, таблицы и ряд более мелких вспомогательных объектов, например, роли и индексы.
  2. язык манипуляции данными (DML) используется для извлечения и изменения данных в БД. Операторы DML позволяют извлекать, вставлять, изменять и удалять данные в таблицах. Иногда операторы select извлечения данных не рассматриваются как часть DML, поскольку они не изменяют состояние данных. Все операторы DML носят декларативный характер.
  3. язык определения доступа к данным (DCL) используется для контроля доступа к данным в БД. Операторы DCL применяются к привилегиям и позволяют выдавать и отбирать права на применение определенных операторов DDL и DML к определенным объектам БД.
  4. язык управления транзакциями (TCL) используется для контроля обработки транзакций в БД. Обычно операторы TCL включают commit для подтверждения изменений, сделанных в ходе транзакции, rollback для их отмены и savepoint для разбиения транзакции на несколько меньших частей.

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

Примеры:

Hello, World!:

Пример для версий Oracle 10g SQL , Oracle 11g SQL

Строка ‘Hello, World!’ выбирается из встроенной таблицы dual , используемой для запросов, не требующих обращения к настоящим таблицам.

select "Hello, World!" from dual ;

Факториал:

Пример для версий Oracle 10g SQL , Oracle 11g SQL

SQL не поддерживает циклы, рекурсии или пользовательские функции. Данный пример демонстрирует возможный обходной путь, использующий:

  • псевдостолбец level для создания псевдотаблиц t1 и t2 , содержащих числа от 1 до 16,
  • агрегатную функцию sum , позволяющую суммировать элементы множества без явного использования цикла,
  • и математические функции ln и exp , позволяющие заменить произведение (необходимое для вычисления факториала) на сумму (предоставляемую SQL).

Строка “0! = 1” не войдет в набор строк, полученный в результате, т.к. попытка вычислить ln(0) приводит к исключению.

Числа Фибоначчи:

Пример для версий Oracle 10g SQL , Oracle 11g SQL

SQL не поддерживает циклы или рекурсии, кроме того, конкатенация полей из разных строк таблицы или запроса не является стандартной агрегатной функцией. Данный пример использует:

  • формулу Бине и математические функции ROUND , POWER и SQRT для вычисления n-ого числа Фибоначчи;
  • псевдостолбец level для создания псевдотаблицы t1, содержащей числа от 1 до 16;
  • встроенную функцию SYS_CONNECT_BY_PATH для упорядоченной конкатенации полученных чисел.

SELECT REPLACE (MAX (SYS_CONNECT_BY_PATH (fib || ", " , "/" )), "/" , "" ) || "..." fiblist FROM ( SELECT n , fib , ROW_NUMBER () OVER (ORDER BY n ) r FROM (select n , round ((power ((1 + sqrt (5 )) * 0 . 5 , n ) - power ((1 - sqrt (5 )) * 0 . 5 , n )) / sqrt (5 )) fib from (select level n from dual connect by level <= 16 ) t1 ) t2 ) START WITH r = 1 CONNECT BY PRIOR r = r - 1 ;

Hello, World!:

Пример для версий Microsoft SQL Server 2005 , Microsoft SQL Server 2008 R2 , Microsoft SQL Server 2012 , MySQL 5 , PostgreSQL 8.4 , PostgreSQL 9.1 , sqlite 3.7.3

select "Hello, World!" ;

Факториал:

Пример для версий Microsoft SQL Server 2005 , Microsoft SQL Server 2008 R2 , Microsoft SQL Server 2012

Используется рекурсивное определение факториала, реализованное через рекурсивный запрос. Каждая строка запроса содержит два числовых поля — n и n!, и каждая следующая строка вычисляется с использованием данных из предыдущей.

Можно вычислить целочисленные факториалы только до 20!. При попытке вычислить 21! возникает ошибка “Arithmetic overflow error”, т.е. происходит переполнение разрядной сетки.

Для вещественных чисел вычисляется факториал 100! (Для этого в примере необходимо заменить bigint на float в 3-ей строке)

Числа Фибоначчи:

Пример для версий Microsoft SQL Server 2005 , Microsoft SQL Server 2008 R2 , Microsoft SQL Server 2012

Используется итеративное определение чисел Фибоначчи, реализованное через рекурсивный запрос. Каждая строка запроса содержит два соседних числа последовательности, и следующая строка вычисляется как (последнее число, сумма чисел) предыдущей строки. Таким образом все числа, кроме первого и последнего, встречаются дважды, поэтому в результат входят только первые числа каждой строки.

Факториал:

Пример для версий Oracle 10g SQL , Oracle 11g SQL

Этот пример демонстрирует использование оператора model , доступного начиная с версии Oracle 10g и позволяющего обработку строк запроса как элементов массива. Каждая строка содержит два поля — номер строки n и его факториал f.

select n || "! = " || f factorial from dual model return all rows dimension by ( 0 d ) measures ( 0 f , 1 n ) rules iterate (17 ) ( f [ iteration_number ] = decode (iteration_number , 0 , 1 , f [ iteration_number - 1 ] * iteration_number ), n [ iteration_number ] = iteration_number );

Числа Фибоначчи:

Пример для версий Oracle 10g SQL , Oracle 11g SQL

Этот пример демонстрирует использование оператора model , доступного начиная с версии Oracle 10g и позволяющего обработку строк запроса как элементов массива. Каждая строка содержит два поля — само число Фибоначчи и конкатенация всех чисел, меньше или равных ему. Итеративная конкатенация чисел в том же запросе, в котором они генерируются, выполняется проще и быстрее, чем агрегация как отдельное действие.

select max (s ) || ", ..." from (select s from dual model return all rows dimension by ( 0 d ) measures ( cast (" " as varchar2 (200 )) s , 0 f ) rules iterate (16 ) ( f [ iteration_number ] = decode (iteration_number , 0 , 1 , 1 , 1 , f [ iteration_number - 1 ] + f [ iteration_number - 2 ]), s [ iteration_number ] = decode (iteration_number , 0 , to_char (f [ iteration_number ]), s [ iteration_number - 1 ] || ", " || to_char (f [ iteration_number ])) ) );

Факториал:

Пример для версий MySQL 5

select concat (cast (t2 . n as char ), "! = " , cast (exp (sum (log (t1 . n ))) as char )) from ( select @ i : = @ i + 1 AS n from TABLE , (select @ i : = 0 ) as sel1 limit 16 ) t1 , ( select @ j : = @ j + 1 AS n from TABLE , (select @ j : = 0 ) as sel1 limit 16 ) t2 where t1 . n <= t2 . n group by t2 . n

Числа Фибоначчи:

Пример для версий MySQL 5

Замените TABLE на любую таблицу, к которой есть доступ, например, mysql.help_topic .

select concat (group_concat (f separator ", " ), ", ..." ) from (select @ f : = @ i + @ j as f , @ i : = @ j , @ j : = @ f from TABLE , (select @ i : = 1 , @ j : = 0 ) sel1 limit 16 ) t

Hello, World!:

Пример для версий Oracle 10g SQL , Oracle 11g SQL

В этом примере используется анонимный блок PL/SQL, который выводит сообщение в стандартный поток вывода с помощью пакета dbms_output .

begin dbms_output . put_line ("Hello, World!" ); end ;

Факториал:

Пример для версий Oracle 10g SQL , Oracle 11g SQL

Этот пример демонстрирует итеративное вычисление факториала средствами PL/SQL.

declare n number : = 0 ; f number : = 1 ; begin while (n <= 16 ) loop dbms_output . put_line (n || "! = " || f ); n : = n + 1 ; f : = f * n ; end loop ; end ;

Числа Фибоначчи:

Пример для версий Oracle 10g SQL , Oracle 11g SQL

Этот пример использует итеративное определение чисел Фибоначчи. Уже вычисленные числа хранятся в структуре данных varray — аналоге массива.

declare type vector is varray (16 ) of number ; fib vector : = vector (); i number ; s varchar2 (100 ); begin fib . extend (16 ); fib (1 ) : = 1 ; fib (2 ) : = 1 ; s : = fib (1 ) || ", " || fib (2 ) || ", " ; for i in 3 .. 16 loop fib (i ) : = fib (i - 1 ) + fib (i - 2 ); s : = s || fib (i ) || ", " ; end loop ; dbms_output . put_line (s || "..." ); end ;

Квадратное уравнение:

Пример для версий Oracle 10g SQL , Oracle 11g SQL

Этот пример тестировался в SQL*Plus, TOAD и PL/SQL Developer.

Чистый SQL позволяет вводить переменные в процессе исполнения запроса в виде заменяемых переменных. Для определения такой переменной ее имя (в данном случае A, B и C) следует использовать с амперсандом & перед ним каждый раз, когда нужно сослаться на эту переменную. Когда запрос выполняется, пользователь получает запрос на ввод значений всех заменяемых переменных, использованных в запросе. После ввода значений каждая ссылка на такую переменную заменяется на ее значение, и полученный запрос выполняется.

Существует несколько способов ввести значения для заменяемых переменных. В данном примере первая ссылка на каждую переменную предваряется не одинарным, а двойным амперсандом && . Таким образом значение для каждой переменной вводится только один раз, а все последующие ссылки на нее будут заменены тем же самым значением (при использовании одиночного амперсанда в SQL*Plus значение для каждой ссылки на одну и ту же переменную приходится вводить отдельно). В PL/SQL Developer ссылки на все переменные должны предваряться одиночным знаком & , иначе будет возникать ошибка ORA-01008 “Not all variables bound”.

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

Сам запрос состоит из четырех разных запросов. Каждый запрос возвращает строку, содержащую результат вычислений, в одном из случаев (A=0, D=0, D>0 и D<0) и ничего — в трех остальных случаях. Результаты всех четырех запросов объединяются, чтобы получить окончательный результат.

alter session set NLS_NUMERIC_CHARACTERS = ". " ; select "Not a quadratic equation." ans from dual where && A = 0 union select "x = " || to_char (-&& B / 2 /& A ) from dual where & A != 0 and & B *& B - 4 *& A *&& C = 0 union select "x1 = " || to_char ((-& B + sqrt (& B *& B - 4 *& A *& C )) / 2 /& A ) || ", x2 = " || to_char (-& B - sqrt (& B *& B - 4 *& A *& C )) / 2 /& A from dual where & A != 0 and & B *& B - 4 *& A *& C > 0 union select "x1 = (" || to_char (-& B / 2 /& A ) || "," || to_char (sqrt (-& B *& B + 4 *& A *& C ) / 2 /& A ) || "), " || "x2 = (" || to_char (-& B / 2 /& A ) || "," || to_char (- sqrt (-& B *& B + 4 *& A *& C ) / 2 /& A ) || ")" from dual where & A != 0 and & B *& B - 4 *& A *& C < 0 ;



В продолжение темы:
Android

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