Основы синтаксиса sql. Примеры SQL-запросов в MariaDB (MySQL)

07.03.2019

Adobe AIR включает компонент SQL Database Engine с поддержкой локальных баз данных SQL и многими стандартными возможностями SQL на основе системы баз данных с открытым кодом. Среда выполнения не определяет способ хранения данных баз данных и их расположение в файловой системе. Каждая база данных целиком хранится в одной файле. Разработчик может указать местоположение в файловой системе для хранения файла базы данных, и отдельное приложение AIR сможет получить доступ к одной или нескольким отдельным базам данных (т.е. отдельным файлам баз данных).

В данном документе описан синтаксис SQL и поддержка типов данных для локальных баз данных SQL Adobe AIR. Этот документ не претендует на роль исчерпывающего справочника по SQL. Наоборот, в нем приводятся конкретные сведения о диалекте SQL, поддерживаемом Adobe AIR. Среда выполнения поддерживает большую часть стандартного диалекта SQL-92. Поскольку существует большое число справочников, веб-узлов, книг и учебных материалов для изучения SQL, данный документ не следует рассматривать, как исчерпывающий справочник по SQL или учебник. Более того, этот документ посвящен, в частности, синтаксису SQL, поддерживаемому Apollo AIR, а также описывает различия между SQL-92 и поддерживаемым диалектом SQL.

Рассматриваются следующие темы:

Поддерживаемый синтаксис SQL

Этот раздел посвящен синтаксису SQL, поддерживаемому компонентом SQL Database Engine Adobe AIR. Приведенный список можно разделить на описания различных инструкций и типов предложений, выражений, встроенных функций и операторов. Рассматриваются следующие темы:

Общий синтаксис SQL

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

Инструкции обработки данных

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

SELECT

Инструкция SELECT служит для опроса базы данных. Результатом инструкции SELECT является ноль или несколько строк данных, где у каждой строки имеется фиксированное число столбцов. Число столбцов в результате определяется именем столбца result или списком выражений между SELECT и необязательным ключевым словом FROM .

Sql-statement::= SELECT result * ] result::= result-column [, result-column]* result-column::= * | table-name . * | expr [ string] table-list::= table [ join-op table join-args ]* table::= table-name | (select) join-op::= , | JOIN join-args::= compound-op::= UNION | UNION ALL | INTERSECT | EXCEPT sort-expr-list::= expr [, expr ]* sort-order::= collation-name::= BINARY | NOCASE

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

По ключевому слову DISTINCT возвращается подмножество строк результатов с разными строками результатов. Значения NULL не рассматриваются как отличные друг от друга. По умолчанию возвращаются все строки результатов, если явным образом использовать ключевое слово ALL .

Запрос выполняется по одной или нескольким таблицам, указанным после ключевого слова FROM . Если несколько имен таблиц разделены запятыми, запрос использует перекрестное соединение различных таблиц. Синтаксис JOIN можно также использовать для указания способа соединения таблиц. Поддерживаемый тип внешнего соединения — LEFT OUTER JOIN . Выражение предложения ON в join-args должно приводить к логическому значению. Вложенный запрос в скобках можно использовать как таблицу в предложении FROM . Предложение FROM можно полностью опустить, в случае чего результатом будет отдельная строка значений списка выражений result .

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

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

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

Предложение ORDER BY вызывает сортировку выходных строк. Аргумент sort-expr-list в предложении ORDER BY представляет собой список выражений, используемых в качестве ключа для списка. Выражения не должны быть частью результата простой инструкции SELECT , но в составной инструкции SELECT (SELECT с использованием одного из операторов compound-op) каждое выражение сортировки должно в точности соответствовать одному из столбцов результатов. После каждого выражения сортировки можно использовать предложение sort-order (необязательно), состоящее из ключевого слова COLLATE и имени функции сортировки, используемое для упорядочивания текста, и/или ключевое слово ASC или DESC для указания порядка сортировки (по возрастанию или убыванию). Предложение sort-order можно опустить и использовать значение по умолчанию (упорядочивание по возрастанию). Определение предложения COLLATE и функций сортировки см. в разделе .

Предложение LIMIT устанавливает верхнюю границу числа строк, возвращаемых в результате. Отрицательное значение LIMIT указывает на отсутствие верхней границы. Необязательный оператор OFFSET после LIMIT указывает количество пропускаемых строк в начале результирующего набора. В составном запросе SELECT предложение LIMIT может только следовать за конечным оператором SELECT , и ограничение применяется к запросу целиком. Обратите внимание, что при использовании в предложении LIMIT ключевого слова OFFSET предельным значением является первое целое число, а смещением — второе целое число. Если вместо ключевого слова OFFSET использовать запятую, то смещением будет первое число, а предельным значением — второе число. Такое внешнее противоречие является намеренным: оно позволяет достичь максимальной совместимости с устаревшими системами баз данных SQL.

Составная инструкция SELECT формируется из одной или нескольких инструкций SELECT , соединенных одним из операторов UNION , UNION ALL , INTERSECT или EXCEPT . В составной инструкции SELECT все входящие в нее инструкции SELECT должны указывать то же число столбцов результатов. После конечной инструкции SELECT может быть только одно предложение ORDER BY (и перед отдельным предложением LIMIT , если оно указано). Операторы UNION и UNION ALL объединяют результаты предшествующих и последующих инструкции SELECT в одну таблицу. Отличие заключается в том, что в UNION различными являются все строки результатов, а в UNION ALL возможны повторения. Оператор INTERSECT принимает пересечение результатов предшествующих и последующих инструкций SELECT . EXCEPT принимает результат предшествующей инструкции SELECT после удаления результатов последующей инструкции SELECT . При соединении трех и более инструкций SELECT для образования составной инструкции, они группируются от первой до последней.

Определение разрешенных выражений см. в разделе

INSERT

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

Sql-statement::= INSERT INTO table-name [(column-list)] VALUES (value-list) | INSERT INTO table-name [(column-list)] select-statement REPLACE INTO table-name [(column-list)] VALUES (value-list) | REPLACE INTO table-name [(column-list)] select-statement

Первая форма (с ключевым словом VALUES) создает новую отдельную строку в существующей таблице. Если column-list не указан, то число значений должно соответствовать числу столбцов в таблице. Если column-list указан, то число значений должно соответствовать числу указанных столбцов. Столбцы таблицы, отсутствующие в списке столбцов, заполняются значением по умолчанию, определенным при создании таблицы, или значением NULL , если значение по умолчанию не определено.

Вторая форма INSERT берет свои данные из инструкции SELECT . Число столбцов в результате SELECT должно в точности соответствовать числу столбцов в таблице, если column-list не указан, или должно соответствовать числу столбцов, чьи имена указаны в column-list . Для каждой строки результата SELECT создается новая запись в таблице. Инструкция SELECT может быть простой или составной. Определение допустимых инструкций SELECT см. в разделе .

Две формы инструкции — REPLACE INTO — эквиваленты использованию стандартной инструкции INSERT с алгоритмом конфликтов REPLACE (т.е., форма INSERT OR REPLACE...).

UPDATE

Инструкция UPDATE служит для изменения значения столбцов в наборе строк в таблице.

Sql-statement::= UPDATE table-name SET assignment [, assignment]* conflict-algorithm::= ROLLBACK | ABORT | FAIL | IGNORE | REPLACE assignment::= column-name = expr

Каждое назначение в инструкции UPDATE указывает имя столбца слева от знака равенства (=) и произвольное выражение справа. В выражении можно использовать значения других столбцов. Перед любым назначением все выражения вычисляются. Определение разрешенных выражений см. в разделе

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

