C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  01.05.2010 — Update World C++: Сборник GPL QT исходников
  15.12.2007 — Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Хостинг:
Windows 2003, ASP.NET 2.0
бесплатный и от 80 руб./мес


   Отправить письмо
Кулабухов Артем, Беларусь




 SQL Структурированный Язык Запросов / Базы данных / Visual C++

SQL Структурированный Язык Запросов
Введение
Язык определения данных (DDL)
   Таблицы
    Типы данных SQL
    Создание таблицы
   Удаление таблицы
    Изменение существующей таблицы
    Индексы
   Представления
Язык управления данными DCL
    Присвоение прав
    Отмена Прав
Язык манипуляции данными DML
    Оператор SELECT
    Оператор WHERE
    Выражения
    Предикат LIKE
    Предикат IN
    Предикат BETWEEN
    Ключевое слово DISTINCT
    Оператор ORDER BY
    Операции, выполняемые над совокупностью данных
    Значения литералов ODBC SQL
    Функции SQL
        Строковые функции
        Числовые функции
        Системные функции
    Преобразование типов данных
    Объединения
    Внешние объединения
    Вложенные запросы
    Объединенные запросы
    Оператор INSERT
    Оператор DELETE
    Оператор UPDATE

Введение
    Все интерфейсы баз данных позволяют использовать SQL. В этом
разделе рассмотрен синтаксис SQL ,пригодный для ODBC и других
интерфейсов, синтаксис для ODBC основан на стандарте ANSI SQL-92.
    Заметим, что почти каждая СУБД использует свой собственный
диалект SQL, синтаксис которого может слегка отличаться.Каждый
диалект может поддерживать различный набор свойств, поэтому
приведенный здесь синтаксис может оказаться неработоспособным
в вашей любимой СУБД. Однако драйвер ODBC для конкретной
базы данных обеспечит необходимый перевод общего SQL на
специфический диалект, используемый вашей СУБД.
    Далее рассмотрим три основные группы операторов SQL. Язык
определения данных DDL(data definition language) - служит для задания
структуры базы данных, язык управления данными DCL (data control
language) - для работы с правами пользователя на конкретные объекты.
И  язык манипуляции данными DML(data manipulation language)- для
выполнения остальных операций, включая добавление и модификацию
данных, а так же выполнения запросов.Все эти языки являются частями
SQL , а не отдельными языками, хотя в большинстве приложений ,
используются лишь операторы , относящиеся  к одной из этих трех групп.

Язык определения данных (DDL)
Язык определения данных DDL(data definition language)  используется для
определения структуры базы данных (БД) и создания ее объектов. В DDL
для работы с объектами БД используются следующие три оператора SQL:

    CREATE - создает новый объект.
    ALTER  - модифицирует существующий объект.
    DROP  - удаляет объект.

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

Таблицы

Таблицы - основной объект в реляционных БД.Реальные данные
содержатся в таблицах, состоящих из строк (записей) и столбцов (полей).
Во многих пользовательских приложений используемые таблицы, как
правило , уже созданы заранее, но иногда вам придется создавать
таблицы самостоятельно.

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

CHAR(n) - символьная строка из n символов фиксированной длины.
VARCHAR(n) - символьная строка переменной длины, не
    превышающей n символов.
LONG VARCHAR - символьная строка переменной неограниченной
    длинны.

    На базовом уровне подчиненности поддерживаются следующие
типы данных.

DECIMAL(p,s) или  NUMERIC( p,s) Эквивалентны между собой.
    Они определяют значение с плавающей точкой,состоящие из p
десятичных символов и s знаков после запятой.

SMALLINT - двухбайтовое целое.
INTEGER - четырехбайтовое целое.
REAL - четырехбайтовое значение с плавающей точкой.
FLOAT   или   DOUBLE  PRECISION - восьмибайтовое значение
    с плавающей точкой.

    На расширенном уровне подчиненности поддерживаются следующие
типы данных.

BIT - один бит.
TYNYINT - однобайтовое целое.
BIGINT - восьмибайтовое целое.
BYNARY(n) - двоичное поле фиксированной длины , состоящее из n байт
VARBINARY(n) - двоичное поле переменной  длины , не больше из n байт
LONG VARBINARY - двоичное поле переменной  неограниченной длины
DATE - значение даты.
TIME - значение времени.
TIMASTAMP - значение, содержащее время и дату.

Создание таблицы

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

CREATE TABLE имя-таблицы ({имя-столбца  тип-данных},...)

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

CREATE TABLE Employee (
                                EmpId          INTEGER,
                                EmpName  VARCHAR (50),
                                Salary    NUMERIC (6,2),
                                Dept   CHAR (10) )

В этом примере создается новая таблица с именем Employee .Эта таблица
будет содержать четыре столбца с различными типами данных .
Столбцы можно доопределить, добавив после типа данных столбца
дополнительные модификаторы.Чаще всего используется модификатор
NOT NULL который указывает на то, что значения для этого столбца
должны быть заданны.Например если Вы хотите, чтобы во всех строках
обязательно были заданы имя и номер сотрудника, необходимо
определить таблицу следующим образом.

CREATE TABLE Employee (
                                EmpId          INTEGER                NOT NULL,
                                EmpName  VARCHAR (50)     NOT NULL,
                                Salary    NUMERIC (6,2),
                                Dept   CHAR (10) )

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

