Spec-Zone .ru
спецификации, руководства, описания, API
|
MySQL 5.7 поддерживает встроенные (собственные) функции, определяемые пользователем функции (UDFs), и сохраненные функции. Этот раздел описывает, как сервер распознает, используется ли имя встроенной функции в качестве вызова функции или в качестве идентификатора, и как сервер определяет, какую функцию использовать в случаях, когда функции различных типов существуют с именем.
Встроенный Парсинг Имени функции
Синтаксический анализатор использует правила значения по умолчанию для того, чтобы проанализировать имена
встроенных функций. Эти правила могут быть изменены, включая IGNORE_SPACE
Режим SQL.
Когда синтаксический анализатор встречается со словом, которое является именем встроенной функции, это должно
определить, показывает ли имя вызов функции или является вместо этого ссылкой невыражения на идентификатор,
такой как имя таблицы или имя столбца. Например, в следующих операторах, первой ссылке на count
вызов функции, тогда как вторая ссылка является именем таблицы:
SELECT COUNT(*) FROM mytable;CREATE TABLE count (i INT);
Синтаксический анализатор должен распознать имя встроенной функции как указание на вызов функции только, анализируя, что, как ожидают, будет выражением. Таким образом, в контексте невыражения имена функций разрешаются как идентификаторы.
Однако, у некоторых встроенных функций есть специальные соображения парсинга или реализации, таким образом, синтаксический анализатор использует следующие правила по умолчанию, чтобы различить, используются ли их имена в качестве вызовов функции или в качестве идентификаторов в контексте невыражения:
Чтобы использовать имя в качестве вызова функции в выражении, не должно быть
никакого пробела между именем и следующим"(
"символ круглой скобки.
Наоборот, чтобы использовать имя функции в качестве идентификатора, это не должно сразу сопровождаться круглой скобкой.
Требование, чтобы вызовы функции быть записанными без пробела между именем и круглой скобкой применялись только
к встроенным функциям, у которых есть специальные соображения. COUNT
одно такое
имя. Точный список имен функций, для которых следование за пробелом определяет их интерпретацию, является
перечисленными в sql_functions[]
массив sql/lex.h
исходный файл. Перед MySQL 5.1 они являются довольно многочисленными (приблизительно 200), таким образом, можно
счесть самым легким обработать непробельное требование как применяющийся ко всем вызовам функции. В MySQL 5.1 и
позже, улучшения синтаксического анализатора сокращают к приблизительно 30 количество имен функций, на которые
влияют.
Для функций, не перечисленных в sql_functions[]
) массив, пробел не имеет значения.
Они интерпретируются как вызовы функции только когда использующийся в контексте выражения и могут использоваться
свободно в качестве идентификаторов иначе. ASCII
одно такое имя. Однако, для этих
имен функций, на которые невлияют, интерпретация может измениться по контексту выражения:
интерпретируется как встроенная функция, если
есть один с именем; в противном случае func_name
()
интерпретируется как определяемая пользователем функция или сохранил функцию, если Вы существуете
с тем именем. func_name
()
IGNORE_SPACE
Режим SQL может использоваться, чтобы изменить, как синтаксический анализатор обрабатывает имена функций,
которые чувствительны к пробелу:
С IGNORE_SPACE
отключенный, синтаксический анализатор интерпретирует имя
как вызов функции, когда нет никакого пробела между именем и следующей круглой скобкой. Это происходит,
даже когда имя функции используется в контексте невыражения:
mysql> CREATE TABLE count(i INT);
ERROR 1064 (42000): You have an error in your SQL syntax ...near 'count(i INT)'
Чтобы устранить ошибку и заставить имя быть обработанным как идентификатор, или используйте пробел после имени или запишите это как идентификатор в кавычках (или оба):
CREATE TABLE count (i INT);CREATE TABLE `count`(i INT);CREATE TABLE `count` (i INT);
С IGNORE_SPACE
включенный, синтаксический анализатор ослабляет требование
что там не быть никаким пробелом между именем функции и следующей круглой скобкой. Это обеспечивает
больше гибкости в записи вызовов функции. Например, любой из следующих вызовов функции являются
законными:
SELECT COUNT(*) FROM mytable;SELECT COUNT (*) FROM mytable;
Однако, включение IGNORE_SPACE
также имеет побочный эффект, что синтаксический
анализатор обрабатывает имена функций, на которые влияют, как зарезервированные слова (см. Раздел
9.3, "Зарезервированные слова"). Это означает, что пространство после имени больше
не показывает свое использование в качестве идентификатора. Имя может использоваться в вызовах
функции с или без следующего пробела, но вызывает синтаксическую ошибку в контексте невыражения,
если это не заключается в кавычки. Например, с IGNORE_SPACE
включенный, оба из следующих операторов перестали
работать с синтаксической ошибкой, потому что синтаксический анализатор интерпретирует count
как зарезервированное слово:
CREATE TABLE count(i INT);CREATE TABLE count (i INT);
Чтобы использовать имя функции в контексте невыражения, запишите это как идентификатор в кавычках:
CREATE TABLE `count`(i INT);CREATE TABLE `count` (i INT);
Включать IGNORE_SPACE
Режим SQL, используйте этот оператор:
SET sql_mode = 'IGNORE_SPACE';
IGNORE_SPACE
также включается определенными другими составными режимами такой как ANSI
это включает это в их значение:
SET sql_mode = 'ANSI';
Проверьте Раздел
5.1.7, "Режимы SQL Сервера", чтобы видеть, которому включают составные режимы IGNORE_SPACE
.
Чтобы минимизировать зависимость SQL кодируют на IGNORE_SPACE
устанавливая, используйте эти направляющие линии:
Избегите создавать UDFs или сохраненные функции, у которых есть то же самое имя как встроенная функция.
Избегайте использования имен функций в контексте невыражения. Например, эти
операторы использование count
(одно из имен функций, на которые влияют, на
которые, влияют IGNORE_SPACE
), таким образом, они перестали работать с или без
пробела после имени если IGNORE_SPACE
включается:
CREATE TABLE count(i INT);CREATE TABLE count (i INT);
Если следует использовать имя функции в контексте невыражения, запишите это как идентификатор в кавычках:
CREATE TABLE `count`(i INT);CREATE TABLE `count` (i INT);
Число имен функций, на которые влияют IGNORE_SPACE
был уменьшен значительно в MySQL 5.1.13, от приблизительно 200 до
приблизительно 30. С MySQL 5.1.13 только на следующие функции все еще влияют IGNORE_SPACE
установка.
ADDDATE |
BIT_AND |
BIT_OR |
BIT_XOR |
CAST |
COUNT |
CURDATE |
CURTIME |
DATE_ADD |
DATE_SUB |
EXTRACT |
GROUP_CONCAT |
MAX |
MID |
MIN |
NOW |
POSITION |
SESSION_USER |
STD |
STDDEV |
STDDEV_POP |
STDDEV_SAMP |
SUBDATE |
SUBSTR |
SUBSTRING |
SUM |
SYSDATE |
SYSTEM_USER |
TRIM |
VARIANCE |
VAR_POP |
VAR_SAMP |
Для более ранних версий MySQL проверьте содержание sql_functions[]
массив в sql/lex.h
исходный файл, чтобы видеть, которым влияют на функции IGNORE_SPACE
.
Несовместимость, предупреждающая: изменение в MySQL 5.1.13, который
сокращает количество имен функций, на которые влияют IGNORE_SPACE
улучшает непротиворечивость работы синтаксического анализатора.
Однако, это также представляет возможность несовместимости для старого кода SQL, который полагается на следующие
условия:
IGNORE_SPACE
отключается.
Присутствие или отсутствие пробела после имени функции используются, чтобы
различить встроенную функцию и сохраненную функцию, у которых есть то же самое имя, такой как PI()
против
PI ()
.
Для функций, которыми больше не влияют IGNORE_SPACE
с MySQL 5.1.13 больше не работает та стратегия. Любой из следующих
подходов может использоваться, если у Вас есть код, который подвергается предыдущей несовместимости:
Если у сохраненной функции есть имя, которое конфликтует со встроенной функцией,
обратитесь к сохраненной функции со спецификатором имени схемы, независимо от того, присутствует ли
пробел. Например, записать
или schema_name
.PI()
. schema_name
.PI ()
Альтернативно, переименуйте сохраненную функцию, чтобы использовать неконфликтное имя и вызовы изменения функции, чтобы использовать новое имя.
Разрешение Имени функции
Следующие правила описывают, как сервер разрешает ссылки на имена функций для функционального создания и вызова:
Встроенные функции и определяемые пользователем функции
Ошибка происходит, если Вы пытаетесь создать UDF с тем же самым именем как встроенная функция.
Встроенные функции и сохраненные функции
Возможно создать сохраненную функцию с тем же самым именем как встроенная функция, но вызвать
сохраненную функцию, необходимо квалифицировать это с именем схемы. Например, если Вы создаете
сохраненную названную функцию PI
в test
схема, Вы вызываете это как test.PI()
потому что сервер решает PI()
как
ссылка на встроенную функцию. Сервер создает предупреждение, если сохраненное имя функции
сталкивается со встроенным именем функции. Предупреждение может быть выведено на экран с SHOW WARNINGS
.
Определяемые пользователем функции и сохраненные функции
Определяемые пользователем функции и сохраненные функции совместно используют то же самое пространство имен, таким образом, невозможно создать UDF и сохраненную функцию с тем же самым именем.
У предыдущих правил разрешения имени функции есть импликации для того, чтобы обновить до версий MySQL, которые реализуют новые встроенные функции:
Если Вы уже создали определяемую пользователем функцию с именем и обновляете MySQL
до версии, которая реализует новую встроенную функцию с тем же самым именем, UDF становится недоступным.
Чтобы исправить это, использовать DROP
FUNCTION
отбрасывать UDF, и затем использовать CREATE FUNCTION
воссоздать UDF с различным неконфликтным именем.
Если новая версия MySQL реализует встроенную функцию с тем же самым именем как
существующая сохраненная функция, у Вас есть два вариантов: Переименуйте сохраненную функцию, чтобы
использовать неконфликтное имя, или изменение призывает к функции так, чтобы они использовали
спецификатор схемы (то есть, использовать
синтаксис).schema_name
.func_name
()