Необязательный conflict-algorithm позволяет указывать альтернативный алгоритм разрешения конфликтов ограничений во время этой команды. Определение и описание алгоритмов конфликтов см. в разделе .

DELETE

Команда удаления служит для удаления записей из таблицы.

Sql-statement::= DELETE FROM table-name

Команда состоит из ключевых слов DELETE FROM , после которых указывается имя таблицы, из которой требуется удалить записи.

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

Инструкции определения данных

Инструкции определения данных служат для создания, изменения и удаления объектов баз данных, таких как таблицы, представления индексы и триггеры. Поддерживаются следующие инструкции определения данных:

CREATE TABLE

Инструкция CREATE TABLE состоит из ключевых слов CREATE TABLE с именем новой таблицы, а затем (в скобках) списком определений столбцов и ограничений. Имя таблицы может быть идентификатором или строкой.

Sql-statement::= CREATE TABLE table-name (column-def [, column-def]* [, constraint]*) sql-statement::= CREATE TABLE table-name AS select-statement column-def::= name [ column-constraint]* type::= typename | typename (number) | typename (number , number) column-constraint::= NOT NULL [ conflict-clause ] | PRIMARY KEY [ conflict-clause ] | UNIQUE | CHECK (expr) | DEFAULT default-value | COLLATE collation-name constraint::= PRIMARY KEY (column-list) | UNIQUE (column-list) | CHECK (expr) conflict-clause::= ON CONFLICT conflict-algorithm conflict-algorithm::= ROLLBACK | ABORT | FAIL | IGNORE | REPLACE default-value::= NULL | string | number | CURRENT_TIME | CURRENT_DATE | CURRENT_TIMESTAMP sort-order::= ASC | DESC collation-name::= BINARY | NOCASE column-list::= column-name [, column-name]*

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

Ограничение столбца NOT NULL указывает, что в столбце не могут содержаться значения NULL .

Ограничение UNIQUE вызывает создание индекса для заданного столбца или столбцов. Этот индекс должен содержать уникальные ключи — две строки не могут содержать одинаковые значения или сочетания значений для заданного столбца или столбцов. Инструкция CREATE TABLE может иметь несколько ограничений UNIQUE , в том числе несколько столбцов с ограничением UNIQUE в определении столбца и/или несколько ограничений UNIQUE уровня таблицы.

Ограничение CHECK определяет вычисляемое выражение и должно быть истинным (true) для вставки или обновления данных строки. Выражение CHECK должно приводить к логическому значению.

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

Ограничение DEFAULT задает значение по умолчанию, используемое при выполнении INSERT . Значение может быть NULL , строковой константой или числом. Значение по умолчанию может также быть специальным независимым от регистра ключевым словом CURRENT_TIME , CURRENT_DATE или CURRENT_TIMESTAMP . Если значение равно NULL , является строковой константой или числом, оно буквально вставляется в столбец, если значение для столбца не задано инструкцией INSERT . Если используется значение CURRENT_TIME , CURRENT_DATE или CURRENT_TIMESTAMP , в столбец вставляется текущая дата и/или время в формате UTC. Для CURRENT_TIME задается формат HH:MM:SS . Для CURRENT_DATE форматом является YYYY-MM-DD . Формат для CURRENT_TIMESTAMP — YYYY-MM-DD HH:MM:SS .

Указание PRIMARY KEY обычно создает индекс UNIQUE для соответствующего столбца или столбцов. При этом если ограничение PRIMARY KEY действует для отдельного столбца с типом данных INTEGER , то столбец используется внутренне в качестве фактического первичного ключа для таблицы. Это означает, что в столбце могут содержаться только уникальные целочисленные значения. Если в таблице отсутствует столбец INTEGER PRIMARY KEY , ключ целых значений будет автоматически создан при вставке строки. Доступ к первичному ключу строки можно всегда получить при помощи одного из специальных имен ROWID , OID или _ROWID_ . Эти имена можно использовать независимо от того, явно объявленный INTEGER PRIMARY KEY это ключ или внутреннее созданное значение. Столбец INTEGER PRIMARY KEY может также включать ключевое слово AUTOINCREMENT . Когда используется ключевое слово AUTOINCREMENT , база данных автоматически создает и вставляет последовательно увеличивающийся ключ целых значений в столбец INTEGER PRIMARY KEY при выполнении инструкции INSERT .

В инструкции CREATE TABLE может быть только одно ограничение PRIMARY KEY . Оно может быть частью определения одного столбца или одного отдельного ограничения PRIMARY KEY уровня таблицы. Столбец первичного ключа неявно NOT NULL .

Необязательный conflict-clause после многих ограничений позволяет указывать альтернативный алгоритм разрешения конфликтов ограничений по умолчанию для такого ограничения. По умолчанию это ABORT . Для различных ограничений в одной и той же таблице возможны разные алгоритмы разрешения конфликтов по умолчанию. Если инструкция INSERT или UPDATE задает другой алгоритм разрешения конфликтов, то он используется вместо алгоритма, указанного в инструкции CREATE TABLE. Дополнительные сведения см. в разделе .

Дополнительные ограничения, такие как FOREIGN KEY, не приводят к ошибке, но среда выполнения пропускает их.

Если ключевое слово TEMP или TEMPORARY стоит между CREATE и TABLE , то создаваемая таблица будет видимой только в рамках одного и того же подключения к базе данных (экземпляр SQLConnection). При закрытии подключения она автоматически удаляется. Любые индексы, созданные во временной таблице, также являются временными. Временные таблицы и индексы хранятся в отдельном файле, отличным от основного файла базы данных.

Если указан необязательный префикс database-name , то таблица создается в именованной базе данных (базе данных, подключенной к экземпляру SQLConnection путем вызова метода attach() с заданным именем базы данных). Ошибочным будет указание префикса database-name и ключевого слова TEMP , если префикс database-name не является temp . Если имя базы данных не указано, а ключевое слово TEMP присутствует, то таблица создается в основной базе данных (базе данных, подключенной к экземпляру SQLConnection при помощи метода open() или openAsync()).

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

Форма CREATE TABLE AS определяет таблицу как результирующий набор запроса. Имена столбцов таблицы — это имена столбцов в результате.

Если присутствует необязательное предложение IF NOT EXISTS и другая таблица с тем же именем уже существует, то база данных пропускает команду CREATE TABLE .

Таблицу можно удалить при помощи инструкции DROP TABLE , а при помощи инструкции ALTER TABLE можно внести ограниченные изменения.

ALTER TABLE

Команда ALTER TABLE позволяет пользователю переименовать столбец или добавить новый столбец в существующую таблицу. Столбец невозможно удалить из таблицы.

Sql-statement::= ALTER TABLE table-name alteration alteration::= RENAME TO new-table-name alteration::= ADD column-def

Синтаксис RENAME TO используется для переименования таблицы, определенной table-name , в new-table-name . Эту команда нельзя использовать для переноса таблицы между присоединенными базами данных — она служит только для переименования таблицы в одной базе данных.

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

Синтаксис ADD используется для добавления нового столбца в существующую таблицу. Новый столбец всегда добавляется в конец списка существующих столбцов. Предложение column-def может принимать любые формы, допустимые в инструкции CREATE TABLE , со следующими ограничениями:

  • Столбец не может иметь ограничения PRIMARY KEY или UNIQUE .
  • Столбец не может иметь значения по умолчанию CURRENT_TIME , CURRENT_DATE или CURRENT_TIMESTAMP .
  • Если указано ограничение NOT NULL , столбец должен иметь значение по умолчанию, отличное от NULL .