CREATE TABLE Employee (
                                EmpId          INTEGER   UNIQUE,
                                EmpName  VARCHAR (50)   NOT NULL,
                                Salary    NUMERIC (6,2),
                                Dept   CHAR (10) )
Вы можете также задать для столбца используемое по умолчанию
значение, присваиваемое полю в новых строках, для которых это
значение не задается явно. Для этого служит модификатор DEFAULT.

CREATE TABLE Employee (
                                EmpId          INTEGER   UNIQUE,
                                EmpName  VARCHAR (50)   NOT NULL,
                                Salary    NUMERIC (6,2),
                                Dept   CHAR (10)    DEFAULT ‘Staff’)

В таблице из этого примера полю Dept во всех новых строках
присваивается значение 'Staff, если явно не задается никакое другое.
Конкретные СУБД могут поддерживать некоторые другие
модификаторы столбцов, которые дают воз-можность указать
главный ключ или задать ограничение целостности ссылок и могут
использоваться для того, чтобы гарантировать корректность данных
в пользовательских приложениях.

Удаление таблицы
Для удаления таблицы из базы данных используется команда
DROP TABLE: где  DROP TABLE имя таблицы
При этом удаляются все данные из таблицы, затем удаляется и сама
таблица. Из раздела "Операторы DELETE" ниже в этой главе вы узнаете,
как просто удалить данные из таблицы с использованием оператора
DELETE. В операторе удаления могут использоваться ключевые слова
CASCADE или RESTRICT. Если в операторе указано ключевое слово
CASCADE, то при удалении таблицы удаляются также все
представления или огра-ничения целостности, связанные с
этой таблицей. Вот пример:
DROP TABLE Employee CASCADE
Модификатор RESTRICT не позволяет удалить таблицу, если на нее
имеются ссылки в каких-либо представлениях или ограничениях
целостности. Например:
DROP TABLE Employee RESTRICT

Изменение существующей таблицы
Иногда приходится изменять структуру таблицы после се создания
и внесения данных. Изменение структуры существующих таблиц
поддерживается не всеми СУБД. При этом операция добавления
столбцов поддерживается чаще, чем операция удаления существующих
столбцов.
Для добавления столбцов используется оператор следующего вида:
ALTER TABLE имя таблицы ADD COLUMN имя столбца тип данных
В созданную ранее таблицу Employee можно добавить столбец с
номерами телефонов сотрудников. Сделать это можно с помощью
следующего оператора:

ALTER TABLE Employee ADD COLUMN Extension INTEGER

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

ALTER TABLE Employee DOROP COLUMN Extension

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

ALTER TABLE Employee DROP COLUMN Extension CASCADE

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

Индексы
Индексы — это объекты баз данных, обеспечивающие более
эффективный доступ к строкам таблицы. Индекс отслеживает строки
таблицы на основе значений определенного столбца или нескольких
столбцов. Использование индекса может значительно повысить
производительность базы данных при выполнении определенных
типов операций поиска, если этот индекс создан соответствующим
образом, с учетом наи-более часто встречающихся типов запросов.
Однако следует помнить, что для поддержания индексов тре-буется
большое количество динамической памяти. Если для одной таблицы
вы создадите много различных индексов, то производительность вашего
приложения существенно снизится.
Индексы создаются с использованием оператора CREATE INDEX,
имеющего следующий общий синтаксис:
CREATE [ UNIQUE ] INDEX имя индекса
ON имя таблицы (имя столбца (s)) [ASC, DESC]

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

CREATE UNIQUE INDEX MyEmpIdIndex ON Employee (EmpId)

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

CREATE INDEX MyNameDeptIndex ON Employee (EmpName, Dept)

Некоторые СУБД позволяют задавать порядок индексации.
Добавив модификатор ASC, можно созда-вать индексы в порядке
возрастания, а добавив модификатор DESC — в порядке убывания.
Изменить индекс невозможно, но это и не требуется. Вы можете
просто удалить индекс и создать но-вый, не теряя никаких данных.
Индекс удаляется с использованием следующего оператора:
DROP INDEX имя индекса

Представления
Представления таблиц (view), или просто представления, можно
рассматривать как вид виртуальной таблицы. С точки зрения
пользователей приложений, представление таблицы выглядит и
используется как обычная таблица. Однако в представлении хранятся
не его собственные данные, а только ссылки на дан-ные,
содержащиеся в таблицах. В целом представления используются
для отображения данных, содержа-щихся в таблицах, различными
способами, удобными для пользователя. Представления можно
использовать для отображения подмножества столбцов одной
или нескольких таблиц, соответствующих некоторому виду запроса.
Это позволяет представлять таблицу с нужными дан-ными, хотя в
действительности структура базы данных может быть иной,
сформированной исходя из со-ображений целостности или
производительности. Представления таблиц удобны для обеспечения
безопасности. Например, с помощью представления можно
обеспечить доступ пользователей к некоторому подмножеству
столбцов в таблице, оставляя защи-щенными другие столбцы.
Представления служат и для обеспечения логической независимости
данных, благодаря чему изменения. внесенные в реальные таблицы
базы данных, не отражаются на приложениях пользователя. Если
таблица в базе данных будет изменена, вы сможете просто настроить
представление в соответствии с новой структурой таблицы, и вам
не придется возвращаться и вносить изменения в каждое написанное
приложение.
Представления создаются с использованием операторов
CREATE VIEW. В следующем примере приведе-но представление,
которое просто отображает все столбцы таблицы.