Объем данных в таблице не влияет на время выполнения инструкции ALTER TABLE .

DROP TABLE

Инструкция DROP TABLE удаляет таблицу, добавленную с помощью инструкции CREATE TABLE . Таблица с указанным table-name — это удаленная таблица. Она полностью удаляется из базы данных и с диска. Восстановить таблицу невозможно. Все связанные с таблицей индексы также удаляются.

Sql-statement::= DROP TABLE table-name

По умолчанию инструкция DROP TABLE не уменьшает размер файла базы данных. Пустой пространство в базе данных сохраняется и используется в последующих операциях INSERT . Для удаления пустого пространства в базе данных служит метод SQLConnection.clean() . Если параметру autoClean присвоено значение true при первоначальном создании базы данных, пространство высвобождается автоматически.

Необязательное предложение IF EXISTS подавляет ошибку, которая обычно возникает, если таблица не существует.

CREATE INDEX

Команда CREATE INDEX состоит из ключевых слов CREATE INDEX с именем нового индекса, ключевым словом ON , именем ранее созданной таблицы, подлежащей индексации, и параметризованным списком имен столбцов в таблице, чьи значения используются для ключа индекса.

Sql-statement::= CREATE INDEX index-name ON table-name (column-name [, column-name]*) column-name::= name

За каждым именем столбца должно следовать ключевое слово ASC или DESC для указания порядка сортировки, но обозначение порядка сортировки пропускается средой выполнения. Сортировка всегда выполняется по возрастанию.

Предложение COLLATE после каждого имени столбца определяет параметры сортировки, применяемые к текстовым значениям в этом столбце. Параметры сортировки по умолчанию — это параметры сортировки, определенные для такого столбца в инструкции CREATE TABLE . Если параметры сортировки не заданы, используются параметры сортировки BINARY . Определение предложения COLLATE и функций сортировки см. в разделе .

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

DROP INDEX

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

Sql-statement::= DROP INDEX index-name

По умолчанию инструкция DROP INDEX не уменьшает размер файла базы данных. Пустой пространство в базе данных сохраняется и используется в последующих операциях INSERT . Для удаления пустого пространства в базе данных служит метод SQLConnection.clean() . Если параметру autoClean присвоено значение true при первоначальном создании базы данных, пространство высвобождается автоматически.

CREATE VIEW

Команда CREATE VIEW служит для назначения имени предопределенной инструкции SELECT . Затем это имя можно использовать в предложении FROM другой инструкции SELECT вместо имени таблицы. Представления, как правило, служат для упрощения запросов путем объединения сложного (или часто используемого) набора данных в структуру, которую можно использовать в других операциях.

Sql-statement::= CREATE VIEW view-name AS select-statement

Если ключевое слово TEMP или TEMPORARY стоит между CREATE и VIEW , то создаваемое представление будет видимым только экземпляру SQLConnection, который открыл базу данных, и будет удалено при закрытии базы данных.

Если указан , то представление создается в именованной базе данных (базе данных, подключенной к экземпляру SQLConnection при помощи метода attach() с указанным аргументом name). Ошибочным будет указание и ключевого слова TEMP , если не является temp . Если имя базы данных не указано, а ключевое слово TEMP присутствует, то представление создается в основной базе данных (базе данных, подключенной к экземпляру SQLConnection при помощи метода open() или openAsync()).

Представления доступны только для чтения. Инструкцию DELETE , INSERT или UPDATE нельзя использовать с представлением, если не определен, по меньшей мере, один триггер связанного типа (INSTEAD OF DELETE , INSTEAD OF INSERT , INSTEAD OF UPDATE). Дополнительные сведения о создании триггера для представления см. в разделе .

Для удаления представления из базы данных служит инструкция DROP VIEW .

DROP VIEW

Инструкция DROP VIEW удаляет представление, созданное с помощью инструкции CREATE VIEW .

Sql-statement::= DROP VIEW view-name

Указанный view-name является именем удаляемого представления. Представление удаляется из базы данных, но данные в базовых таблицах не изменяются.

CREATE TRIGGER

Инструкция создания триггера служит для добавления триггеров к схеме базы данных. Триггер — это операция базы данных (trigger-action), выполняемая автоматически при возникновении заданного события базы данных (database-event).

Sql-statement::= CREATE TRIGGER trigger-name database-event ON table-name trigger-action sql-statement::= CREATE TRIGGER trigger-name INSTEAD OF database-event ON view-name trigger-action database-event::= DELETE | INSERT | UPDATE | UPDATE OF column-list trigger-action::= BEGIN trigger-step ; [ trigger-step ; ]* END trigger-step::= update-statement | insert-statement | delete-statement | select-statement column-list::= column-name [, column-name]*

Триггер задается для запуска при возникновении события DELETE , INSERT или UPDATE определенной таблицы базы данных, или при обновлении одного или нескольких заданных столбцов таблицы при помощи инструкции UPDATE . Триггеры являются постоянными, если не используется ключевое слово TEMP или TEMPORARY . В таком случае триггер удаляется при закрытии подключения к основной базе данных экземпляра SQLConnection. Если время не указано (BEFORE или AFTER), триггер по умолчанию имеет значение BEFORE .

Поддерживаются только триггеры FOR EACH ROW , поэтому текст FOR EACH ROW является необязательным. С триггером FOR EACH ROW инструкции trigger-step выполняются для каждой вставляемой, обновляемой или удаляемой при помощи инструкции строки базы данных, вызывая запуск триггера, если выражение предложения WHEN получает значение true .

При указании предложения WHEN , инструкции SQL, указанные в качестве шагов триггера, выполняются только для строк, для которых предложение WHEN является истинным (true). Если предложение WHEN не указано, инструкции SQL выполняются для всех строк.

В теле триггера (предложение trigger-action) значения до изменения и после изменения затронутой таблицы доступны при помощи специальных имен таблиц OLD и NEW . Структура таблиц OLD и NEW соответствует структуре таблицы, для которой создается триггер. Таблица OLD содержит любые строки, измененные или удаленные инструкцией триггера, и их состояние до операций инструкции триггера. Таблица NEW содержит любые строки, измененные или созданные инструкцией триггера, и их состояние после операций инструкции триггера. Как предложение WHEN , так и инструкции trigger-step могут обращаться к значениям из вставляемых, удаляемых или обновляемых строк посредством ссылок вида NEW.column-name и OLD.column-name , где column-name — имя столбца из таблицы, с которой связан триггер. Доступность ссылок на таблицы OLD и NEW зависит от типа database-event , обрабатываемого триггером:

Указанное время (BEFORE , AFTER или INSTEAD OF) определяет время выполнения инструкций trigger-step относительно вставке, изменению или удалению связанной строки. Предложение ON CONFLICT может быть указано в составе инструкции UPDATE или INSERT в trigger-step . При этом если предложение ON CONFLICT указано в составе инструкции, вызывающей запуск триггера, то вместо этого используется политика разрешения конфликтов.

Помимо триггеров таблиц, триггер INSTEAD OF можно создать для представления. Если для представления определен один или несколько триггеров INSTEAD OF INSERT , INSTEAD OF DELETE или INSTEAD OF UPDATE , выполнение связанного типа инструкции для представления не будет считаться ошибкой (INSERT , DELETE и UPDATE). В этом случае выполнение INSERT , DELETE или UPDATE для представления приводит к запуску связанных триггеров. Так как триггер является триггером INSTEAD OF , таблицы в основе представления не изменяются инструкцией, запускающей триггер. При этом триггеры можно использовать для выполнения операций изменения с базовыми таблицами.

При создании триггера в таблице со столбцом INTEGER PRIMARY KEY важно помнить об одном. Если триггер BEFORE изменяет столбец INTEGER PRIMARY KEY строки, которая подлежит обновлению инструкцией, вызывающей запуск триггера, обновление не происходит. Выходом может быть создание таблицы со столбцом PRIMARY KEY вместо столбца INTEGER PRIMARY KEY .

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

Функция RAISE()

В инструкции trigger-step триггера можно использовать специальную функцию SQL RAISE() . Эта функция имеет следующий синтаксис:

Raise-function::= RAISE (ABORT, error-message) | RAISE (FAIL, error-message) | RAISE (ROLLBACK, error-message) | RAISE (IGNORE)

Одна из трех форм вызывается во время выполнения триггера, выполняется указанное действие обработки ON CONFLICT (ABORT , FAIL или ROLLBACK) и выполнение текущей инструкции прекращается. ROLLBACK считается ошибкой выполнения инструкции, поэтому экземпляр SQLStatement, чей метод execute() выполнялся, выдает событие error (SQLErrorEvent.ERROR). Объект SQLError в свойстве error выданного события объекта имеет свойство details со значением error-message , заданным в функции RAISE() .

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

DROP TRIGGER

Инструкция DROP TRIGGER удаляет триггер, созданный с помощью инструкции CREATE TRIGGER .

Sql-statement::= DROP TRIGGER trigger-name

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

Специальные инструкции и предложения

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

COLLATE

Предложение COLLATE используется в инструкциях SELECT , CREATE TABLE и CREATE INDEX для указания алгоритма сравнения, используемого при сравнении или сортировке значений.

Sql-statement::= COLLATE collation-name collation-name::= BINARY | NOCASE

Для столбцов типом сортировки по умолчанию является BINARY . При использовании сортировки BINARY со значениями класса хранения TEXT , двоичная сортировка выполняется путем сравнения байтов в памяти, представляющих значение, независимо от кодировки текста.

Параметры сортировки NOCASE применяются только к значениями класса хранения TEXT . При использовании сортировка NOCASE выполняет независимое от регистра сравнение.

Параметры сортировки не используются для классов хранения типа NULL , BLOB , INTEGER или REAL .