CREATE VIEW MyView AS SELECT * FROM MyTable

Здесь представлению присваивается имя и добавляется оператор
SELECT, определяющий данные, со-ставляющие представление
таблицы. Можно также указать имена столбцов в представлении,
как это сде-лано в следующем примере, отображающем часть
таблицы Employee:

CREATE VIEW MyView (Id, Name) AS SELECT (EmpId, EmpName) FROM Employee

Вы можете создать представления, использующие гораздо более
сложные операторы выбора, включая объединения, в которых в
одном представлении используется комбинация данных из нескольких
различ-ных таблиц. Однако, поскольку в этой главе еще не
рассматривались более сложные операторы SELECT, мы не будем
углубляться в этом вопрос.
Существующие представления нельзя модифицировать, но вы всегда
сможете просто удалить одно представление и создать другое без
потери какой-либо информации. Представление таблицы удаляется
из базы данных с помощью следующего оператора:
DROP VIEW имя представления

Язык управления данными DCL
Если вы пишете приложения, работающие с файлами локальной
системы управления базами данных, та-кой как Microsoft Access,
то вам, вероятно, нс придется сталкиваться с проблемой защиты
отдельных объек-тов в базе данных. Даже если такая проблема и
возникнет, то вы не сможете ее решить, поскольку большинство
настольных СУБД не поддерживают этого уровня защиты. Однако,
если вы используете более мощные системы управления базами данных
на платформе клиент/сервер, то проблемы защиты отдельных объектов
в базе данных могут быть решены. Язык управления данными
DCL (Data Control Language) — это та часть языка SQL, которая
позволяет работать с правами пользователей на объекты в базе данных.
Присвоение прав
Язык SQL позволяет присвоить группе пользователей определенные
права на некоторый объект. Права могут быть следующими.

    SELECT  позволяет запрашивать данные.
    INSERT  позволяет добавлять новые строки.
    DELETE  позволяет удалять строки.
    UPDATE  позволяет изменять существующие строки.
    REFERENCES. Это право требуется в том случае, если пользователь
пытается модифицировать таблицу, имеющую ограничения целостности
ссылок, которые указывают на столбцы другой таблицы. Такой
пользователь должен иметь право REFERENCES на столбцы,
используемые с ограничениями.
Права на конкретный объект присваиваются оператором GRANT.
Например:

GRANT SELECT ON Employee TO PUBLIC

В этом примере используется ключевое слово PUBLIC для присвоения
всем пользователям права SELECT на таблицу Employee. Можно также
в одном операторе присвоить несколько прав нескольким пользователям,
как показано в следующей строке кода. Однако присвоить права на
несколько объектов с помощью одного оператора нельзя.

GRANT SELECT, INSERT ON Employee To Bob, Doug

Права UPDATE и REFERENCES могут распространяться на отдельные
столбцы. В следующем примере пользователям Bob и Doug разрешено
изменять только столбцы Salary и Dept.

GRANT UPDATE (Salary, Dept) ON Employee To Bob, Doug

Отмена Прав
Права на объекты БД можно отменить с помощью оператора REVOKE,
имеющего синтаксис аналогичный рассмотренному выше оператору
GRANT. Например ,если для присвоения прав исользуется оператор

GRANT SELECT ON Royalties TO ED,Alex,Michael,Dave

то отменить права пользователя на таблицу Royalties можно с помощью
следующей команды

REVOKE SELECT ON Royalties TO Dave

В операторе REVOKE можно использовать модификаторы CASCADE и
RESTRICT . Если Вы хотите отменть права пользователя на некоторую
таблицу, то имеет смысл отменить его права на все представления,
требующие доступа ко всей таблице. Сделать это можно с помощью
модификатора CASCADE. А вот модификатор RESTRICT не позволяет
отменить право  доступа, которое требуется согласно другим правам,
присвоенным этому пользователю.
 

Язык манипуляции данными DML
    В предыдущих разделах мы рассмотрели те части SQL, которые
используются для определения БД. Теперь самая главная часть.
DML включает в себя след основные типы операторов:

    SELECT
    INSERT
    DELETE
    UPDATE

далее подробно о каждом операторе.

Оператор SELECT
Оператор SELECT составляет основу SQL .Этот оператор
используется каждый раз при получении данных. Синтаксис очень
прост.Самая простая форма выглядит след образом:

SELECT список-выбора FROM имя-таблицы

Параметр  список-выбора может принимать несколько значений.
Самым простым является * , когда выбираются все столбцы
указанной таблицы. В следующем примере выбираются все
столбцы и строки из таблицы MyTable

SELECT * FROM MyTable

Можно выбирать отдельные поля таблицы, указав их названия
как показано в примере ниже.

SELECT  EmpId,  EmpName FROM MyTable

Кроме того , в списке параметров можно указать литералы-константы.
Эта возможность очень редко используется в С++ , но очень часто
применяется в утилитах генерации отчетов, когда для их оформления
добавляется постоянный текст.Например следующий оператор
возвращает значение ' _ _ _ _ _ _ ' ,как будто оно является значением
следующего поля.

SELECT  EmpId, '_ _ _ _ _ _ ',  EmpName FROM MyTable

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