Чтобы использовать тип сортировки, отличный от BINARY со столбцом, в составе определения столбца в инструкции CREATE TABLE необходимо указать предложение COLLATE . Каждый раз при сравнении двух значений TEXT , параметры сортировки используются для определения результатов сравнения по следующим правилам:

  • В случае с операторами двоичного сравнения (= , < , > , =) если один из операндов является столбцом, то тип сортировки столбца по умолчанию определяет параметры сортировки, используемые для сравнения. Если оба операнда являются столбцами, то тип сортировки для левого операнда определяет используемые параметры сортировки. Если ни один из операндов не является столбцом, то используют параметры сортировки BINARY .
  • Оператор BETWEEN...AND эквивалентен использованию двух выражений с операторами >= и = y AND x = < = или < string > < string > [любой печатаемый текст в одиночных кавычках] Примечание: В < string >, две последовательных одиночных кавычки (" ") интерпретируются как одна ("). < SQL term > окончание, зависящее от главного языка. (*только вложенный*)

    ФУНКЦИОНАЛЬНЫЕ ЭЛЕМЕНТЫ Следующая таблица показывает функциональные элементы команд SQL и их определения: ЭЛЕМЕНТ ОПРЕДЕЛЕНИЕ < query > Предложение SELECT < subquery > Заключенное в круглых скобках предложение SELECT внутри другого условия, которое, фактически, оценивается отдельно для каждой строки-кандидата другого предложения. < value expression > < primary > | < primary > < operator > < primary > | < primary > < operator > < value expression > < operator > любое из следующих: + - / * < primary > < column name > | < literal > | < aggregate function > | < built-in constant > | < nonstandard function > < literal > < string > | < mathematical expressio ЭЛЕМЕНТ ОПРЕДЕЛЕНИЕ < built-in constant > USER | < implementation-dehned constant > < table name > < identifier > < column spec > [< table name > | < alias >.]< column name > < grouping column > < column spec > | < integer > < ordering column > < column spec > | < integer > < colconstraint > NOT NULL | UNIQUE | CHECK (< predicate >) | PRIMARY KEY | REFERENCES < table name >[(< column name >)] < tabconstraint > UNIQUE (< column list >) | CHECK (< predicate >) | PRIMARY KEY (< column list >) | FOREIGN KEY (< column list >) REFERENCES < table name >[(< column list >)] < defvalue > ЗНАЧЕНИЕ ПО УМОЛЧАНИЮ = < value expression > < data type > Допустимый тип данных (См. Приложение B для описания типов обеспечиваемых ANSI или Приложение C для других общих типов.) < size > Значение зависит от < data type >(См. Приложение B .) < cursor name > < identifier > < index name > < identifier > < synonym > < identifier >(*nonstandard*) < owner > < Authorization ID > < column list > < column spec > .,.. < value list > < value expression > .,.. < table reference > { < table name > [< alias >] } .,.. ПРЕДИКАТЫ

    Следующее определяет список различных типов предиката < predicate > описанных на следующих страницах:

    < predicate > ::=

    { < comparison predicate > | < in predicate > | < null predicate > | < between predicate > | < like predicate > | < quantified predicate > | < exists predicate > } < predicate > - это выражение, которое может быть верным, неверным, или неизвестным, за исключением < exists predicate > и < null predicate >, которые могут быть только верными или неверными.

    Будет получено неизвестно если NULL значения предотвращают вывод полученного ответа. Это будет случаться всякий раз, когда NULL значение сравнивается с любым значением. Стандартные операторы Буля - AND, OR, и NOT - могут использоваться с предикатом. NOT верно = неверно, NOT неверно = верно, а NOT неизвестно = неизвестно. Результаты AND и OR в комбинации с предикатами, показаны в следующих таблицах:

    AND AND Верно Неверно Неизвестно Верно верно неверно неизвестно Неверно неверно неверно неверно Неизвестно неизвестно неверно неизвестно OR OR Верно Неверно Неизвестно Верно верно верно верно Неверно верно неверно неизвестно Неизвестно верно неизвестно неизвестно

    Эти таблицы читаются способом наподобие таблицы умножения: вы объединяете верные, неверные, или неизвестные значения из строк с их столбцами чтобы на перекрестье получить результат. В таблице AND, например, третий столбец (Неизвестно) и первая строка (Верно) на пересечении в верхнем правом углу дают результат - неизвестно, другими словами: Верно AND Неизвестно = неизвестно. Порядок вычислений определяется круглыми скобками. Они не представляются каждый раз. NOT оценивается первым, далее AND и OR. Различные типы предикатов < predicate > рассматриваются отдельно в следующем разделе.

    < comparison predicate > (предикат сравнения)

    Синтаксис

    < value expresslon > < relational op > < value expresslon > |
    < subquery >
    < relatlonal op > :: =
    =
    | <
    | >
    | <
    | >=
    | < >

    Если либо < value expression > = NULL, либо < comparison predicate > = неизвестно; другими словами, это верно если сравнение верно или неверно если сравнение неверно.
    < relational op > имеет стандартные математические значения для числовых значений; для других типов значений, эти значения определяются конкретной реализацией.
    Оба < value expression > должны иметь сравнимые типы данных. Если подзапрос < subquery > используется, он должен содержать одно выражение < value expression > в предложении SELECT, чье значение будет заменять второе выражение < value expression > в предикате сравнения < comparision predicate >, каждый раз когда < subquery > действительно выполняется.

    < between predicate >

    Синтаксис

    < value expression > BETWEEN < value expression >
    AND < value expression >

    < between predicate > - A BETWEEN B AND C , имеет такое же значение что и < predicate > - (A >= B AND < = C). < between predicate > для которого A NOT BETWEEN B AND C, имеет такое же значение что и NOT (BETWEEN B AND C). < value expression > может быть выведено с помощью нестандартного запроса < subquery > (*nonstandard*).

    < in prediicate >

    Синтаксис

    < value expression > IN < value list > | < subquery >

    Список значений < value list > будет состоять из одного или более перечисленных значений в круглых скобках и отделяемых запятыми, которые имеют сравнимый с < value expression > тип данных. Если используется подзапрос < subquery >, он должен содержать только одно выражение < value expression > в предложении SELECT (возможно и больше, но это уже будет вне стандарта ANSI). Подзапрос < subquery > фактически, выполняется отдельно для каждой строки-кандидата основного запроса, и значения которые он выведет, будут составлять список значений < value list > для этой строки. В любом случае, предикат < in predicate > будет верен если выражение < value expression > представленное в списке значений < value list >, если не указан NOT. Фраза A NOT IN (B, C) является эквивалентом фразы NOT (A IN (B, C)).

    < like predicate >

    Синтаксис

    < charvalue > LIKE < pattern >

    < charvalue > - это любое *нестандартное* выражение < value expression > алфавитно-цифрового типа. < charvalue > может быть, в соответствии со стандартом, только определенным столбцом < column spec >. Образец < pattern > состоит из строки которая будет проверена на совпадение с < charvalue >. Символ окончания < escapechar > - это одиночный алфавитно-цифровой символ. Совпадение произойдет, если верны следующие условия:

  • Для каждого символа подчеркивания < underscore > в образце < pattern > которая не предшествует символу окончания < escapechar >, имеется один соответствующий ему символ < charvalue >.
  • Для каждого < percent sign > в образце < pattern >, который не предшествует < escapechar >, имеются нули или более соответствующие символы в < charvalue >.
  • Для каждого < escapechar > в < pattern > который не предшествует другому < escapechar >, нет никакого соответствующего символа в < charvalue >.
  • Для каждого иного символа в < pattern >, один и тот же символ устанавливается у соответствующей отметке в < charvalue >.

    Если совпадение произошло, < like predicate > - верен, если не был указан NOT. Фраза NOT LIKE "текст" - эквивалентна NOT (A LIKE "текст").

    < null predicate >

    Синтаксис

    < column spec > IS NULL

    < column spec > = IS NULL, если NULL значение представлено в этом столбце. Это сделает < null predicate > верным если не указан NULL. Фраза < column spec > IS NOT NULL, имеет тот же результат что и NOT (< column spec > IS NULL).

    < quantified predicate >

    Синтаксис

    < value expression > < relational op >
    < quantifier > < subquery >
    < quantifier > :: = ANY | ALL | SOME

    Предложение SELECT подзапроса < subquery > должно содержать одно и только одно выражение значения < value expression >. Все значения выведенные подзапросом < subquery > составляют набор результатов < result set >. < value expression > сравнивается, используя оператор связи < relational operator >, с каждым членом набора результатов < result set >. Это сравнение оценивается следующим образом:

  • Если < quantifier > = ALL, и каждый член набора результатов < result set > делает это сравнение верным, < quantified predicate > - верен.
  • Если < quantifier > = ANY, и имеется по крайней мере один член из набора результатов < result set > , который делает верным это сравнение, то < quantified predicate > является верным.
  • Если набор результатов < result set > пуст, то < quantified predicate > верен, если < quantifier > = ALL , и неверен если иначе.
  • Если < quantifier > = SOME, эффект - тот же что и для ANY.
  • Если < quantified predicate > не верен и не неверен, он - неизвестен.

    < exists predicate >

    Синтаксис:

    EXISTS (< subquery >)

    Если подзапрос < subquery > выводит одну или более строк вывода, < exists predicate > - верен; и неверен если иначе.

    SQL КОМАНДЫ

    Этот раздел подробно описывает синтаксис различных команд SQL. Это даст вам возможность быстро отыскивать команду, находить ее синтаксис и краткое описание ее работы.

    ИМЕЙТЕ ВВИДУ Команды которые начинаются словами - EXEC SQL, а также команды или предложения заканчивающиеся словом - могут использоваться только во вложенном SQL.

    BEGIN DECLARE SECTION (НАЧАЛО РАЗДЕЛА ОБЪЯВЛЕНИЙ)

    Синтаксис

    EXEC SQL BEGIN DECLARE SECTION < SQL term > < host-language variable declarations > EXEC SQL END DECLARE SECTION < SQL term >

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

    CLOSE CURSOR (ЗАКРЫТЬ КУРСОР)

    Синтаксис

    EXEC SQL CLOSE CURSOR < cursor name > < SQL term >;

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

    COMMIT (WORK) (ФИКСАЦИЯ (ТРАНЗАКЦИИ))

    Синтаксис

    Эта команда оставляет неизменными все изменения сделанных в базе данных, до тех пор пока начавшаяся транзакция не закончится, и не начнется новая транзакция.

    CREATE INDEX (СОЗДАТЬ ИНДЕКС)

    (*NONSTANDARD*) (НЕСТАНДАРТНО)

    Синтаксис

    CREATE INDEX < Index name >
    ON < table name > (< column list >);

    Эта команда создает эффективный маршрут с быстрым доступом для поиска строк содержащих обозначенные столбцы. Если UNIQUE - указана, таблица не сможет содержать дубликатов(двойников) значений в этих столбцах.

    CREATE SYNONYM (*NONSTANDARD*)
    (СОЗДАТЬ СИНОНИМ) (*НЕСТАНДАРТНО*)

    Синтаксис

    CREATE IPUBLICl SYNONYM < synonym > FOR
    < owner >.< table name >;

    Эта команда создает альтернативное(синоним) им для таблицы. Синоним принадлежит его создателю, а сама таблица, обычно другому пользователю. Используя синоним, его владелец может не ссылаться к таблице ее полным (включая им владельца) именем. Если PUBLIC - указан, синоним принадлежит каталогу SYSTEM и следовательно доступен всем пользователям.

    CREATE TABLE (СОЗДАТЬ ТАБЛИЦУ)

    Синтаксис

    CREATE TABLE < table name >
    ({< column name > < data type >[< size >]
    [< colconstralnt > . . .]
    [< defvalue >]} . , . . < tabconstraint > . , . .);

    Команда создает таблицу в базе данных. Эта таблица будет принадлежать ее создателю. Столбцы будут рассматриваться в поименном порядке. < data type > - определяет тип данных который будет содержать столбец. Стандарт < data type > описывается в Приложении B ; все прочие используемые типы данных < data type >, обсуждались в Приложении C . Значение размера < size > зависит от типа данных < data type >.
    < colconstraint > и < tabconstraint > налагают ограничения на значения ко торые могут быть введены в столбцу.
    < defvalue > определяет значение(по умолчанию) которое будет вставлено автоматически, если никакого другого значения не указано для этой строки. (См. Главу 17 для подробностей о самой команде CREATE TABLE иГлавы 18 И для подробностей об ограничениях и о < defvalue >).

    CREATE VIEW (СОЗДАТЬ ПРОСМОТР)

    Синтаксис

    CREATE VIEW < table name >
    AS < query >
    ;

    Просмотр обрабатывается как люба таблица в командах SQL. Когда команда ссылается на имя таблицы < table name >, запрос < query > выполняется, и его вывод соответствует содержанию таблицы указанной в этой команде.
    Некоторые просмотры могут модифицироваться, что означает, что команды модификации могут выполняться в этих просмотрах и передаваться в таблицу, на которую была ссылка в запросе < query >. Если указано предложение WITH CHECK OPTION, эта модификация должны также удовлетворять условию предиката < predicate > в запросе < query >.

    DECLARE CURSOR (ОБЪЯВИТЬ КУРСОР)

    Синтаксис

    EXEC SQL DECLARE < cursor name > CURSOR FOR
    < query >< SQL term >

    Эта команда связывает им курсора < cursor name >, с запросом < query >. Когда курсор открыт (см. OPEN CURSOR), запрос < query > выполняет ся, и его результат может быть выбран(командой FETCH) для вывода. Если курсор модифицируемый, таблица на которую ссылается запрос < query >, может получить изменение содержания с помощью операции модификации в курсоре (См. Главу 25 о модифицируемых курсорах).

    DELETE (УДАЛИТЬ)

    Синтаксис

    DELETE FROM < table name >
    { ; }
    | WHERE CURRENT OF < cursorname >< SQL term >

    Если предложение WHERE отсутствует, ВСЕ строки таблицы удаляются. Если предложение WHERE использует предикат < predicate >, строки, ко торые удовлетворяют условию этого предиката < predicate > удаляются. Если предложение WHERE имеет аргумент CURRENT OF(ТЕКУЩИЙ) в имени курсора < cursor name >, строка из таблицы < table name > на ко торую в данный момент имеется ссылка с помощью имени курсора < cursor name > будет удалена. Форма WHERE CURRENT может использоваться только во вложенном SQL, и только с модифицируемыми курсорами.

    EXEC SQL (ВЫПОЛНИТЬ SQL)

    Синтаксис

    EXEC SQL < embedded SQL command > < SQL term >

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

    FETCH (ВЫБОРКА)

    Синтаксис

    EXEC SQL FETCH < cursorname >
    INTO < host-varlable llst >< SQL term >

    FETCH принимает вывод из текущей строки запроса < query >, вставляет ее в список главных переменных < host-variable list >, и перемещает кур сор на следующую строку. Список < host-variable list > может включать переменную indicator в качестве целевой переменной (См. Главу 25 .)

    GRANT (ПЕРЕДАТЬ ПРАВА)

    Синтаксис (стандартный)

    GRANT ALL
    | {SELECT
    | INSERT
    | DELETE
    | UPDATE [(< column llst >)]
    | REFERENCES [(< column llst >)l } . , . .
    ON < table name > . , . .
    TO PUBLIC | < Authorization ID > . , . .
    ;

    Аргумент ALL(ВСЕ), с или без PRIVILEGES(ПРИВИЛЕГИИ), включает каждую привилегию в список привилегий. PUBLIC(ОБЩИЙ) включает всех существующих пользователей и всех созданных в будущем. Эта команда дает возможность передать права для выполнения действий в таблице с указанным именем. REFERENCES позволяет дать права чтобы использовать столбцы в списке столбцов < column list > как родительский ключ для внешнего ключа. Другие привилегии состоят из права выполнять команды для которых привилегии указаны их именами в таблице. UPDATE, подобен REFERENCES, и может накладывать ограничения на определенные столбцы. GRANT OPTION дает возможность передавать эти привилегии другим пользователям.

    Синтаксис (нестандартный)

    GRANT DBA
    | RESOURCE
    | CONNECT ... .
    TO < Authorization ID > . , . .
    | < privilege > . , . . }
    FROM { PUBLIC
    | < Authorization ID > . , . . };

    Привилегия < privelege > может быть любой из указанных в команде GRANT. Пользователь дающий REVOKE должен иметь те же привилегии, что и пользователь который давал GRANT. Предложение ON может быть использовано, если используется привилегия специального типа для особого объекта.

    ROLLBACK (WORK)
    (ОТКАТ) (ТРАНЗАКЦИИ)

    Синтаксис

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

    SELECT (ВЫБОР)

    Синтаксис

    SELECT { IDISTINCT | ALL] < value expression > . , . . } / *
    FROM < table reference > . , . .

    . , . . ];

    Это предложение организует запрос и выводит значения из базы данных (см. Глава 3 - Глава 14). Применяются следующие правила:

  • Если ни ALL, ни DISTINCT - не указаны, принимается - ALL.
  • Выражение < value expression > состоит из < column spec >, агрегатной функции < aggregate funct >, нестандартной функции < nonstandard fu nction >, постоянной < constant >, или любой их комбинации с операторами в допустимых выражениях.
  • Ссылаемая таблица < table reference >, состоит из имени таблицы, включая префикс владельца если текущий пользователь не владелец, или синоним(нестандартно) для таблицы. Таблица может быть или базовой таблицей или просмотром. В принципе, псевдоним может указать, как- ой синонимом используется для таблицы только на врем текущей ко- манды. Имя таблицы или синоним должны отделяться от псевдонима одним или более разделительными знаками < separator >.
  • Если используется GROUP BY, все столбцы < column spec > используемые в предложении SELECT, должны будут использоваться как группа столбцов < grouping column >, если они не содержатся в агрегатной функции < aggregate funct >. Вся группа столбцов < grouping column > должна быть представлена среди выражений < value expressions > указанных в предложении SELECT. Для каждой отдельной комбинации значений группы столбцов < grouping column >, будет иметься одна и только одна строка вывода.
  • Если HAVING используется, предикат < predicate > применяется к каждой строке произведенной предложением GROUP BY, и те строки которые сделают этот предикат верным, будут выведены.
  • Если ORDER BY используется, вывод имеет определенную последовательность. Каждый идентификатор столбца < column identifer > ссылается к указанному < value expression > в предложении SELECT. Если это < value expression > является указанным столбцом < column spec >, < co lumn identifier > может быть таким же как < column spec >. Иначе < co lumn identifier > может быть положительным целым числом, указываю щим место где находится < value expression > в последовательности предложения SELECT. Вывод будет сформирован так чтобы помещать значения содержащиеся в < column identifier > в порядке возрастания, если DESC не указан. Имя идентификатора столбца < column identifier > стоящее первым в предложении ORDER BY будет предшествовать позже стоящим именам в определении последовательности вывода.

    Предложение SELECT оценивает каждую строку-кандидат таблицы в которой строки показаны независимо. Строка-кандидат определяется следующим образом:

  • Если только одна ссылаемая таблица < table reference > включена, каждая строка этой таблица в свою очередь является строкой-кандидатом.
  • Если более одной ссылаемой таблицы < table reference > включено, каждая строка каждой таблицы должна быть скомбинирована в свою очередь с каждой комбинацией строк из всех других таблиц. Каждая такая комбинация будет в свою очередь строкой-кандидатом.

    Каждая строка-кандидат производит значения, которые делают предикат < predicate > в предложении WHERE верным, неверным, или неизвестным. Если GROUP BY не используется, каждое < value expression > применяется в свою очередь для каждой строки-кандидата чье значение делает предикат верным, и результатом этой операции является вывод.
    Если GROUP BY используется, строки-кандидаты комбинируются, используя агрегатные функции. Если никакого предиката < predicate > не установлено, каждое выражение< value expression > применяется к каждой строке-кандидату или к каждой группе. Если указан DISTINCT, дубликаты(двойники) строк будут удалены из вывода.

    UNION (ОБЪЕДИНЕНИЕ)

    Синтаксис

    < query > {UNION < query > } . . . ;

    Вывод двух или более запросов < query > будет объединен. Каждый запрос < query > должен содержать один и тот же номер < value expression > в предложение SELECT и в таком порядке что 1.. n каждого, совместим по типу данных < data type > и размеру < size > с 1.. n всех других.

    UPDATE (МОДИФИКАЦИЯ)

    Синтаксис

    UPDATE < table name >
    SET { < column name > = < value expression > } . , . .
    {[ WHERE < predlcate >]; }
    | {
    < SQL term >]}

    UPDATE изменяет значения в каждом столбце с именем < column name > на соответствующее значение < value expression >. Если предложение WHERE использует предикат < predicate >, то только строки таблиц чьи текущие значения делают тот предикат < predicate > верным, могут быть изменены. Если WHERE использует предложение CURRENT OF, то значения в строке таблицы с именем < table name > находящиеся в курсоре с именем < cursor name > меняются. WHERE CURRENT OF пригодно для использования только во вложенном SQL, и только с модифицируемыми курсорами. При отсутствии предложения WHERE - все строки меняются.

    WHENEVER (ВСЯКИЙ РАЗ КАК)

    Синтаксис

    EXEC SQL WHENEVER < SQLcond > < actlon > < SQL term >
    < SQLcond > :: = SQLERROR | NOT FOUND | SQLWARNING
    (последнее - нестандартное)
    < action > :: = CONTINUE | GOTO < target > | GOTO < target >
    < target > :: = зависит от главного языка

  • Типы данных SQL (Как в Pg , как в стандарте)

    Строковые типы

    Числовые типы данных

    Денежные, Символьные, Двоичные типы данных

    Логический тип. Перечисления

    Примеры простейших SQL-запросов

    Простейшие SELECT-запросы

    Оператор SELECT (выбрать) языка SQL является самым важным и самым часто используемым оператором. Он предназначен для выборки информации из таблиц базы данных. Упрощенный синтаксис оператора SELECT выглядит следующим образом.

    SELECT [ ALL | DISTINCT ] select_item_commalist

    FROM table_reference_commalist

    [ WHERE conditional_expression ]

    [ GROUP BY column_name_commalist ]

    [ HAVING conditional_expression ]

    [ ORDER BY order_item_commalist ]

    В квадратных скобках указаны элементы, которые могут отсутствовать в запросе.

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

    После слова SELECT через запятую перечисляются наименования полей (список атрибутов), содержимое которых запрашивается.

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

    Например, select title, description from film

    Любой SQL-запрос должен заканчиваться символом «;» (точка с запятой). Результатом данного запроса будет таблица...

    Порядок следования столбцов в этой таблице соответствует порядку полей, указанному в запросе

    Если необходимо вывести значения всех, столбцов таблицы, то можно вместо перечисления их имен использовать символ «*» (звездочка).

    SELECT * FROM film;

    В данном случае результатом выполнения запроса будет вся таблица film.

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

    Например, запрос «список имен актеров», можно записать в следующем виде.

    select first_name from actor;

    Его результатом будет таблица, в таблице встречаются одинаковые строки. Для исключения из результата SELECT-запроса повторяющихся записей используется ключевое слово DISTINCT (отличный).

    Если запрос SELECT извлекает множество полей, то DISTINCT исключает дубликаты строк, в которых значения всех выбранных полей идентичны.

    Предыдущий запрос можно записать в следующем виде.

    select distinct first_name from actor;

    В результате получим таблицу, в которой дубликаты строк исключены.

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

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

    Пример: Написать запрос, выполняющий выборку фамилий всех актеров с именем PENELOPE

    select last_name from actor

    where first_name="PENELOPE";

    В задаваемых в предложении WHERE условиях могут использоваться операции сравнения, определяемые операторами = (равно), > (больше), < (меньше), >= (больше или равно), (SELECT avg(stock) FROM books)) GROUP BY members.firstname, members.lastname;

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


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


    Не смотря на то, что синтаксис SQL почти не отличается в разных базах данных, в этой статье для запросов используется PostgreSQL. Некоторые примеры будут работать в MySQL и других базах.

    1. Три волшебных слова

    В SQL много ключевых слов, но SELECT , FROM и WHERE присутствуют практически в каждом запросе. Чуть позже вы поймете, что эти три слова представляют собой самые фундаментальные аспекты построения запросов к базе, а другие, более сложные запросы, являются всего лишь надстройками над ними.

    2. Наша база

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







    У нас есть книжная библиотека и люди. Также есть специальная таблица для учета выданных книг.

    • В таблице "books" хранится информация о заголовке, авторе, дате публикации и наличии книги. Все просто.
    • В таблице “members” - имена и фамилии всех записавшихся в библиотеку людей.
    • В таблице “borrowings” хранится информация о взятых из библиотеки книгах. Колонка bookid относится к идентификатору взятой книги в таблице “books”, а колонка memberid относится к соответствующему человеку из таблицы “members”. У нас также есть дата выдачи и дата, когда книгу нужно вернуть.
    3. Простой запрос

    Давайте начнем с простого запроса: нам нужны имена и идентификаторы (id) всех книг, написанных автором “Dan Brown”


    Запрос будет таким:


    SELECT bookid AS "id", title FROM books WHERE author="Dan Brown";

    А результат таким:


    id title
    2 The Lost Symbol
    4 Inferno

    Довольно просто. Давайте разберем запрос чтобы понять, что происходит.

    3.1 FROM - откуда берем данные

    Сейчас это может показаться очевидным, но FROM будет очень важен позже, когда мы перейдем к соединениям и подзапросам.


    FROM указывает на таблицу, по которой нужно делать запрос. Это может быть уже существующая таблица (как в примере выше), или таблица, создаваемая на лету через соединения или подзапросы.

    3.2 WHERE - какие данные показываем

    WHERE просто-напросто ведет себя как фильтр строк , которые мы хотим вывести. В нашем случае мы хотим видеть только те строки, где значение в колонке author - это “Dan Brown”.

    3.3 SELECT - как показываем данные

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


    Весь запрос можно визуализировать с помощью простой диаграммы:


    4. Соединения (джойны)

    Теперь мы хотим увидеть названия (не обязательно уникальные) всех книг Дэна Брауна, которые были взяты из библиотеки, и когда эти книги нужно вернуть:


    SELECT books.title AS "Title", borrowings.returndate AS "Return Date" FROM borrowings JOIN books ON borrowings.bookid=books.bookid WHERE books.author="Dan Brown";

    Результат:


    Title Return Date
    The Lost Symbol 2016-03-23 00:00:00
    Inferno 2016-04-13 00:00:00
    The Lost Symbol 2016-04-19 00:00:00

    По большей части запрос похож на предыдущий за исключением секции FROM . Это означает, что мы запрашиваем данные из другой таблицы . Мы не обращаемся ни к таблице “books”, ни к таблице “borrowings”. Вместо этого мы обращаемся к новой таблице , которая создалась соединением этих двух таблиц.


    borrowings JOIN books ON borrowings.bookid=books.bookid - это, считай, новая таблица, которая была сформирована комбинированием всех записей из таблиц "books" и "borrowings", в которых значения bookid совпадают. Результатом такого слияния будет:



    А потом мы делаем запрос к этой таблице так же, как в примере выше. Это значит, что при соединении таблиц нужно заботиться только о том, как провести это соединение. А потом запрос становится таким же понятным, как в случае с «простым запросом» из пункта 3.


    Давайте попробуем чуть более сложное соединение с двумя таблицами.


    Теперь мы хотим получить имена и фамилии людей, которые взяли из библиотеки книги автора “Dan Brown”.


    На этот раз давайте пойдем снизу вверх:


    Шаг Step 1 - откуда берем данные? Чтобы получить нужный нам результат, нужно соединить таблицы “member” и “books” с таблицей “borrowings”. Секция JOIN будет выглядеть так:


    borrowings JOIN books ON borrowings.bookid=books.bookid JOIN members ON members.memberid=borrowings.memberid

    Результат соединения можно увидеть по ссылке .


    Шаг 2 - какие данные показываем? Нас интересуют только те данные, где автор книги - “Dan Brown”


    WHERE books.author="Dan Brown"

    Шаг 3 - как показываем данные? Теперь, когда данные получены, нужно просто вывести имя и фамилию тех, кто взял книги:


    SELECT members.firstname AS "First Name", members.lastname AS "Last Name"

    Супер! Осталось лишь объединить три составные части и сделать нужный нам запрос:


    SELECT members.firstname AS "First Name", members.lastname AS "Last Name" FROM borrowings JOIN books ON borrowings.bookid=books.bookid JOIN members ON members.memberid=borrowings.memberid WHERE books.author="Dan Brown";

    Что даст нам:


    First Name Last Name
    Mike Willis
    Ellen Horton
    Ellen Horton

    Отлично! Но имена повторяются (они не уникальны). Мы скоро это исправим.

    5. Агрегирование

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


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


    SELECT members.firstname AS "First Name", members.lastname AS "Last Name", count(*) AS "Number of books borrowed" FROM borrowings JOIN books ON borrowings.bookid=books.bookid JOIN members ON members.memberid=borrowings.memberid WHERE books.author="Dan Brown" GROUP BY members.firstname, members.lastname;

    Что даст нам нужный результат:


    First Name Last Name Number of books borrowed
    Mike Willis 1
    Ellen Horton 2

    Почти все агрегации идут вместе с выражением GROUP BY . Эта штука превращает таблицу, которую можно было бы получить запросом, в группы таблиц. Каждая группа соответствует уникальному значению (или группе значений) колонки, которую мы указали в GROUP BY . В нашем примере мы конвертируем результат из прошлого упражнения в группу строк. Мы также проводим агрегирование с count , которая конвертирует несколько строк в целое значение (в нашем случае это количество строк). Потом это значение приписывается каждой группе.


    Каждая строка в результате представляет собой результат агрегирования каждой группы.



    Можно прийти к логическому выводу, что все поля в результате должны быть или указаны в GROUP BY , или по ним должно производиться агрегирование. Потому что все другие поля могут отличаться друг от друга в разных строках, и если выбирать их SELECT "ом, то непонятно, какие из возможных значений нужно брать.


    В примере выше функция count обрабатывала все строки (так как мы считали количество строк). Другие функции вроде sum или max обрабатывают только указанные строки. Например, если мы хотим узнать количество книг, написанных каждым автором, то нужен такой запрос:


    SELECT author, sum(stock) FROM books GROUP BY author;

    Результат:


    author sum
    Robin Sharma 4
    Dan Brown 6
    John Green 3
    Amish Tripathi 2

    Здесь функция sum обрабатывает только колонку stock и считает сумму всех значений в каждой группе.

    6. Подзапросы


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

    6.1 Двумерная таблица

    Есть запросы, которые возвращают несколько колонок. Хороший пример это запрос из прошлого упражнения по агрегированию. Будучи подзапросом, он просто вернет еще одну таблицу, по которой можно делать новые запросы. Продолжая предыдущее упражнение, если мы хотим узнать количество книг, написанных автором “Robin Sharma”, то один из возможных способов - использовать подзапросы:


    SELECT * FROM (SELECT author, sum(stock) FROM books GROUP BY author) AS results WHERE author="Robin Sharma";

    Результат:



    Можно записать как: ["Robin Sharma", "Dan Brown"]


    2. Теперь используем этот результат в новом запросе:


    SELECT title, bookid FROM books WHERE author IN (SELECT author FROM (SELECT author, sum(stock) FROM books GROUP BY author) AS results WHERE sum > 3);

    Результат:


    title bookid
    The Lost Symbol 2
    Who Will Cry When You Die? 3
    Inferno 4

    Это то же самое, что:


    SELECT title, bookid FROM books WHERE author IN ("Robin Sharma", "Dan Brown"); 6.3 Отдельные значения

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


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


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


    select avg(stock) from books;

    Что дает нам:


    7. Операции записи

    Большинство операций записи в базе данных довольно просты, если сравнивать с более сложными операциями чтения.

    7.1 Update

    Синтаксис запроса UPDATE семантически совпадает с запросом на чтение. Единственное отличие в том, что вместо выбора колонок SELECT "ом, мы задаем знаения SET "ом.


    Если все книги Дэна Брауна потерялись, то нужно обнулить значение количества. Запрос для этого будет таким:


    UPDATE books SET stock=0 WHERE author="Dan Brown";

    WHERE делает то же самое, что раньше: выбирает строки. Вместо SELECT , который использовался при чтении, мы теперь используем SET . Однако, теперь нужно указать не только имя колонки, но и новое значение для этой колонки в выбранных строках.


    7.2 Delete

    Запрос DELETE это просто запрос SELECT или UPDATE без названий колонок. Серьезно. Как и в случае с SELECT и UPDATE , блок WHERE остается таким же: он выбирает строки, которые нужно удалить. Операция удаления уничтожает всю строку, так что не имеет смысла указывать отдельные колонки. Так что, если мы решим не обнулять количество книг Дэна Брауна, а вообще удалить все записи, то можно сделать такой запрос:


    DELETE FROM books WHERE author="Dan Brown"; 7.3 Insert

    Пожалуй, единственное, что отличается от других типов запросов, это INSERT . Формат такой:


    INSERT INTO x (a,b,c) VALUES (x, y, z);

    Где a , b , c это названия колонок, а x , y и z это значения, которые нужно вставить в эти колонки, в том же порядке. Вот, в принципе, и все.


    Взглянем на конкретный пример. Вот запрос с INSERT , который заполняет всю таблицу "books":


    INSERT INTO books (bookid,title,author,published,stock) VALUES (1,"Scion of Ikshvaku","Amish Tripathi","06-22-2015",2), (2,"The Lost Symbol","Dan Brown","07-22-2010",3), (3,"Who Will Cry When You Die?","Robin Sharma","06-15-2006",4), (4,"Inferno","Dan Brown","05-05-2014",3), (5,"The Fault in our Stars","John Green","01-03-2015",3); 8. Проверка

    Мы подошли к концу, предлагаю небольшой тест. Посмотрите на тот запрос в самом начале статьи. Можете разобраться в нем? Попробуйте разбить его на секции SELECT , FROM , WHERE , GROUP BY , и рассмотреть отдельные компоненты подзапросов.


    Вот он в более удобном для чтения виде:


    SELECT members.firstname || " " || members.lastname AS "Full Name" FROM borrowings INNER JOIN members ON members.memberid=borrowings.memberid INNER JOIN books ON books.bookid=borrowings.bookid WHERE borrowings.bookid IN (SELECT bookid FROM books WHERE stock> (SELECT avg(stock) FROM books)) GROUP BY members.firstname, members.lastname;

    Этот запрос выводит список людей, которые взяли из библиотеки книгу, у которой общее количество выше среднего значения.


    Результат:


    Full Name
    Lida Tyler

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

    Теги: Добавить метки