Оператор WHERE
В рассмотренных примерах выбирались все строки таблицы. Если
использовать оператор WHERE, то можно ограничить множество
возвращаемых строк. Операторы WHERE могут содержать широкий
диапазон различных условных выражений, которые применяются для
выборки возвращаемых строк. Самые простые из этих выражений
используют операторы сравнения <, >, <=, >=, =, <>. Например,
следующий оператор получает все строки, в которых
идентификационный номер сотрудника равен 123:

SELECT * FROM Employee WHERE EmpId = 123

Можно также комбинировать несколько условий с использованием
логических операторов AND и OR, как в следующих примерах:

SELECT * FROM Employee WHERE Salary > 50000 AND Salary < 60000
SELECT * FROM Employee WHERE Dept = 'MIS' OR Dept » 'Sales'

Кроме того, вы можете включить в условие оператор отрицания NOT.
В следующем примере выбирают-ся все строки, в которых сотрудники
не включены в перечень "Human Resources":

SELECT * FROM Employee WHERE NOT Dept = 'HR'

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

SELECT * FROM Employee WHERE Dept <> 'HR'

Выражения
Вместо имен отдельных столбцов можно использовать числовые
выражения, в которых несколько столбцов комбинируются с помощью
арифметических операторов +, -, /, *. Выражения можно включать в
операторы SELECT.Например:

SELECT PartNum, PartCost + ExtraCost FROM Parts

Оператор WHERE также может содержать выражения, что показано в
следующем примере:

SELECT PartNum FROM Parts WHERE (ExtraCost / PartCost) > .25

Предикат LIKE
Кроме перечисленных операторов сравнения, в SQL присутствует
специальный оператор сравнения для символьных строк.
Предикат LIKE позволяет выбирать строки на основе строки,
соответствующей определенному шаблону. В шаблон могут быть
включены любые обычные символы, а также специальные
символы % и _ .Строку символов произвольной длины можно
поставить в соответствие шаблону %, а один сим-вол _ .
Например, для выбора всех строк, содержащих строку Database в
поле Title, можно использовать следующий запрос:

SELECT ChapterNum FROM Chapters WHERE Title LIKE '%Database%'

Можно также произвести поиск заголовков, в которых начиная со
второй позиции содержится строка ata:

SELECT ChapterNum FROM Chapters WHERE Title LIKE '_ata%'
 

Предикат IN
Для упрощения оператора WHERE используется и предикат IN,
который позволяет выбрать строки со значением, принадлежащим
определенному набору. Приведем пример такого запроса:

SELECT EmpNum FROM Employee
WHERE Dept = 'MIS' OR Dept » 'HR' OR Dept = 'Sales'

Этот запрос можно упростить с использованием предиката IN:

SELECT EmpNum FROM Employee WHERE Dept IN ('MIS, 'HR', 'Sales')

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

SELECT EmpNum FROM Employee WHERE Dept NOT IN ('MIS, 'HR', 'Sales')

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

SELECT EpmNum FROM Employee WHERE Salary > 20000 AND Salary < 30000

Этот запрос можно упростить за счет использования предиката BETWEEN:

SELECT EpmNum FROM Employee WHERE Salary BETWEEN 20000 AND 30000

Как и другие операторы сравнения, предикат BETWEEN можно применять
к столбцам с нечисловыми данными. Например:

SELECT EpmNum FROM Employee WHERE name BETWEEN 'Andersen' AND 'Baker'

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

Ключевое слово DISTINCT
Во многих задачах требуется найти все возможные значения
определенного поля на некотором множе-стве строк. Сделать это
можно с помощью ключевого слова DISTINCT, которое предотвращает
дублирова-ние элементов в возвращаемом множестве результатов.
В следующем примере возвращаются только непо-вторяющиеся
номера отделов из таблицы Employee:

SELECT DISTINCT Dept FROM Employe

Без использования ключевого слова DISTINCT были бы выбраны
все строки из таблицы Employee, а не только перечень отдельных
значений, используемых в столбце Dept.

Оператор ORDER BY
По умолчанию возвращаемые запросом строки представляются в
произвольном порядке. Если вы хоти-те определить некоторый
порядок возвращаемых строк, используйте оператор ORDER BY,
который позво-ляет указать один или несколько столбцов,
используемых для сортировки возвращаемых строк. Для каждого
столбца можно также указать модификатор ASC или DESC,
определяющий порядок возрастания или убывания при сортировке
строк по данному столбцу.
В следующем примере возвращаемые строки будут отсортированы
по возрастанию идентификационных номеров сотрудников:

SELECT EmpId FROM Employee ORDER BY EmpId ASC

Если в операторе ORDER BY указать несколько столбцов, то
возвращаемые строки сначала будут отсор-тированы по первому
столбцу. Затем строки, содержащие одинаковые значения в первом
поле, будут отсортированы еще и по второму столбцу. Например,
следующий оператор сортирует строки в порядке воз-растания
значений в столбце Salary, а строки с равными значениями в этом
поле - в порядке убывания идентификационных номеров EmpId:

SELECT EmpId, Salary FROM Employee ORDER BY Salary ASC, EmpId DESC

Операции, выполняемые над совокупностью данных
Зачастую приходится вычислять значения на основе данных из всех
возвращаемых строк, например общую сумму значений в некотором
столбце всех возвращаемых строк. Такие типы вычислений можно
выполнить с помощью следующих функций, выполняемых над
совокупностью данных (aggregate function).

AVG       возвращает среднее значение в столбце.
COUNT   вычисляет количество возвращаемых строк.
МАХ       возвращает максимальное значение для некоторого столбца
                 в результирующем множестве.
MIN       возвращает минимальное значение для некоторого столбца
                 в результирующем множестве.
SUM       вычисляет общую сумму всех значений для некоторого
                 столбца в результирующем множестве.

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

SELECT COUNT (*) FROM Employee

При использовании функции COUNT (*) вычисляется общее количество
строк, обработанных данным запросом. Однако если в качестве параметра
этой функции указать имя столбца, то будет подсчитано ко-личество
строк, содержащих в этом столбце ненулевое значение. Например,
если в одной или нескольких строках в поле Dept содержится значение
NULL, то следующий запрос возвратит не общее число строк, а количество
строк, содержащих ненулевое значение в поле Dept:

SELECT COUNT (Dept) FROM Employee

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

SELECT COUNT (DISTINCT Dept) FROM Employee

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

SELECT Dept, SUM (Salary) FROM Employee GROUP BY Dept

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

SELECT Dept, SUM (Salary) FROM Employee
GROUP BY Dept
HAVING SUM (Salary) < 200000

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

1. Выбираются все строки, удовлетворяющие оператору WHERE.
2. Вычисляются агрегированные значения.
3. Строки, полученные в результате агрегированных вычислений,
фильтруются с использованием оператора HAVING.

Значения литералов ODBC SQL
В некоторых из предыдущих примеров использовались простые
литералы или константы, имеющие по-стоянные значения в
операторах SQL. Для числовых значений, как целочисленных, так
и с плавающей точкой, необходимо использовать только десятичное
представление. Для строковых литералов строка символов просто
заключается в одинарные кавычки.
В качестве литерала можно использовать константу NULL, если вы
хотите установить для столбца нуле-вое значение.
Теперь перейдем к той части, в которой литералы представляют
особый интерес, к заданию значений даты и времени. Как правило,
в разных системах управления базами данных используются абсолютно
различные, а значит, несовместимые, способы представления литералов
для типов даты. Чтобы помочь решению этой проблемы, ODBC
обеспечивает переносимый синтаксис для таких значений.
Для литералов даты используется один из следующих форматов:
{ d 'yyyy-mm-dd' }
--(* VENDOR (Microsoft), PRODUCT (ODBC) d ' yyyy-mm-dd ' *)--

Аналогичным образом для литералов времени используется один из
следующих форматов:
{ t  ‘ hh: mm: ss ’ }
--(* VENDOR (Microsoft), PRODUCT (ODBC) t ‘ hh:mm:ss ' *)--

Для представления значений даты и времени используются следующие
форматы:
{ ts ' yyyy-mm-dd  hh:mm:ss' }
--(* VENDOR (Microsoft), PRODUCT (ODBC) ts ' yyyy-rom-dd hh:mm:ss ' *)--

Функции SQL
В SQL, используемом для ODBC, определено много различных функций,
которые можно использовать при построении запросов либо в параметре
списка выбора, либо в операторе WHERE. Для некоторых драйверов
функции также можно использовать в операторе ORDER BY. Эти
функции можно разделить на пять групп: строковые, числовые,
функции даты и времени, функции системы и функции преобразования
ти-пов данных.Синтаксис ODBC определяет одну из следующих форм
записи при вызове функции в SQL:

{fn имя функции }
или
--(* VENDOR (Microsoft), PRODUCT(ODBC) fn имя функции  *)--

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

SELECT Name,  (fn LENGTH (Name)1 FROM Employee
SELECT Name,--(* VENDOR (Microsoft), PRODUCT (ODBC) fn LENGTH(Name) *)-- FROM Employee
SELECT Name, LENGTH (Name) FROM Employee

Строковые функции
Для работы со строками в ODBC SQL определены следующие функции:

ASCII (строковое выражение) возвращает ASCII-код первого символа в строке.
BIT_LENGTH (строковое выражение) возвращает длину символа в битах.
CHAR (код) возвращает символ, соответствующий данному значению ASCII-кода.
CHAR_LENGTH (строковое выражение) возвращает длину строки в символах.
CHARACTER_LENGTH (строковое выражение) совпадает c CHAR_LENGTH ().
СОNСАТ (строковое_выраж1, строковое_выраж2) возвращает результат присоединения строковое_выраж2 к строковое_выраж1.
DIFFERENCE (строковое_выраж1, строковое_выраж2) возвращает целое значение, составляющее разность значений SOUNDEX для двух строковых выражений.
INSERT (строковое_выраж1, начало, длина, строковое_выраж2) возвращает строковое_вьраж1, из которого удалена длина символов, начиная с символа начало, на место которых начиная с символа начало, вставлено строковое выраж2.
LCASE (строковое_выраж) возвращает строковое выраж, символы которого преобразованы к нижне-му регистру.
LEFT (строковое_выраж, количество) возвращает количество символов слева в строковое_выраж.
LENGTH (строковое_выраж) возвращает длину строковое_выраж1 в символах за вычетом замыкающих пробелов.
LOCATE (строковое_выраж1, строковое_выраж2 [, начало]) возвращает начальную позицию пер-вого вхождения строковое_выраж1 в строковое_выраж2. Дополнительно можно указать номер началь-ного символа начало, начиная с которого будет осуществляться поиск в выражении строковое_выраж2 .
LTRIM (строковое выраж) возвращает строковое выраж, из которого удалены начальные пробелы.
ОСТЕТ_LENGHTH(строковое_выраж) возвращает длину строковое_выраж в байтах.
POSITION (строковое_выраж1 IN строковое_выраж2) возвращает позицию строковое_выраж1 в строковое выраж2.
REPEAT (строковое_выраж, количество) возвращает строку, состоящую из строковое_выраж, повто-ряющегося количество раз.
REPLACE (строковое_выраж1,строковое_выраж2, строковое_выраж3) возвращает строку, сгенери-рованную путем поиска вхождений строковое_выраж2 в строковое_выраж1 и их замены на строковое выражЗ.
RIGHT (строковое_выраж, количество) возвращает количество   символов   справа   в строковое_выраж.
RTRIM (строковое_выраж) возвращает строковое_выраж, из которого удалены все замыкающие пробелы.
SOUNDEX (строковое_выраж) возвращает символьную строку, представляющую транскрипцию пара-метра строковое_выраж. Тип возвращаемого значения определяется источником данных.
SPACE (количество) возвращает строку, состоящую из количество пробелов.
SUBSTRING (строковое_выраж, начало, длина) возвращает строку, состоящую из длина символов, взятых из строковое_выраж, начиная с символа начало.
UCASE (строковое_выраж) возвращает строковое_выраж, все символы которого преобразованы к верхнему регистру.

Числовые функции
Спецификация ODBC SQL включает также следующие числовые функции:
ABS (числовое_выраж) возвращает абсолютное значение параметра числовое_выраж.
ACOS (выраж_с_плав_точкой) возвращает арккосинус параметра выраж_с_плав_точкой в радианах.
ASIN (выраж_с_плав_точкой) возвращает арксинус параметра выраж_с_плав_точкой в радианах.
ATAN (выраж_с_плав_точкой) возвращает арктангенс параметра выраж_с_плав_точкой в радианах
ATAN2 (выраж_с_плав_точкой1, выраж_с_плав_точкой2) возвращает величину угла в радианах, за-данного координатами х и у в выражениях выраж_с_плав_точкой1 и выраж_с_плав_точкой2.
CEILING (числовое_выраж) возвращает наименьшее целое, большее или равное числовое_выраж.
COS ( выраж_с_плав_точкой) возвращает косинус угла выраж_с_плав_точкой, где выраж_с_плав_точ-кой представляет собой угол в радианах.
СОТ (выраж_с_плав_точкой) возвращает котангенс угла выраж_с_плав_точкой, где выраж_с_плав_точкой представляет собой угол в радианах.
DEGREES (числовое_выраж) возвращает угол в градусах, соответствующий углу числовое_выраж, за-данному в радианах.
ЕХР (выраж_с_плав_точкой) возвращает экспоненциальное значение выраж_с_плав_точкой.
FLOOR (числовое_выраж) возвращает наибольшее целое, не превышающее числовое_выраж. LOG(выраж_с_плав_точкой) возвращает натуральный логарифм выраж_с_плав_точкой.
LOG 10 (выраж_с_плав_точкой) возвращает десятичный логарифм выраж_с_плав_точкой. МOD(целое_выраж1, целое_выраж2) возвращает модуль (остаток) от деления целое_выраж1 на целое вьграж2.
PI () возвращает константу пи.
POWER (числовое_выраж, целое_выраж) возвращает числовое_выраж, возведенное в степень целое_выраж.
RADIANS (числовое_выраж) возвращает угол в радианах, соответствующий углу числовое_выраж, за-данному в градусах.
RAND ([целое_выраж]) возвращает случайное число с плавающей точкой. Дополнительно можно задать количество генерируемых случайных чисел целое_выраж.
ROUND (числовое_выраж, целое_выраж) возвращает значение числового выражения, округленное с точностью до целое_выраж знаков после запятой. Для параметра целое выраж можно задать отрицатель-ное значение, чтобы округлить числовое_выраж до нужного количества знаков после точки.
SIGN (числовое_выраж) возвращает -1, если числовое_выраж меньше нуля; 1, если оно больше нуля;
или 0, если числовое_выраж равно нулю.
SQRT (выраж_с_плав_точкой) возвращает квадратный корень из выраж_с_плав_точкой.
ТАN (выраж_с_плав_точкой)    возвращает    тангенс    угла    выраж_с_плав_точкой,    где выраж_с_плав_точкой представляет собой угол в радианах.
TRUNCATE (числовое_выраж, целое_выраж) возвращает числовое_выраж, усеченное до целое_выраж знаков после запятой. Чтобы усечь числовое выражение до целое_выраж слева от десятичной точки, можно задать отрицательное значение параметра целое_выраж.
Функции даты и времени
Для работы с переменными в различных форматах даты и времени используются следующие функции.
CURRENT_DATE () возвращает текущую дату.
CURRENT_TIME([точность]) возвращает текущее местное время. В качестве параметра точность можно указать значение точности в секундах.
CURRENT_TIMESTAMP ([точность]) возвращает текущее время и дату в формате даты/времени. В каче-стве параметра точность можно указать значение точности в секундах.
CURDATE () возвращает текущую дату.
CURTIME () возвращает текущее время.
DAYNAME (выраж_даты) возвращает строку символов, содержащую день недели для выраж_даты, задан-ного на локальном языке источника даты.
DAYOFMONTH (выраж_даты) возвращает число дней в месяце для даты выраж_даты.
DAYOFWEEK (выраж_даты) возвращает день недели как целое из диапазона 1-7, где 1 соответствует воскресенью.
DAYOFYEAR (выраж_даты) возвращает день в году из диапазона 1-366.
EXTRACT ( извлек_поле FROM источник) используется для извлечения некоторых полей из даты или времени, указанных в параметре источник. В качестве параметра извлек_поле можно задать одно из сле-дующих полей:
    YEAR
    MONTH
    DAY
    HOUR
    MINUTE
    SECOND
HOUR (выраж_времени) возвращает время суток в часах из диапазона 0—23 для выраж_времени.
MINUTE (выраж времени) возвращает минуты из диапазона 0—59 для выраж времени.
MONTH (выраж_времени) возвращает месяц из диапазона 1-12 для выраж_времени.
MONTHNAME (выраж_даты) возвращает Название месяца в выраж_времени.
NOW () возвращает текущую дату и время в формате даты/времени.
QUARTER (выраж даты) возвращает квартал из диапазона 1—4 для выраж даты. Значение 1 соответству-ет кварталу с 1 января по 31 марта.
SECOND (выраж_времени) возвращает секунды из диапазона 0—59 для выраж времени.
TIMESTAMPADD (интервал, целое_выраж, выраж_даты / времени) возвращает дату и время, получен-ные при добавлении целое_выраж единиц времени к дате и времени, указанным в выраж даты/времени. Тип единиц времени задается с помощью параметра интервал и может быть одним из следующих:
    SQL_TSI_FRAC_SECOND SQL TSI SECOND
    SQL_TSI_MINUTE
    SQL_TSI_HOUR
    SQL_TSI_DAY
    SQL_TSI_WEEK
    SQL_TSI_MONTH
    SQL_TSI_QUARTER
    SQL_TSI_YEAR

TIMESTAMPDIFF (интервал, выраж_даты/времени1, выраж_даты/времени2) возвращает количество единиц времени, полученное при вычитании выраж_даты/времени2 из выраж_даты/времени1. Исполь-зуемый тип единиц задается параметром интервал, который может принимать одно из значений, пере-численных ДЛЯ ФУНКЦИИ TIMES ТАМ PAD D () .
WЕЕК (выраж_даты) возвращает номер недели в году из диапазона 1—53 для выраж_даты.
YEAR (выраж_даты) возвращает год из выраж_даты.

Системные функции
В версии ODBC SQL поддерживаются следующие функции, связанные с некоторыми конструкциями, используемыми в ODBC.
DATABASE () возвращает имя базы данных, используемой в текущем сеансе.
IFNULL(выраж, значение) Если параметр выраж принимает значение NULL, то эта функция возвраща-ет значение параметра значение. В противном случае возвращается значение параметра выраж.
USER () возвращает имя пользователя базы данных, используемое в текущем сеансе.

Преобразование типов данных
Диалект ODBC SQL позволяет четко конвертировать значение поля или выражения в другой тип с ис-пользованием ФУНКЦИИ CONVERT():

CONVERT(значение_выраж, тип_данных)

Здесь параметр значение_вырая: задает имя поля или выражение, значение которого необходимо кон-вертировать, а параметр тип_данных используется для определения нового типа. Параметр тип_данных может принимать следующие значения:
    SQL_BINARY
    SQL_CHAR
    SQL_DECIMAL
    SQL_DOUBLE
    SQL_FLOAT
    SQL_INTEGER
    SQL_LONGVARCHAR
    SQL_NUMERIC
    SQL_REAL
    SQL_SMALLINT
    SQL_TYPE_DATE
    SQL_TYPE_TIME
    SQL_TYPE_TIMESTAMP
    SQL_VARCHAR

Объединения
Одной из наиболее важных операции, выполняемых над
реляционными базами данных, является операция объединения
(join), возвращающая строки, сформированные из данных двух или
более различных таблиц и объединенные в процессе выполнения
запроса. Объединения приобретают еще более важное значение
при работе с нормализованными базами данных.
Нормализация  это процесс, который в большей или меньшей
степени изменяет структуру базы данных.
Чтобы выполнить объединение, выделите столбцы нескольких таблиц.
Предположим, что у вас есть таблица Parts, содержащая информацию
о товарах, включая их описание, а также таблица Prices, содержащая
информацию о ценах на эти товары. Следующий запрос выполняет
объединение этих двух таблиц:

SELECT Description, Price FROM Parts, Prices

Однако полученный результат может вас удивить. В описанном
примере будет возвращено картезианское объединение этих двух
таблиц, представляющее собой все возможные комбинации строк
таблиц Parts и Prices. В большинстве случаев такой результат
абсолютно бесполезен. Чтобы ограничить множество возвращаемых
строк и сделать его более осмысленным, необходимо использовать
оператор WHERE. Желательно, чтобы в обоих таблицах содержался
общий идентификатор. Например, если в таблицах Prices и parts
содержится столбец PartNum, то можно объединить строки,
относящиеся к одному товару:

SELECT Description, Price FROM Parts, Prices WHERE Parts.PartNum = Prices.PartNum

Чтобы упростить некоторые запросы, SQL позволяет использовать
коррелированные имена, уменьшающие "многословность" запросов
и необходимые для некоторых более сложных запросов. Например,
если у вас есть следующий запрос

SELECT MyFirstTable.Name, MyFirstTable.Num, MySecondTable.Date, MySecondTable.Time
FROM MyFirstTable, MySecondTable
WHERE MyFirstTabie.Id = MySecondTable.Id

то его можно упростить с использованием коррелированных
имен f и s для таблиц MyFirstTable и MySecondTable соответственно:

SELECT ?.Name, f.Num, s.Date, s.Time FROM MyFirstTable f, MySecondTable s
WHERE f.Id = s.Id

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

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

SELECT * FROM Employee, Department
WHERE Employee.DeptNum - Department.DeptNum

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

SELECT * FROM
{oj Employee LEFT OUTER JOIN Department ON Employee. DeptNum " Department. DeptNum)

В этом примере мы использовали LEFT OUTER JOIN, чтобы
гарантировать, что в результирующем множестве будут представлены
все строки из левой таблицы (Employee). Чтобы включить все строки
из правой таблицы, можно использовать RIGHT OUTER JOIN, а чтобы
обеспечить выбор всех строк из обеих таблиц — FULL OUTER JOIN.

Вложенные запросы
В рассмотренных выше примерах с использованием оператора
WHERE мы сравнивали значения литера-лов, двух столбцов или
логические комбинации этих элементов. Однако, информацию для
оператора WHERE можно получать путем выполнения других запросов,
называемых вложенными запросами (subquery).
Вложенный запрос может использоваться с предикатом EXISTS
(или NOT EXISTS). Предположим, вы хотите выбрать список отделов,
еще не укомплектованных сотрудниками. Сделать это можно с
использованием следующего запроса:

SELECT DeptName FROM Department
WHERE DeptNum NOT EXISTS (SELECT * FROM Employee)

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

SELECT DeptName FROM Department d WHERE EXISTS
(SELECT * FROM Employee e WHERE e.Salary > 100000 AND d.DeptNum - e.DeptNum)

Вложенные запросы также применяются при использовании
предикатов IN или NOT IN. Например, с помощью следующего
запроса можно получить список всех отделов, в которых в
настоящее время числятся сотрудники:

SELECT DeptName FROM Department
WHERE DeptNum IN (SELECT DeptNum FROM Employee)

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

SELECT Ex.Name FROM Executives Ex WHERE Ex.Salary > ALL
(SELECT Emp.Salary FROM Employee Emp)

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

 SELECT Ex.Name FROM Executives Ex WHERE Ex.Salary > ANY
(SELECT Emp.Salary FROM Employee Emp)

Объединенные запросы
SQL позволяет получать один результат после выполнения двух
независимых запросов путем их ком-бинации с ключевым словом
UNION. По умолчанию повторяющиеся строки удаляются из
результирующего множества, однако от этого можно отказаться,
если вместо ключевого слова UNION использовать UNION ALL.
Кроме того, можно отсортировать конечный результат с
использованием оператора ORDER BY, который должен следовать
после последнего запроса в объединенном запросе.
Например, список сотрудников отделов MIS и Sales можно
сформировать с помощью следующего за-проса:

SELECT * FROM Employee WHERE Dept = 'MIS'
UNION
SELECT * FROM Employee WHERE Dept = 'Sales'

Конечно, существуют и более эффективные способы, позволяющие
получить этот результат, но мы хо-тели привести пример
использования ключевого слова UNION.

Оператор INSERT
Итак, теперь вы знаете, как извлечь строки из базы данных самыми
различными способами. Но как поместить их в определенное место
базы данных? На помощь здесь приходит оператор INSERT, имеющий
следующий основной синтаксис:

INSERT INTO имя-таблицы [(список-столбцов)] VALUES (список-значений)
котором они содержатся в таблице

Если значения добавляются для каждого из столбцов в том порядке,
лице, то параметр список-столбцов не используется:

INSERT INTO Employee
VALUES (123, 'Bob Jones', 35000, 'MIS')

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

INSERT INTO Employee (EmpId, EmpName, Dept) i VALUES (123, 'Joe Bob Griffin', 'Sales')

Кроме того, можно вставить строки с использованием значений,
возвращаемых оператором SELECT, вме-сто используемого ранее
оператора VALUES. Например, если отдел MIS перешел работать
в новую фирму, то вы можете добавить в таблицу FormerEmployee
новые записи с использованием следующего оператора:

INSERT INTO FormerEmployee (EmpId, EmpName, Reason)
SELECT EmpId, EmpName, 'Outsourced' FROM Employee WHERE Dept = 'MIS'

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

DELETE FROM Employee

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

DELETE FROM Employee WHERE EmpId " 456

Оператор UPDATE
Оператор UPDATE позволяет изменять значения в существующих
строках базы данных. Например, всем сотрудникам можно добавить
надбавку в размере $100:

UPDATE Employee SET Salary = Salary + 100

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

UPDATE Employee SET Salary = 21000 WHERE Salary < 21000

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

UPDATE Employee
SET EmpName = 'Mary Jones'. Dept = NULL, Status = 'On Leave' WHERE EmpNum =324