Глава 10. Структура языка
Эта глава обсуждает правила для того, чтобы написать следующие элементы
запросов SQL, используя MySQL:
10.1. Буквальные значения
Этот раздел описывает, как написать буквальные значения в MySQL. Они
включают строки, числа, шестнадцатеричные и битовые значения, булевы
значения и NULL . Раздел также покрывает различные нюансы, с
которыми Вы можете столкнуться, имея дело с этими основными типами в MySQL.
10.1.1. Строковые литералы
Строка последовательность байтов или символов в пределах одинарных
(' ) или двойных (" ) кавычек:
'a string'
"another string"
Заключенные в кавычки строки, помещенные друг рядом с другом, связаны в
единственную строку. Следующие строки эквивалентны:
'a string'
'a' ' ' 'string'
Если режим SQL ANSI_QUOTES
включен, строковые литералы могут быть заключены только в
одинарные кавычки, потому что строка, заключенная в двойные кавычки,
интерпретируется как идентификатор.
Двоичная строка строка байтов. У каждой двоичной строки есть
набор символов и сопоставление binary . Недвоичная строка
строка символов. У нее есть набор символов не binary и
сопоставление, которое совместимо с набором символов.
Для обоих типов строк сравнения основаны на числовых значениях строкового
модуля. Для двоичных строк модуль байт, сравнения используют числовые
значения байта. Для обычных строк модуль символ, и некоторые наборы символов
поддерживают мультибайтные символы. Сравнения используют числовые значения
кодов символов. Символьное упорядочивание кода функция строкового
сопоставления. Для получения дополнительной информации см.
раздел 11.1.8.5.
У буквальной строки символов может быть дополнительный набор символов
introducer и пункт COLLATE , чтобы определять это как строку,
которая использует особый набор символов и сопоставление:
[_charset_name ]'string '
[COLLATE collation_name ]
Примеры:
SELECT _latin1'string ';
SELECT _binary'string ';
SELECT _utf8'string ' COLLATE utf8_danish_ci;
Вы можете использовать N'literal ' (или
n'literal ' ), чтобы создать строку в наборе
национального характера. Эти запросы эквивалентны:
SELECT N'some text';
SELECT n'some text';
SELECT _utf8'some text';
Для информации об этих формах строкового синтаксиса см. разделы
11.1.3.7 и
11.1.3.8.
В пределах строки у определенных последовательностей нет особого
значения, если включен SQL-режим
NO_BACKSLASH_ESCAPES
. Каждая из этих последовательностей начинается с наклонной черты
влево (\ ), известной как escape character.
MySQL признает escape-последовательности, показанные в
таблице 10.1.
Для всех других escape-последовательностей проигнорирована наклонная черта
влево. Таким образом, экранированный символ интерпретируется, как будто его
не экранировали. Например, \x означает x .
Эти последовательности являются чувствительными к регистру. Например,
\b интерпретируется как клавиша Backspace, но
\B интерпретируется как B .
Обработка Escape сделана согласно набору символов, обозначенному переменной
character_set_connection . Это истина даже для строк, которым
предшествует introducer, который указывает на иной набор символов, как
обсуждается в разделе 11.1.3.6.
Таблица 10.1. Специальные символьные Escape-последовательности
Escape-последовательность |
Символ, представленный последовательностью |
\0
| ASCII NUL (X'00' ) |
\'
| Одинарная кавычка (' ) |
\"
| Двойная кавычка (" ) |
\b
| backspace |
\n
| newline (linefeed) |
\r
| carriage return |
\t
| Табуляция |
\Z
| ASCII 26 (Control+Z) |
\\
| backslash (\ ) |
\%
| % |
\_
| _ |
Символ ASCII 26 символов может быть закодирован как \Z ,
чтобы обойти проблему с ASCII 26 END-OF-FILE в Windows. ASCII 26
в пределах файла вызывает проблемы, если Вы пытаетесь использовать
mysql db_name <
file_name .
\% и \_ используются, чтобы искать буквальные
случаи % и _ в соответствующих образцу контекстах,
где они иначе интерпретировались бы как подстановочные символы. См. описание
оператора LIKE в
разделе 13.5.1.
Если Вы используете \% или \_ за пределами
соответствующих образцу контекстов они оцениваются к строкам
\% и \_ , но не % и _ .
Есть несколько способов включать символы кавычки в пределах строки:
Следующие запросы SELECT
демонстрируют, как работает заключение в кавычки:
mysql> SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello';
+-------+---------+-----------+--------+--------+
| hello | "hello" | ""hello"" | hel'lo | 'hello |
+-------+---------+-----------+--------+--------+
mysql> SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello";
+-------+---------+-----------+--------+--------+
| hello | 'hello' | ''hello'' | hel"lo | "hello |
+-------+---------+-----------+--------+--------+
mysql> SELECT 'This\nIs\nFour\nLines';
+--------------------+
| This
Is
Four
Lines |
+--------------------+
mysql> SELECT 'disappearing\ backslash';
+------------------------+
| disappearing backslash |
+------------------------+
Чтобы вставить двоичные данные в строковый столбец (например,
BLOB ), Вы должны представить
определенные символы escape-последовательностями. Наклонная черта влево
(\ ) и символ кавычки, используемый, чтобы заключить строку в
кавычки, нужно экранировать. В определенной окружающей среде клиента может
быть также необходимо экранировать NUL или Control+Z. Клиент
mysql
усекает заключенные в кавычки строки, содержащие символы NUL ,
если их не экранируют, а Control+Z может быть понят как END-OF-FILE в
Windows, если не экранирован. Для escape-последовательностей, которые
представляют каждый из этих символов см.
таблицу 10.1.
Сочиняя приложения, любую строку, которая могла бы содержать любой из этих
специальных символов, нужно должным образом экранировать прежде, чем строка
используется в качестве значения данных в запросе SQL, который посылают в
сервер MySQL. Вы можете сделать это двумя способами:
Обработайте строку с функцией, которая экранирует
специальные символы. В программе C Вы можете использовать функцию C API
mysql_real_escape_string_quote() . См.
раздел 25.8.7.56.
В пределах запросов SQL, которые создают другие запросы SQL, Вы можете
использовать функцию QUOTE()
. Интерфейс Perl DBI обеспечивает метод quote , чтобы
преобразовать специальные символы в надлежащие escape-последовательности. См.
раздел 25.10.
Другие языковые интерфейсы могут обеспечить подобную способность.
- Как альтернатива явной экранировке специальных символов, многие MySQL API
обеспечивают способность заполнителя, которая позволяет Вам вставить
специальные маркеры в строку запроса, и затем связать значения данных с ними,
когда Вы делаете запрос. В этом случае API заботится об экранировке
специальных символов в значениях для Вас.
10.1.2. Числовые литералы
Числовые литералы включают точное значение (целое число и
DECIMAL ) и
литералы приблизительной точности (с плавающей запятой).
Целые числа представлены как последовательность цифр. Числа могут включать
. как десятичный разделитель. Числам может предшествовать
- или + , чтобы указать на отрицательное или
положительное значение, соответственно. Числа, представленные в
экспоненциальном представлении с мантиссой и экспонентой, являются
числами приблизительной точности.
У числовых литералов точного значения есть целая часть или дробная часть,
или обе. Они могут быть со знаком. Примеры:
1 , .2 , 3.4 , -5 ,
-6.78 , +9.10 .
Числовые литералы приблизительной точности
представлены в экспоненциальном представлении с мантиссой и экспонентой.
Любая одна или обе части могут быть со знаком. Примеры: 1.2E3 ,
1.2E-3 , -1.2E3 , -1.2E-3 .
Два числа, которые выглядят подобными, могут быть обработаны по-другому.
Например, 2.34 точное значение (фиксированная точка) число,
тогда как 2.34E0 приблизительная точность
число (с плавающей запятой).
Тип данных DECIMAL
тип фиксированной точки, и вычисления точны. В MySQL тип
DECIMAL
имеет несколько синонимов:
NUMERIC ,
DEC ,
FIXED .
Типы целого числа также типы точного значения. Для получения дополнительной
информации о вычислениях точного значения см.
раздел 13.20.
Типы данных FLOAT
и DOUBLE
типы с плавающей запятой, и вычисления приблизительны. В MySQL типы, которые
синонимичны с FLOAT
или DOUBLE это
DOUBLE PRECISION и
REAL .
Целое число может использоваться в контексте с плавающей запятой:
это интерпретируется как эквивалентное число с плавающей запятой.
10.1.3. Литералы Date и Time
Значения Date и time могут быть представлены в нескольких форматах, таких
как заключенные в кавычки строки или как числа, в зависимости от точного типа
значения и других факторов. Например, в контекстах, где MySQL ожидает дату,
он интерпретирует любое из '2015-07-20' , '20150720'
и 20150720 именно как дату.
Этот раздел описывает приемлемые форматы для литералов времени и даты. Для
получения дополнительной информации о временных типах данных, таких как
диапазон разрешенных значений, консультирйтесь с этими разделами:
Стандартные литералы даты и времени SQL и ODBC.
Стандартный SQL разрешает временным литералам быть определенными, используя
ключевое слово типа и строку. Пространство между ключевым словом и
строкой является дополнительным.
DATE 'str '
TIME 'str '
TIMESTAMP 'str '
MySQL признает те конструкции и также соответствующий синтаксис ODBC:
{ d 'str ' }
{ t 'str ' }
{ ts 'str ' }
MySQL использует ключевое слово типа, и эти конструкции производят значения
DATE ,
TIME и
DATETIME , соответственно,
включая дробную часть секунд, если определена. Синтаксис
TIMESTAMP производит значение
DATETIME в MySQL потому, что
DATETIME имеет диапазон,
который более близко соответствует стандартному SQL-типу
TIMESTAMP ,
у которого есть диапазон года от 0001 до 9999 .
В MySQL TIMESTAMP диапазон года
от 1970 до 2038 .
Строковые и числовые литералы в контексте даты и времени.
MySQL признает значения DATE
в этих форматах:
Как строка в формате 'YYYY-MM-DD' или
'YY-MM-DD' . Расслабленный синтаксис разрешен: любой символ
пунктуации может использоваться в качестве разделителя между частями даты.
Например, '2012-12-31' , '2012/12/31' ,
'2012^12^31' и '2012@12@31' эквивалентны.
- Как строка без разделителей в формате
'YYYYMMDD' или 'YYMMDD' , при условии, что строка
имеет смысл как дата. Например, '20070523' и
'070523' интерпретируются как '2007-05-23' , но
'071332' незаконно (у этого значения есть бессмысленные части
месяца и дня) и становится '0000-00-00' .
- Как число в формате
YYYYMMDD или YYMMDD ,
при условии, что число имеет смысл как дата. Например,
19830905 и 830905 интерпретируются как
'1983-09-05' .
MySQL признает DATETIME и
TIMESTAMP в этих форматах:
Как строка в форматах 'YYYY-MM-DD HH:MM:SS' или
'YY-MM-DD HH:MM:SS' . Расслабленный
синтаксис разрешен здесь также: любой символ пунктуации может использоваться
в качестве разделителя между частями даты или времени. Например,
'2012-12-31 11:30:45' , '2012^12^31 11+30+45' ,
'2012/12/31 11*30*45' и '2012@12@31 11^30^45' .
Единственный разделитель, признанный между датой и дробной частью секунд
в части времени, является десятичной запятой.
Дата и части времени могут быть отделены T вместо пробела.
Например, '2012-12-31 11:30:45' эквивалент
'2012-12-31T11:30:45' .
- Как строка без разделителей в формате
'YYYYMMDDHHMMSS' или 'YYMMDDHHMMSS' ,
при условии, что строка имеет смысл как дата. Например,
'20070523091528' и '070523091528'
интерпретируются как '2007-05-23 09:15:28' , но
'071122129015' незаконно (у этого значения есть бессмысленная
часть минут) и становится '0000-00-00 00:00:00' .
- Как число в формате
YYYYMMDDHHMMSS или
YYMMDDHHMMSS , при условии, что число имеет смысл как дата.
Например, 19830905132800 и 830905132800
интерпретируются как '1983-09-05 13:28:00' .
Значения DATETIME или
TIMESTAMP могут включать
дробную часть секунд с точностью до микросекунд (6 цифр). Дробная часть
должна всегда отделяться от остальной части времени десятичной запятой:
никакой другой дробный разделитель секунд не признан. Для информации о
поддержке частей секунд в MySQL см.
раздел 12.3.6.
Даты, содержащие значения года с двумя цифрами, неоднозначны, потому что
столетие неизвестно. MySQL интерпретирует значения года с двумя цифрами,
используя эти правила:
Для значений, определенных как строки, которые включают разделители части
даты, не нужно определять две цифры для значений месяца или дня, которые
меньше 10 . '2015-6-9' воспринимается как
'2015-06-09' . Точно так же для значений, определенных как
строки, которые включают разделители части времени, не нужно определять две
цифры в значениях часа, минуты или секунды, которые меньше 10 .
'2015-10-30 1:2:3' то же самое, как
'2015-10-30 01:02:03' .
Значения, определенные как числа, должны быть длиной в 6, 8, 12 или 14
цифр. Если число 8 или 14 цифр, оно, как предполагается, находится в
формате YYYYMMDD или YYYYMMDDHHMMSS , а
год задан первыми 4 цифрами. Если число 6 или 12 цифр, оно, как
предполагается, в формате YYMMDD или YYMMDDHHMMSS ,
а год задан первыми 2 цифрами. Числа, которые не являются ни одной из этих
длин, дополняются начальными нулями к самой близкой длине.
Значения, определенные как неразграниченные строки, интерпретируются
согласно их длине. Для строки в 8 или 14 символов, год, как предполагается,
задан первыми 4 символами. Иначе год, как предполагается, задан первыми 2
символами. Строка интерпретируется слева направо, чтобы найти год, месяц,
день, час, минуту и секунду. Это означает, что Вы не должны использовать
строки, у которых есть меньше 6 символов. Например, если Вы определяете
'9903' , считая, что это задает март 1999, MySQL преобразует это
в нулевую дату. Это происходит, потому что значения
года и месяца 99 и 03 , но дневная часть
отсутствует. Однако, Вы можете явно определить значение ноля, чтобы
представить недостающие части месяца или дня. Например, чтобы вставить
значение '1999-03-00' , используйте '990300' .
MySQL признает значения TIME
в этих форматах:
Как строка в формате 'D HH:MM:SS' .
Вы можете также использовать один из следующих вариантов:
'HH:MM:SS' , 'HH:MM' , 'D HH:MM' ,
'D HH' или 'SS' . Здесь D представляет
дни и может иметь значение от 0 до 34.
- Как строка без разделителей в формате
'HHMMSS'
при условии, что это имеет смысл как время. Например, '101112'
понято как '10:11:12' , но '109712' недопустимо
(у этого есть бессмысленная минутная часть), и становится
'00:00:00' .
- Как число в виде
HHMMSS при условии, что это имеет смысл как
время. Например, 101112 понимается как '10:11:12' .
Следующие альтернативные форматы также поняты: SS ,
MMSS или HHMMSS .
Дробная часть секунд признана в форматах
'D HH:MM:SS.fraction' , 'HH:MM:SS.fraction' ,
'HHMMSS.fraction' и HHMMSS.fraction , здесь
fraction дробная часть до микросекунд (6 цифр). Дробная часть
должна всегда отделяться от остальной части времени десятичной запятой,
никакой другой дробный разделитель секунд не признан. Для информации о
дробной поддержке секунд в MySQL см.
раздел 12.3.6.
Для значений TIME , определенных
как строки, которые включают разделитель части времени, не нужно определять
две цифры часов, минут или значений секунд, которые меньше 10 .
'8:3:2' означает '08:03:02' .
10.1.4. Шестнадцатеричные литералы
Шестнадцатеричные литералы написаны, используя нотацию
X'val ' или
0xval , где val
содержит шестнадцатеричные цифры (0..9 , A..F ).
Регистр символов не имеет значения. Лидирующий 0x
является чувствительным к регистру и не может быть написан как
0X .
Допустимые шестнадцатеричные литералы:
X'01AF'
X'01af'
x'01AF'
x'01af'
0x01AF
0x01af
Недопустимые шестнадцатеричные литералы:
X'0G' (G не шестнадцатеричная цифра)
0X01AF (0X должен быть записан как 0x)
Значения, использующие формат X'val '
должны содержать четное число цифр, или синтаксическая ошибка происходит.
Чтобы исправить проблему, дополните значение начальным нулем:
mysql> SET @s = X'FFF';
ERROR 1064 (42000): You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server
version for the right syntax to use near 'X'FFF''
mysql> SET @s = X'0FFF';
Query OK, 0 rows affected (0.00 sec)
Значения, использующие формат 0xval ,
которые содержат нечетное число цифр, обработаны как будто есть начальный
0 . Например, 0xaaa это 0x0aaa .
По умолчанию, шестнадцатеричный литерал двоичная строка, где каждая пара
шестнадцатеричных цифр представляет символ:
mysql> SELECT X'4D7953514C', CHARSET(X'4D7953514C');
+---------------+------------------------+
| X'4D7953514C' | CHARSET(X'4D7953514C') |
+---------------+------------------------+
| MySQL | binary |
+---------------+------------------------+
mysql> SELECT 0x5461626c65, CHARSET(0x5461626c65);
+--------------+-----------------------+
| 0x5461626c65 | CHARSET(0x5461626c65) |
+--------------+-----------------------+
| Table | binary |
+--------------+-----------------------+
Шестнадцатеричный литерал может иметь дополнительный набор символов
introducer и предложение COLLATE , чтобы определять это как
строку, которая использует особый набор символов и сопоставление:
[_charset_name ] X'val ' [COLLATE collation_name ]
Примеры:
SELECT _latin1 X'4D7953514C';
SELECT _utf8 0x4D7953514C COLLATE utf8_danish_ci;
Формат 0xval также позволяет introducer.
В числовых контекстах MySQL обрабатывает шестнадцатеричный литерал как
BIGINT (64-bit integer).
Чтобы гарантировать числовую обработку шестнадцатеричного литерала,
используйте это в числовом контексте. Способы сделать это включают добавление
0 или использование CAST(... AS
UNSIGNED) . Например, шестнадцатеричный литерал, назначенный
определяемой пользователем переменной, является двоичной строкой по
умолчанию. Чтобы назначить значение в качестве числа, используйте
это в числовом контексте:
mysql> SET @v1 = X'41';
mysql> SET @v2 = X'41'+0;
mysql> SET @v3 = CAST(X'41' AS UNSIGNED);
mysql> SELECT @v1, @v2, @v3;
+-----+-----+-----+
| @v1 | @v2 | @v3 |
+-----+-----+-----+
| A | 65 | 65 |
+-----+-----+-----+
Пустое шестнадцатеричное значение (X'' ) оценивается к двоичной
строке с нулевой длиной. Преобразованная в число она производит 0:
mysql> SELECT CHARSET(X''), LENGTH(X'');
+--------------+-------------+
| CHARSET(X'') | LENGTH(X'') |
+--------------+-------------+
| binary | 0 |
+--------------+-------------+
mysql> SELECT X''+0;
+-------+
| X''+0 |
+-------+
| 0 |
+-------+
Формат X'val ' основан на стандартном SQL.
0x основан на ODBC, для которого шестнадцатеричные строки часто
используются, чтобы поставлять значения для столбцов
BLOB .
Чтобы преобразовать строку или число к строке в шестнадцатеричном формате,
используйте фугкцию HEX() :
mysql> SELECT HEX('cat');
+------------+
| HEX('cat') |
+------------+
| 636174 |
+------------+
mysql> SELECT X'636174';
+-----------+
| X'636174' |
+-----------+
| cat |
+-----------+
10.1.5. Битовые строки
Битовые строки написаны, используя формат
b'val ' или
0bval . val
двоичное значение, использующее 0 и 1. Регистр лидирующего b
не имеет значения. 0b является чувствительным к регистру и не
может быть написан как 0B .
Допустимые литералы битового значения:
b'01'
B'01'
0b01
Недопустимые литералы битового значения:
b'2'(2 не может быть использована)
0B01 (0B надо писать как 0b)
По умолчанию, буквальное битовое значение является двоичной строкой:
mysql> SELECT b'1000001', CHARSET(b'1000001');
+------------+---------------------+
| b'1000001' | CHARSET(b'1000001') |
+------------+---------------------+
| A | binary |
+------------+---------------------+
mysql> SELECT 0b1100001, CHARSET(0b1100001);
+-----------+--------------------+
| 0b1100001 | CHARSET(0b1100001) |
+-----------+--------------------+
| a | binary |
+-----------+--------------------+
У буквального битового значения может быть дополнительный набор символов
introducer и COLLATE , чтобы определять это как строку, которая
использует особый набор символов и сопоставление:
[_charset_name ] b'val ' [COLLATE collation_name ]
Примеры:
SELECT _latin1 b'1000001';
SELECT _utf8 0b1000001 COLLATE utf8_danish_ci;
В числовых контекстах MySQL обрабатывает литералы как целое число. Чтобы
гарантировать числовую обработку, используйте это в числовом контексте.
Способы сделать это включают добавление 0 или использование
CAST(... AS UNSIGNED) .
Например, литерал, назначенный определяемой пользователем переменной,
является двоичной строкой по умолчанию. Чтобы назначить значение в качестве
числа, используйте это в числовом контексте:
mysql> SET @v1 = b'1100001';
mysql> SET @v2 = b'1100001'+0;
mysql> SET @v3 = CAST(b'1100001' AS UNSIGNED);
mysql> SELECT @v1, @v2, @v3;
+-----+-----+-----+
| @v1 | @v2 | @v3 |
+-----+-----+-----+
| a | 97 | 97 |
+-----+-----+-----+
Пустое битовое значение (b'' ) оценивается к двоичной строке
нулевой длины. Преобразованная в число она производит 0:
mysql> SELECT CHARSET(b''), LENGTH(b'');
+--------------+-------------+
| CHARSET(b'') | LENGTH(b'') |
+--------------+-------------+
| binary | 0 |
+--------------+-------------+
mysql> SELECT b''+0;
+-------+
| b''+0 |
+-------+
| 0 |
+-------+
Формат битового значения удобен для того, чтобы определить значения, которые
будут назначены столбцам BIT :
mysql> CREATE TABLE t (b BIT(8));
mysql> INSERT INTO t SET b = b'11111111';
mysql> INSERT INTO t SET b = b'1010';
mysql> INSERT INTO t SET b = b'0101';
Битовые значения в наборах результатов возвращены как двоичные значения,
которые, возможно, не выводятся на экран хорошо. Чтобы преобразовать немного
значения в пригодную для печати форму, используйте это в числовом контексте
или используйте конверсионную функцию, например,
BIN() .
Старший разряд 0 бита не выведен на экран в переделанном значении.
mysql> SELECT b+0, BIN(b), OCT(b), HEX(b) FROM t;
+-----+----------+--------+--------+
| b+0 | BIN(b) | OCT(b) | HEX(b) |
+-----+----------+--------+--------+
| 255 | 11111111 | 377 | FF |
| 10 | 1010 | 12 | A |
| 5 | 101 | 5 | 5 |
+-----+----------+--------+--------+
10.1.6. Boolean
Константы TRUE и FALSE оцениваются как
1 и 0 , соответственно.
Постоянные имена могут быть написаны в любом регистре.
mysql> SELECT TRUE, true, FALSE, false;
-> 1, 1, 0, 0
10.1.7. NULL
Значение NULL означает "нет данных".
NULL может быть написан в любом регистре символов.
Синоним \N (чувствительный к регистру).
Для экспорта и импорта текстовых файлов через
LOAD DATA INFILE или
SELECT ... INTO OUTFILE
NULL представлен последовательностью \N . См.
раздел 14.2.6.
Знайте что NULL отличается от таких значений, как
0 для числовых типов или пустой строки для строковых типов. Для
получения дополнительной информации см.
раздел B.5.4.3.
10.2. Названия объекта схемы
Определенные объекты в пределах MySQL, включая базу данных, таблицу,
индекс, столбец, псевдоним, представление, хранимую процедуру, разделение,
табличное пространство и другие названия объекта известны как идентификаторы.
Этот раздел описывает допустимый синтаксис для идентификаторов в MySQL.
Раздел 10.2.2
описывает, какие типы идентификаторов являются чувствительными к регистру и
при каких условиях.
Идентификатор может быть заключен в кавычки или написан без них. Если
идентификатор содержит специальные символы или является зарезервированным
словом, Вы должны заключить его в кавычки всякий раз,
когда Вы обращаетесь к нему. Исключение: зарезервированное слово, которое
следует за периодом в полностью определенном имени, должно быть
идентификатором, таким образом, оно не должно быть заключено в кавычки.
Зарезервированные слова перечислены в
разделе 10.3.
Идентификаторы преобразованы в Unicode внутренне.
Они могут содержать эти символы:
Разрешенные символы в идентификаторах:
ASCII: [0-9,a-z,A-Z$_] (основные латинские буквы,
цифры 0-9, доллар, подчеркивание).
- Расширенные: U+0080 .. U+FFFF.
Разрешенные символы в заключенных в кавычки идентификаторах включают
полный Unicode Basic Multilingual Plane (BMP), кроме U+0000:
ASCII: U+0001 .. U+007F.
- Расширенные: U+0080 .. U+FFFF.
ASCII NUL (U+0000) и дополнительные символы (U+10000 и выше) не
разрешен в любых идентификаторах.
- Идентификаторы могут начаться с цифры, но если не заключены в кавычки,
не могут состоять исключительно из цифр.
- База данных, таблица и имена столбцов не могут закончиться пробелами.
Символ кавычки идентификатора обратная галочка (` ):
mysql> SELECT * FROM `select` WHERE `select`.id > 100;
Если включен режим SQL
ANSI_QUOTES также допустимо заключить идентификаторы в кавычки в
пределах двойных кавычек:
mysql> CREATE TABLE "test" (col INT);
ERROR 1064: You have an error in your SQL syntax...
mysql> SET sql_mode='ANSI_QUOTES';
mysql> CREATE TABLE "test" (col INT);
Query OK, 0 rows affected (0.00 sec)
Режим ANSI_QUOTES
заставляет сервер интерпретировать заключенные в двойные кавычки строки как
идентификаторы. Следовательно, когда этот режим включен, строковые литералы
должны быть указаны в пределах одинарных кавычек. Они не могут быть указаны в
пределах двойных кавычек. Режим SQL управляют как описано в
разделе 6.1.8.
Символы кавычки идентификатора могут быть включены в пределах
идентификатора, если Вы заключаете идентификатор в кавычки. Если символ,
который будет включен в пределах идентификатора, является тем же самым,
которым заключен идентификатор в кавычки непосредственно, то Вы должны
удвоить символ. Следующий запрос составляет таблицу a`b ,
которая содержит столбец c"d :
mysql> CREATE TABLE `a``b` (`c"d` INT);
В избранном списке запроса заключенный в кавычки псевдоним столбца может
быть определен, используя идентификатор или строковые
символы заключения в кавычки:
mysql> SELECT 1 AS `one`, 2 AS 'two';
+-----+-----+
| one | two |
+-----+-----+
| 1 | 2 |
+-----+-----+
В другом месте в запросе заключенные в кавычки ссылки на псевдоним должны
использовать заключение в кавычки идентификатора, или ссылка будет обработана
как буквальная строка.
Рекомендуется, чтобы Вы не использовали имена, которые начинаются с
M e или
M eN , где
M и N целые числа. Например, надо
избегать использования 1e как идентификатора, потому что такое
выражение, как 1e+3 неоднозначно. В зависимости от контекста это
могло бы интерпретироваться как выражение 1e + 3
или как число 1e+3 .
Будьте осторожны, используя
MD5() , чтобы произвести имена таблиц, потому что это может
произвести имена в незаконных или неоднозначных форматах, таких, как
только что описанные.
Пользовательская переменная не может использоваться непосредственно в
запросе SQL как идентификатор или как часть идентификатора. См.
раздел 10.4.
Специальные символы в именах базы данных и таблиц закодированы в
соответствующие имена файловой системы как описано в
разделе 10.2.3.
Следующая таблица описывает максимальную длину для
каждого типа идентификатора.
Идентификатор |
Максимальная длина (символов) |
База данных | 64 |
Таблица | 64 |
Столбец | 64 |
Индекс | 64 |
Ограничение | 64 |
Сохраненная программа | 64 |
Представление | 64 |
Табличное пространство | 64 |
Сервер | 64 |
Группа файла журнала | 64 |
Псевдоним | 256 |
Составная метка запроса | 16 |
Определяемая пользователем переменная | 64 |
Псевдонимы для имен столбцов в CREATE
VIEW проверены по максимальной длине столбца 64 символов (не
максимальная длина псевдонима 256 символов).
Идентификаторы сохранены, используя Unicode (UTF-8). Это относится к
идентификаторам в табличных определениях и к идентификаторам, сохраненным в
таблицах привилегий в базе данных mysql . Размеры строковых
столбцов идентификатора в таблицах привилегий измерены в символах. Вы можете
использовать мультибайтные символы, не сокращая количество символов,
разрешенных для значений, сохраненных в этих столбцах. Как обозначено ранее,
допустимые символы Unicode Basic Multilingual Plane (BMP).
Дополнительные символы не разрешены.
10.2.1.
Спецификаторы идентификатора
MySQL разрешает имена, которые состоят из единственного или многих
идентификаторов. Компоненты имени многократной части должны быть отделены
символом точки (. ). Начальные части имени рассматриваются как
спецификаторы, которые затрагивают контекст, в пределах которого
интерпретируется заключительный идентификатор.
В MySQL Вы можете сослаться на столбец таблицы, используя любую
из следующих форм.
Ссылка столбца | Значение
|
col_name |
Столбец col_name из любой таблицы в запросе со
столбцом с этим именем. |
tbl_name.col_name |
Столбец col_name таблицы
tbl_name из базы данных по умолчанию. |
db_name.tbl_name.col_name |
Столбец col_name таблицы
tbl_name базы данных
db_name . |
Символ спецификатора отдельный маркер и не должен быть непрерывным со
связанными идентификаторами. Например,
tbl_name.col_name и
tbl_name . col_name эквивалентны.
Если какие-либо компоненты имени составной части требуют заключения в
кавычки, их заключают в кавычки индивидуально вместо того, чтобы заключить
имя в кавычки в целом. Например, надо писать `my-table`.`my-column`
, а не `my-table.my-column` .
Зарезервированное слово, которое следует за точкой в полностью
определенном имени, должно быть идентификатором, таким образом, в этом
контексте оно не должно быть заключено в кавычки.
Вы не должны определить префикс tbl_name или
db_name.tbl_name для ссылки столбца в запросе, если
ссылка не была бы неоднозначна. Предположите, что таблицы
t1 и t2 содержат столбец
c , и Вы получаете c в запросе
SELECT , который использует
t1 и t2 . В этом случае c
неоднозначно, потому что это не уникально среди таблиц, используемых в
запросе. Вы должны квалифицировать это с именем таблицы как
t1.c или t2.c , чтобы указать, какую таблицу Вы
имеете в виду. Точно так же, чтобы получить данные из таблиц
t в базе данных db1 и t в базе данных
db2 в том же самом запросе Вы должны обратиться к столбцам в тех
таблицах как db1.t.col_name и
db2.t.col_name .
Синтаксис .tbl_name означает таблицу
tbl_name в базе данных по умолчанию. Этот синтаксис
принят для совместимости с ODBC, потому что некоторые программы ODBC передают
имена таблиц с префиксным символом . .
10.2.2.
Чувствительность к регистру идентификатора
В MySQL базы данных соответствуют каталогам в пределах каталога данных.
Каждая таблица в пределах базы данных соответствует по крайней мере одному
файлу в пределах каталога базы данных (возможно, больше, в зависимости от
механизма хранения). Триггеры также соответствуют файлам. Следовательно,
чувствительность к регистру операционной системы играет роль в
чувствительности базы данных, таблицы и прочих имен. Это означает, что такие
имена не являются чувствительными к регистру в Windows, но являются
чувствительными к регистру в большинстве вариантов Unix. Одно известное
исключение: OS X, которая основана на Unix, но использует тип файловой
системы по умолчанию (HFS+), который не является чувствительным к регистру.
Однако, OS X также поддерживает тома UFS, которые являются чувствительными к
регистру так же, как в любой Unix. См.
раздел 1.8.1. Переменная
lower_case_table_names также затрагивает, как сервер обрабатывает
чувствительность к регистру идентификатора, как описано позже в этом разделе.
Хотя база данных, таблица и триггеры не являются чувствительными к
регистру на некоторых платформах, Вы не должны обратиться к одному из них,
используя разный регистр в пределах того же самого запросы. Следующий запрос
не работает, потому что он отсылает к таблице my_table как к
MY_TABLE :
mysql> SELECT * FROM my_table WHERE MY_TABLE.col=1;
Столбцы, индексы, сохраненные программы и имена событий не являются
чувствительными к регистру на любой платформе.
Однако, имена групп файла регистрации являются чувствительными к регистру.
Это отличается от стандартного SQL.
По умолчанию, табличные псевдонимы являются чувствительными к регистру в
Unix, но это не так в Windows или OS X. Следующий запрос не работает в Unix,
потому что это отсылает к псевдониму a как к A :
mysql> SELECT col_name FROM tbl_name AS a
-> WHERE a.col_name = 1 OR A.col_name = 2;
Однако, этот же самый запрос разрешен в Windows. Чтобы избежать проблем,
вызванных такими различиями, лучше принимать последовательное соглашение,
такое как всегда создавать и обращаться к базам данных и таблицам, используя
строчные имена. Это соглашение рекомендуется для максимальной
мобильности и простоты использования.
То, как имена таблиц и имена базы данных сохранены на диске и используются
в MySQL, затронуто переменной
lower_case_table_names , которую Вы можете установить, запуская
mysqld.
lower_case_table_names может взять значения, показанные в
следующей таблице. Эта переменная не затрагивает
чувствительность к регистру идентификаторов триггеров. В Unix значение по
умолчанию
lower_case_table_names 0. В Windows 1. В OS X 2.
Значение | Смысл
|
0 |
Имена таблиц и баз данных сохранены на диске, используя нижний регистр,
определенный в CREATE
TABLE или CREATE
DATABASE . Сравнения имен являются чувствительными к регистру. Вы
не должны установить эту переменную в 0, если Вы выполняете MySQL на системе,
у которой есть нечувствительные к регистру имена файла (Windows или OS X).
Если Вы установите ее в 0 с
--lower-case-table-names=0 на нечувствительной к регистру файловой
системе и обратитесь к именам таблиц MyISAM , используя различный
регистр, индекс может быть поврежден. |
1 |
Имена таблиц сохранены в нижнем регистре на диске, и сравнения не являются
чувствительными к регистру. MySQL преобразовывает все имена таблиц в нижний
регистр при хранении и поиске. Это поведение также относится к именам базы
данных и табличным псевдонимам. |
2 |
Имена таблиц и баз данных сохранены на диске, используя регистр, определенный
в CREATE
TABLE или CREATE
DATABASE , но MySQL преобразовывает их в нижний регистр при поиске.
Сравнения имени не являются чувствительными к регистру. Это работает
только с файловыми системами, которые не являются
чувствительными к регистру! Имена таблиц InnoDB сохранены в
нижнем регистре, как при lower_case_table_names=1 .
|
Если Вы используете MySQL только на одной платформе, Вы не должны обычно
изменять
lower_case_table_names . Однако, Вы можете столкнуться с
трудностями, если Вы хотите передать таблицы между платформами, которые
отличаются по чувствительности к регистру файловой системы. Например, в Unix
у Вас может быть две различных таблицы, названные my_table и
MY_TABLE , но в Windows эти два имени считают идентичными. Чтобы
избежать проблем передачи данных, являющихся результатом регистра
имен базы данных или таблиц, у Вас есть две опции:
Использовать lower_case_table_names=1 на всех
системах. Основной недостаток с этим: когда Вы используете
SHOW TABLES или
SHOW DATABASES ,
Вы не видите имена в их оригинальном регистре.
- Использовать
lower_case_table_names=0 в Unix и
lower_case_table_names=2 в Windows. Это сохраняет регистр
имен базы данных и таблиц. Недостаток этого: Вы должны гарантировать, что
Ваши запросы всегда относятся к Вашим именам базы данных и таблиц с
правильным регистром в Windows. Если Вы передаете свои запросы Unix, где
регистр является существенным, они не работают, если
регистр является неправильным.
Исключение: Если Вы используете таблицы
InnoDB и пытаетесь избежать этих проблем передачи данных, Вы
должны установить
lower_case_table_names в 1 на всех платформах, чтобы вынудить
преобразовать имена в нижний регистр.
Если Вы планируете установить
lower_case_table_names в 1 в Unix, Вы должны сначала преобразовать
свою старую базу данных и имена таблиц к нижнему регистру прежде, чем
остановить mysqld
и перезапустить с новой переменной установкой. Чтобы сделать это для
отдельной таблицы, надо использовать
RENAME TABLE :
RENAME TABLE T1 TO t1;
Чтобы преобразовать одну или более баз данных, выведите их перед установкой
lower_case_table_names , затем удалите базы данных и перезагрузите
их после установки
lower_case_table_names :
Используйте
mysqldump, чтобы вывести каждую базу данных:
mysqldump --databases db1 > db1.sql
mysqldump --databases db2 > db2.sql
...
Сделайте это для каждой базы данных, которая должна быть обновлена.
- Используйте
DROP DATABASE , чтобы удалить
каждую базу данных.
- Остановите сервер, установите
lower_case_table_names и перезапустите сервер.
- Перезагрузите файл дампа для каждой базы данных. Поскольку
lower_case_table_names установлена, каждое имя базы данных и
таблицы будет преобразовано в нижний регистр, поскольку это обновлено:
mysql < db1.sql
mysql < db2.sql
...
Названия объекта можно считать дубликатами, если их формы верхнего
регистра равны согласно двоичному сопоставлению. Это истина для названий
курсоров, условий, процедур, функции, точек сохранения, местных переменных
сохраненных программ и плагинов. Это не истина для названий столбцов,
ограничений, баз данных, разделений, запросов, подготовленных с
PREPARE , триггеров, таблиц,
пользователей и определяемых пользователем переменных.
Чувствительность к регистру файловой системы может затронуть поиски в
строковых столбцах таблиц INFORMATION_SCHEMA . Подробности в
разделе 11.1.8.7
.
10.2.3. Отображение идентификаторов
к именам файлов
Есть связь между идентификаторами базы данных и таблиц и именами в
файловой системе. Для базовой структуры MySQL представляет каждую базу данных
как каталог в каталоге данных, и в зависимости от механизма хранения, каждая
таблица может быть представлена одним или более файлами в соответствующем
каталоге базы данных.
Для файлов с данными и индексных файлов, точное представление на диске
определено механизмом хранения. Эти файлы могут храниться в каталоге базы
данных, или информация может храниться в отдельном файле. Данные
InnoDB хранятся в файлах с данными InnoDB. Если Вы используете
табличные пространства с InnoDB , тогда определенные файлы
табличного пространства, которые Вы создаете, используются вместо этого.
Любой символ является законным в идентификаторах, кроме ASCII NUL
(X'00' ). MySQL кодирует любые символы, которые проблематичны в
соответствующих объектах файловой системы, когда создает каталоги базы данных
или табличные файлы:
Латинские буквы (a..zA..Z ), цифры
(0..9 ) и подчеркивание (_ ) закодированы как есть.
Следовательно, их чувствительность к регистру непосредственно зависит от
особенностей файловой системы.
- Все другие национальные символы из алфавитов, у которых есть отображение
верхнего/нижнего регистра, закодированы как показано в следующей таблице.
Значения в столбце Code Range это значения UCS-2.
Code Range | Шаблон |
Номер | Используется |
Не используется | Блоки |
00C0..017F | [@][0..4][g..z] |
5*20= 100 | 97 | 3 |
Latin-1 Supplement + Latin Extended-A |
0370..03FF | [@][5..9][g..z] | 5*20= 100 |
88 | 12 | Greek and Coptic |
0400..052F | [@][g..z][0..6] | 20*7= 140 |
137 | 3 | Cyrillic + Cyrillic Supplement |
0530..058F | [@][g..z][7..8] | 20*2= 40 |
38 | 2 | Armenian |
2160..217F | [@][g..z][9] | 20*1= 20 |
16 | 4 | Number Forms |
0180..02AF | [@][g..z][a..k] | 20*11=220 |
203 | 17 | Latin Extended-B + IPA Extensions |
1E00..1EFF | [@][g..z][l..r] | 20*7= 140 |
136 | 4 | Latin Extended Additional |
1F00..1FFF | [@][g..z][s..z] | 20*8= 160 |
144 | 16 | Greek Extended |
.... .... | [@][a..f][g..z] | 6*20= 120 |
0 | 120 | RESERVED |
24B6..24E9 | [@][@][a..z] | 26 | 26
| 0 | Enclosed Alphanumerics |
FF21..FF5A | [@][a..z][@] | 26 | 26
| 0 | Halfwidth и Fullwidth формы |
Один из байтов в последовательности кодирует регистр. Например:
LATIN CAPITAL LETTER A WITH GRAVE кодируется как
@0G , тогда как LATIN SMALL LETTER A WITH GRAVE
кодируется как @0g . Здесь третий байт (G или
g ) указывает на регистр. На нечувствительной к регистру файловой
системе оба символа будут обработаны как то же самое.
Для некоторых блоков, таких как Cyrillic, второй байт определяет
регистр. Для других блоков, таких как Latin1 Supplement, третий байт
определяет регистр. Если два байта в последовательности символы (как в
Greek Extended), крайние левые символы определяют регистр. Все другие байты
должны быть в нижнем регистре.
- Все небуквенные символы кроме подчеркивания (
_ ), так же как
буквы алфавитов, у которых нет отображения верхнего/нижнего регистра (такого,
как иврит) закодированы, используя шестнадцатеричное представление, используя
строчные буквы для шестнадцатеричных цифр a..f :
0x003F -> @003f
0xFFFF -> @ffff
Шестнадцатеричные значения соответствуют символьным значениям в
двухбайтовом наборе символов ucs2 .
В Windows некоторые имена, например, nul , prn и
aux закодированы, добавляя @@@ к имени, когда
сервер создает соответствующий файл или каталог. Это происходит на всех
платформах для мобильности соответствующего объекта базы
данных между платформами.
10.2.4.
Парсинг имени функции и разрешение
MySQL 8.0 поддерживает встроенные функции, определяемые пользователем
(UDF) и сохраненные функции. Этот раздел описывает, как сервер признает,
используется ли название встроенной функции в качестве вызова функции или в
качестве идентификатора, и как сервер определяет, какую функцию использовать
в случаях, когда функции различных типов существуют с этим именем.
Встроенный парсинг имени функции
Анализатор использует правила значения по умолчанию для того, чтобы
разобрать названия встроенных функций. Эти правила могут быть изменены,
включая режим SQL
IGNORE_SPACE .
Когда анализатор сталкивается со словом, которое является названием
встроенной функции, это должно определить, показывает ли имя вызов функции
или является вместо этого ссылкой на такой идентификатор, как имя таблицы или
столбца. Например, в следующих запросах, первая ссылка на
count вызов функции, тогда как вторая ссылка имя таблицы:
SELECT COUNT(*) FROM mytable;
CREATE TABLE count (i INT);
Анализатор должен признать название встроенной функции как указание на вызов
функции только, разбирая то, что будет выражением. Таким образом, не в
контексте выражения имена функций разрешены как идентификаторы.
Однако, у некоторых встроенных функций есть специальные соображения
парсинга или выполнения, таким образом, анализатор использует следующие
правила по умолчанию, чтобы различить, используются ли их имена в качестве
вызовов функции или в качестве идентификаторов не в контексте выражения:
Требование, чтобы вызовы функции быть написанными без пробела
между именем и круглой скобкой применимы только к встроенным функциям, у
которых есть специальные соображения. COUNT одно такое имя.
Исходный файл sql/lex.h перечисляет названия этих специальных
функций, для которых следующий пробел определяет их интерпретацию: имена,
определенные макросом SYM_FN() в массиве symbols[] .
В MySQL 8.0 есть приблизительно 30 таких имен функций. Вы можете счесть
самым легким не обрабатывать ничего без пробела
как относящееся ко всем вызовам функции.
Следующяя таблица показывает имена функций, которые затронуты
IGNORE_SPACE
и перечислены как особенные в файле sql/lex.h .
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 |
Для функций, не перечисленных как особенные в sql/lex.h ,
пробел не имеет значения. Они интерпретируются как вызовы функции только
когда используются в контексте выражения и могут использоваться свободно в
качестве идентификаторов иначе. ASCII одно такое имя. Однако,
для этих незатронутых имен функций, интерпретация может измениться
по контексту выражения: func_name ()
интерпретируется как встроенная функция, если она одна с именем,
в противном случае func_name ()
интерпретируется как определяемая пользователем или сохраненная функция.
Режим SQL IGNORE_SPACE
может использоваться, чтобы изменить, как анализатор обрабатывает
имена функций, которые чувствительны к пробелу:
С выключенным
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
также имеет побочный эффект, что анализатор обрабатывает затронутые имена
функций как зарезервированные слова (см. раздел
10.3). Это означает, что пробел после имени больше не показывает свое
использование в качестве идентификатора. Имя может использоваться в вызовах
функции с или без следующего пробела, но вызывает синтаксическую ошибку не в
контексте выражения, если это не заключено в кавычки. Например, с
IGNORE_SPACE
оба следующих запроса терпят неудачу с синтаксической ошибкой, потому что
анализатор интерпретирует count как зарезервированное слово:
CREATE TABLE count(i INT);
CREATE TABLE count (i INT);
Чтобы использовать имя функции не в контексте выражения, напишите это как
заключенный в кавычки идентификатор:
CREATE TABLE `count`(i INT);
CREATE TABLE `count` (i INT);
Чтобы включить режим SQL
IGNORE_SPACE , используйте этот запрос:
SET sql_mode = 'IGNORE_SPACE';
IGNORE_SPACE
также включен другими сложными режимами, например,
ANSI
включает это в их значение:
SET sql_mode = 'ANSI';
Изучите раздел 6.1.8,
чтобы видеть, которые сложные режимы включают
IGNORE_SPACE .
Чтобы минимизировать зависимость SQL от
IGNORE_SPACE :
Избегайте создавать UDF или сохраненные функции, у которых есть то
же самое имя, как у встроенной функции.
- Избегайте использования имен функций не в контексте выражения. Например,
эти запросы используют
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);
Разрешение имени функции
Следующие правила описывают, как сервер решает ссылки на имена функций
для функционального создания:
Встроенные функции и определяемые пользователем функции.
Ошибка происходит, если Вы пытаетесь создать UDF с тем же самым именем,
как встроенная функция.
- Встроенные и сохраненные функции.
Возможно создать сохраненную функцию с тем же самым именем, как встроенная
функция, но чтобы вызвать сохраненную функцию, необходимо квалифицировать это
с именем схемы. Например, если Вы создаете сохраненную функцию, названную
PI в схеме test , вызовите это как
test.PI() потому что сервер решает
PI() без спецификатора как
ссылка на встроенную функцию. Сервер производит предупреждение, если
сохраненное имя функции сталкивается со встроенным именем функции.
Предупреждение может быть выведено на экран с
SHOW WARNINGS .
- Определяемые пользователем и сохраненные функции.
Определяемые пользователем и сохраненные функции совместно используют то
же самое пространство имен, таким образом, Вы не можете создать UDF и
сохраненную функцию с тем же самым именем.
У предыдущих правил разрешения имени функции есть значения для того, чтобы
обновить до версий MySQL, которые осуществляют новые встроенные функции:
Если Вы уже создали определяемую пользователем функцию с именем и
обновляете MySQL до версии, которая осуществляет новую встроенную функцию с
тем же самым именем, UDF становится недоступным. Чтобы исправить это, надо
использовать DROP FUNCTION ,
чтобы удалить UDF и CREATE FUNCTION
, чтобы пересоздать UDF с иным непротиворечивым именем. Затем
измените любой затронутый код, чтобы использовать новое имя.
- Если новая версия MySQL осуществляет встроенную функцию с тем же самым
именем как существующая сохраненная функция, у Вас есть два выбора:
переименуйте сохраненную функцию, чтобы использовать непротиворечивое имя,
или измените вызов функции так, чтобы он использовал спецификатор схемы (то
есть, надо использовать синтаксис
schema_name .
func_name () ). В любом случае
измените любой затронутый код соответственно.
10.3. Ключевые и зарезервированные слова
Ключевые слова это такие слова, у которых есть значение в SQL.
Определенные ключевые слова такие, как
SELECT ,
DELETE или
BIGINT ,
требуют специального режима для использования в качестве идентификаторов,
таких как имена таблиц и имена столбцов. Это может также быть истиной для
названий встроенных функций.
Несохраненные ключевые слова разрешены как идентификаторы без заключения в
кавычки. Зарезервированные слова разрешены как идентификаторы, если Вы
заключаете их в кавычки как описано в разделе
10.2:
mysql> CREATE TABLE interval (begin INT, end INT);
ERROR 1064 (42000): You have an error in your SQL syntax ...
near 'interval (begin INT, end INT)'
BEGIN и END ключевые слова, но не сохраненные,
таким образом, их использование в качестве идентификаторов не требует
заключения в кавычки. INTERVAL сохраненное ключевое слово и
должно быть заключено в кавычки, чтобы
использоваться в качестве идентификатора:
mysql> CREATE TABLE `interval` (begin INT, end INT);
Query OK, 0 rows affected (0.01 sec)
Исключение: слово, которое следует за точкой в полностью определенном имени,
должно быть идентификатором, таким образом, оно не должно быть заключено в
кавычки, даже если оно сохранено:
mysql> CREATE TABLE mydb.interval (begin INT, end INT);
Query OK, 0 rows affected (0.01 sec)
Названия встроенных функций разрешены как идентификаторы. Например,
COUNT является приемлемым как имя столбца. Однако, по умолчанию
никакой пробел не разрешен в функциональных вызовах между именем функции и
следующей ( . Это требование позволяет анализатору различить,
используется ли имя в вызове функции или в нефункциональном контексте.
Для получения дальнейшей информации о распознавании имен функций см.
раздел 10.2.4.
Следующая таблица показывает ключевые слова и зарезервированные слова в
MySQL 8.0, наряду с изменениями отдельных слов от версии к версии.
Сохраненные ключевые слова отмечены (R).
Кроме того, _FILENAME сохранено.
В некоторый момент, Вы могли бы обновиться до более высокой версии,
таким образом, хорошая идея взглянуть на будущие зарезервированные слова
также. Вы можете найти их в руководствах, которые касаются более высоких
версий MySQL. Большинство зарезервированных слов в таблице запрещены
стандартным SQL как имена столбцов или имена таблиц (например,
GROUP ). Некоторые сохранены, потому что MySQL нуждается в них и
использует парсер yacc.
Таблица 10.2.
Ключевые и зарезервированные слова в MySQL 8.0
ACCESSIBLE (R) |
ACCOUNT |
ACTION |
ADD (R) |
ADMIN (R) |
AFTER |
AGAINST |
AGGREGATE |
ALGORITHM |
ALL (R) |
ALTER (R) |
ALWAYS |
ANALYSE |
ANALYZE (R) |
AND (R) |
ANY |
AS (R) |
ASC (R) |
ASCII |
ASENSITIVE (R) |
AT |
AUTOEXTEND_SIZE |
AUTO_INCREMENT |
AVG |
AVG_ROW_LENGTH |
BACKUP |
BEFORE (R) |
BEGIN |
BETWEEN (R) |
BIGINT (R) |
BINARY (R) |
BINLOG |
BIT |
BLOB (R) |
BLOCK |
BOOL |
BOOLEAN |
BOTH (R) |
BTREE |
BY (R) |
BYTE |
CACHE |
CALL (R) |
CASCADE (R) |
CASCADED |
CASE (R) |
CATALOG_NAME |
CHAIN |
CHANGE (R) |
CHANGED |
CHANNEL |
CHAR (R) |
CHARACTER (R) |
CHARSET |
CHECK (R) |
CHECKSUM |
CIPHER |
CLASS_ORIGIN |
CLIENT |
CLOSE |
COALESCE |
CODE |
COLLATE (R) |
COLLATION |
COLUMN (R) |
COLUMNS |
COLUMN_FORMAT |
COLUMN_NAME |
COMMENT |
COMMIT |
COMMITTED |
COMPACT |
COMPLETION |
COMPONENT |
COMPRESSED |
COMPRESSION |
CONCURRENT |
CONDITION (R) |
CONNECTION |
CONSISTENT |
CONSTRAINT (R) |
CONSTRAINT_CATALOG |
CONSTRAINT_NAME |
CONSTRAINT_SCHEMA |
CONTAINS |
CONTEXT |
CONTINUE (R) |
CONVERT (R) |
CPU |
CREATE (R) |
CROSS (R) |
CUBE |
CURRENT |
CURRENT_DATE (R) |
CURRENT_TIME (R) |
CURRENT_TIMESTAMP (R) |
CURRENT_USER (R) |
CURSOR (R) |
CURSOR_NAME |
DATA |
DATABASE (R) |
DATABASES (R) |
DATAFILE |
DATE |
DATETIME |
DAY |
DAY_HOUR (R) |
DAY_MICROSECOND (R) |
DAY_MINUTE (R) |
DAY_SECOND (R) |
DEALLOCATE |
DEC (R) |
DECIMAL (R) |
DECLARE (R) |
DEFAULT (R) |
DEFAULT_AUTH |
DEFINER |
DELAYED (R) |
DELAY_KEY_WRITE |
DELETE (R) |
DESC (R) |
DESCRIBE (R) |
DES_KEY_FILE |
DETERMINISTIC (R) |
DIAGNOSTICS |
DIRECTORY |
DISABLE |
DISCARD |
DISK |
DISTINCT (R) |
DISTINCTROW (R) |
DIV (R) |
DO |
DOUBLE (R) |
DROP (R) |
DUAL (R) |
DUMPFILE |
DUPLICATE |
DYNAMIC |
EACH (R) |
ELSE (R) |
ELSEIF (R) |
ENABLE |
ENCLOSED (R) |
ENCRYPTION |
END |
ENDS |
ENGINE |
ENGINES |
ENUM |
ERROR |
ERRORS |
ESCAPE |
ESCAPED (R) |
EVENT |
EVENTS |
EVERY |
EXCEPT (R) |
EXCHANGE |
EXECUTE |
EXISTS (R) |
EXIT (R) |
EXPANSION |
EXPIRE |
EXPLAIN (R) |
EXPORT |
EXTENDED |
EXTENT_SIZE |
FALSE (R) |
FAST |
FAULTS |
FETCH (R) |
FIELDS |
FILE |
FILE_BLOCK_SIZE |
FILTER |
FIRST |
FIXED |
FLOAT (R) |
FLOAT4 (R) |
FLOAT8 (R) |
FLUSH |
FOLLOWS |
FOR (R) |
FORCE (R) |
FOREIGN (R) |
FORMAT |
FOUND |
FROM (R) |
FULL |
FULLTEXT (R) |
FUNCTION |
GENERAL |
GENERATED (R) |
GEOMETRY |
GEOMETRYCOLLECTION |
GET (R) |
GET_FORMAT |
GLOBAL |
GRANT (R) |
GRANTS |
GROUP (R) |
GROUP_REPLICATION |
HANDLER |
HASH |
HAVING (R) |
HELP |
HIGH_PRIORITY (R) |
HOST |
HOSTS |
HOUR |
HOUR_MICROSECOND (R) |
HOUR_MINUTE (R) |
HOUR_SECOND (R) |
IDENTIFIED |
IF (R) |
IGNORE (R) |
IGNORE_SERVER_IDS |
IMPORT |
IN (R) |
INDEX (R) |
INDEXES |
INFILE (R) |
INITIAL_SIZE |
INNER (R) |
INOUT (R) |
INSENSITIVE (R) |
INSERT (R) |
INSERT_METHOD |
INSTALL |
INSTANCE |
INT (R) |
INT1 (R) |
INT2 (R) |
INT3 (R) |
INT4 (R) |
INT8 (R) |
INTEGER (R) |
INTERVAL (R) |
INTO (R) |
INVISIBLE |
INVOKER |
IO |
IO_AFTER_GTIDS (R) |
IO_BEFORE_GTIDS (R) |
IO_THREAD |
IPC |
IS (R) |
ISOLATION |
ISSUER |
ITERATE (R) |
JOIN (R) |
JSON |
KEY (R) |
KEYS (R) |
KEY_BLOCK_SIZE |
KILL (R) |
LANGUAGE |
LAST |
LEADING (R) |
LEAVE (R) |
LEAVES |
LEFT (R) |
LESS |
LEVEL |
LIKE (R) |
LIMIT (R) |
LINEAR (R) |
LINES (R) |
LINESTRING |
LIST |
LOAD (R) |
LOCAL |
LOCALTIME (R) |
LOCALTIMESTAMP (R) |
LOCK (R) |
LOCKS |
LOGFILE |
LOGS |
LONG (R) |
LONGBLOB (R) |
LONGTEXT (R) |
LOOP (R) |
LOW_PRIORITY (R) |
MASTER |
MASTER_AUTO_POSITION |
MASTER_BIND (R) |
MASTER_CONNECT_RETRY |
MASTER_DELAY |
MASTER_HEARTBEAT_PERIOD |
MASTER_HOST |
MASTER_LOG_FILE |
MASTER_LOG_POS |
MASTER_PASSWORD |
MASTER_PORT |
MASTER_RETRY_COUNT |
MASTER_SERVER_ID |
MASTER_SSL |
MASTER_SSL_CA |
MASTER_SSL_CAPATH |
MASTER_SSL_CERT |
MASTER_SSL_CIPHER |
MASTER_SSL_CRL |
MASTER_SSL_CRLPATH |
MASTER_SSL_KEY |
MASTER_SSL_VERIFY_SERVER_CERT (R) |
MASTER_TLS_VERSION |
MASTER_USER |
MATCH (R) |
MAXVALUE (R) |
MAX_CONNECTIONS_PER_HOUR |
MAX_QUERIES_PER_HOUR |
MAX_ROWS |
MAX_SIZE |
MAX_UPDATES_PER_HOUR |
MAX_USER_CONNECTIONS |
MEDIUM |
MEDIUMBLOB (R) |
MEDIUMINT (R) |
MEDIUMTEXT (R) |
MEMORY |
MERGE |
MESSAGE_TEXT |
MICROSECOND |
MIDDLEINT (R) |
MIGRATE |
MINUTE |
MINUTE_MICROSECOND (R) |
MINUTE_SECOND (R) |
MIN_ROWS |
MOD (R) |
MODE |
MODIFIES (R) |
MODIFY |
MONTH |
MULTILINESTRING |
MULTIPOINT |
MULTIPOLYGON |
MUTEX |
MYSQL_ERRNO |
NAME |
NAMES |
NATIONAL |
NATURAL (R) |
NCHAR |
NDB |
NDBCLUSTER |
NEVER |
NEW |
NEXT |
NO |
NODEGROUP |
NONE |
NOT (R) |
NO_WAIT |
NO_WRITE_TO_BINLOG (R) |
NULL (R) |
NUMBER |
NUMERIC (R) |
NVARCHAR |
OFFSET |
ON (R) |
ONE |
ONLY |
OPEN |
OPTIMIZE (R) |
OPTIMIZER_COSTS (R) |
OPTION (R) |
OPTIONALLY (R) |
OPTIONS |
OR (R) |
ORDER (R) |
OUT (R) |
OUTER (R) |
OUTFILE (R) |
OWNER |
PACK_KEYS |
PAGE |
PARSER |
PARTIAL |
PARTITION (R) |
PARTITIONING |
PARTITIONS |
PASSWORD |
PERSIST (R) |
PHASE |
PLUGIN |
PLUGINS |
PLUGIN_DIR |
POINT |
POLYGON |
PORT |
PRECEDES |
PRECISION (R) |
PREPARE |
PRESERVE |
PREV |
PRIMARY (R) |
PRIVILEGES |
PROCEDURE (R) |
PROCESSLIST |
PROFILE |
PROFILES |
PROXY |
PURGE (R) |
QUARTER |
QUERY |
QUICK |
RANGE (R) |
READ (R) |
READS (R) |
READ_ONLY |
READ_WRITE (R) |
REAL (R) |
REBUILD |
RECOVER |
REDOFILE |
REDO_BUFFER_SIZE |
REDUNDANT |
REFERENCES (R) |
REGEXP (R) |
RELAY |
RELAYLOG |
RELAY_LOG_FILE |
RELAY_LOG_POS |
RELAY_THREAD |
RELEASE (R) |
RELOAD |
REMOVE |
RENAME (R) |
REORGANIZE |
REPAIR |
REPEAT (R) |
REPEATABLE |
REPLACE (R) |
REPLICATE_DO_DB |
REPLICATE_DO_TABLE |
REPLICATE_IGNORE_DB |
REPLICATE_IGNORE_TABLE |
REPLICATE_REWRITE_DB |
REPLICATE_WILD_DO_TABLE |
REPLICATE_WILD_IGNORE_TABLE |
REPLICATION |
REQUIRE (R) |
RESET |
RESIGNAL (R) |
RESTORE |
RESTRICT (R) |
RESUME |
RETURN (R) |
RETURNED_SQLSTATE |
RETURNS |
REVERSE |
REVOKE (R) |
RIGHT (R) |
RLIKE (R) |
ROLE (R) |
ROLLBACK |
ROLLUP |
ROTATE |
ROUTINE |
ROW |
ROWS |
ROW_COUNT |
ROW_FORMAT |
RTREE |
SAVEPOINT |
SCHEDULE |
SCHEMA (R) |
SCHEMAS (R) |
SCHEMA_NAME |
SECOND |
SECOND_MICROSECOND (R) |
SECURITY |
SELECT (R) |
SENSITIVE (R) |
SEPARATOR (R) |
SERIAL |
SERIALIZABLE |
SERVER |
SESSION |
SET (R) |
SHARE |
SHOW (R) |
SHUTDOWN |
SIGNAL (R) |
SIGNED |
SIMPLE |
SLAVE |
SLOW |
SMALLINT (R) |
SNAPSHOT |
SOCKET |
SOME |
SONAME |
SOUNDS |
SOURCE |
SPATIAL (R) |
SPECIFIC (R) |
SQL (R) |
SQLEXCEPTION (R) |
SQLSTATE (R) |
SQLWARNING (R) |
SQL_AFTER_GTIDS |
SQL_AFTER_MTS_GAPS |
SQL_BEFORE_GTIDS |
SQL_BIG_RESULT (R) |
SQL_BUFFER_RESULT |
SQL_CACHE |
SQL_CALC_FOUND_ROWS (R) |
SQL_NO_CACHE |
SQL_SMALL_RESULT (R) |
SQL_THREAD |
SQL_TSI_DAY |
SQL_TSI_HOUR |
SQL_TSI_MINUTE |
SQL_TSI_MONTH |
SQL_TSI_QUARTER |
SQL_TSI_SECOND |
SQL_TSI_WEEK |
SQL_TSI_YEAR |
SSL (R) |
STACKED |
START |
STARTING (R) |
STARTS |
STATS_AUTO_RECALC |
STATS_PERSISTENT |
STATS_SAMPLE_PAGES |
STATUS |
STOP |
STORAGE |
STORED (R) |
STRAIGHT_JOIN (R) |
STRING |
SUBCLASS_ORIGIN |
SUBJECT |
SUBPARTITION |
SUBPARTITIONS |
SUPER |
SUSPEND |
SWAPS |
SWITCHES |
TABLE (R) |
TABLES |
TABLESPACE |
TABLE_CHECKSUM |
TABLE_NAME |
TEMPORARY |
TEMPTABLE |
TERMINATED (R) |
TEXT |
THAN |
THEN (R) |
TIME |
TIMESTAMP |
TIMESTAMPADD |
TIMESTAMPDIFF |
TINYBLOB (R) |
TINYINT (R) |
TINYTEXT (R) |
TO (R) |
TRAILING (R) |
TRANSACTION |
TRIGGER (R) |
TRIGGERS |
TRUE (R) |
TRUNCATE |
TYPE |
TYPES |
UNCOMMITTED |
UNDEFINED |
UNDO (R) |
UNDOFILE |
UNDO_BUFFER_SIZE |
UNICODE |
UNINSTALL |
UNION (R) |
UNIQUE (R) |
UNKNOWN |
UNLOCK (R) |
UNSIGNED (R) |
UNTIL |
UPDATE (R) |
UPGRADE |
USAGE (R) |
USE (R) |
USER |
USER_RESOURCES |
USE_FRM |
USING (R) |
UTC_DATE (R) |
UTC_TIME (R) |
UTC_TIMESTAMP (R) |
VALIDATION |
VALUE |
VALUES (R) |
VARBINARY (R) |
VARCHAR (R) |
VARCHARACTER (R) |
VARIABLES |
VARYING (R) |
VIEW |
VIRTUAL (R) |
VISIBLE |
WAIT |
WARNINGS |
WEEK |
WEIGHT_STRING |
WHEN (R) |
WHERE (R) |
WHILE (R) |
WITH (R) |
WITHOUT |
WORK |
WRAPPER |
WRITE (R) |
X509 |
XA |
XID |
XML |
XOR (R) |
YEAR |
YEAR_MONTH (R) |
ZEROFILL (R) |
| |
Следующая таблица показывает ключевые слова и зарезервированные слова,
которые добавлены в MySQL 8.0. Сохраненные ключевые слова отмечены (R).
Таблица 10.3. Ключевые и зарезервированные слова, добавленные в MySQL
8.0 по сравнению с MySQL 5.7
ADMIN (R) |
COMPONENT |
EXCEPT (R) |
INVISIBLE |
PERSIST (R) |
ROLE (R) |
VISIBLE |
| |
Следующая таблица показывает ключевые и зарезервированные слова, которые
удалены в MySQL 8.0. Сохраненные ключевые слова отмечены (R).
Таблица 10.4. Ключевые и
зарезервированные слова, удаленные в MySQL 8.0 по сравнению с MySQL 5.7
10.4. Определяемые пользователем переменные
Вы можете сохранить значение в определяемой пользователем переменной в
одном запросе и обратиться к нему позже в другом запросе. Это позволяет Вам
передать значения от одного запроса другому.
Пользовательские переменные написаны как
@var_name , где имя переменной
var_name состоит из алфавитно-цифровых символов,
. , _ и $ . Пользовательское имя
переменной может содержать другие символы, если Вы заключаете его в кавычки
как строку или идентификатор (например, @'my-var' ,
@"my-var" или @`my-var` ).
Определяемые пользователем переменные определены в рамках сеанса.
Пользовательская переменная, определенная одним клиентом, не может быть
замечена или использоваться другими клиентами. Исключение: пользователь с
доступом к таблице
user_variables_by_thread в Performance Schema
может видеть все пользовательские переменные для всех сеансов. Все переменные
для данного сеанса клиента автоматически освобождены, когда клиент выходит.
Пользовательские имена переменной не являются чувствительными к регистру.
У имен есть максимальная длина 64 символа.
Один способ установить определяемую пользователем переменную, применив
SET :
SET @var_name = expr [, @var_name = expr ] ...
Для SET ,
= или
:=
может использоваться в качестве оператора назначения.
Вы можете также назначить значение на пользовательскую переменную в
запросах кроме SET .
В этом случае оператор назначения должен быть
:= , но не
= , так как
последний обработан как оператор сравнения
= не в запросах
SET :
mysql> SET @t1=1, @t2=2, @t3:=4;
mysql> SELECT @t1, @t2, @t3, @t4 := @t1+@t2+@t3;
+-----+-----+-----+--------------------+
| @t1 | @t2 | @t3 | @t4 := @t1+@t2+@t3 |
+-----+-----+-----+--------------------+
| 1 | 2 | 4 | 7 |
+-----+-----+-----+--------------------+
Пользовательским переменным можно назначить значение из ограниченного набора
типов данных: целое число, десятичная, двоичная или недвоичная строка с
плавающей запятой или NULL . Назначение десятичных и реальных
значений не сохраняет точность или масштаб значения. Значение типа кроме
одного из допустимых типов преобразовано в допустимый тип. Например,
значение, имеющее временный или пространственный тип данных, преобразовано в
двоичную строку. Значение, имеющее тип
JSON преобразовано в строку с
набором символов utf8mb4 и сопоставлением
utf8mb4_bin .
Если пользовательской переменной назначают недвоичное (символьное)
строковое значение, у нее есть тот же самый набор символов и сопоставление,
как у строки. coercibility пользовательских переменных неявен. Это тот же
самый coercibility, что касается значений столбца таблицы.
Шестнадцеричные или битовые значения, назначенные на пользовательские
переменные, обработаны как двоичные строки. Чтобы назначить шестнадцатеричное
или битовое значение в качестве числа пользовательской переменной,
используйте это в числовом контексте. Например, добавьте 0 или используйте
CAST(... AS UNSIGNED) :
mysql> SET @v1 = X'41';
mysql> SET @v2 = X'41'+0;
mysql> SET @v3 = CAST(X'41' AS UNSIGNED);
mysql> SELECT @v1, @v2, @v3;
+-----+-----+-----+
| @v1 | @v2 | @v3 |
+-----+-----+-----+
| A | 65 | 65 |
+-----+-----+-----+
mysql> SET @v1 = b'1000001';
mysql> SET @v2 = b'1000001'+0;
mysql> SET @v3 = CAST(b'1000001' AS UNSIGNED);
mysql> SELECT @v1, @v2, @v3;
+-----+-----+-----+
| @v1 | @v2 | @v3 |
+-----+-----+-----+
| A | 65 | 65 |
+-----+-----+-----+
Если значение пользовательской переменной выбрано в наборе результатов, оно
возвращено клиенту как строка.
Если Вы обращаетесь к переменной, которая не была инициализирована, у нее
есть значение NULL и тип строки.
Пользовательские переменные могут использоваться в большинстве контекстов,
где выражения разрешены. Это в настоящее время не включает контексты, которые
явно требуют буквального значения такие, как в предложении LIMIT
запроса SELECT или в предложении
IGNORE N LINES запроса
LOAD DATA .
Как правило, кроме запросов
SET Вы никогда не должны
назначать значение пользовательской переменной и читать значение в пределах
того же самого запроса. Например, чтобы постепенно увеличить переменную:
SET @a = @a + 1;
Для других запросов, например,
SELECT ,
Вы могли бы получить результаты, которые Вы ожидаете, но это не
гарантируется. В следующем запросе Вы могли бы думать, что MySQL оценит
сначала @a , а потом выполнит присвоение:
SELECT @a, @a:=@a+1, ...;
Однако, порядок оценки для выражений, вовлекающих
пользовательские переменные, неопределен.
Другая проблема с назначением значения переменной и чтению значения в
пределах того же самого не SET
то, что тип результата значения по умолчанию переменной основан на ее
типе в начале запроса. Следующий пример иллюстрирует это:
mysql> SET @a='test';
mysql> SELECT @a,(@a:=20) FROM tbl_name ;
Для SELECT MySQL сообщает клиенту,
что столбец строка и преобразовывает все доступы к @a в
строки, даже при том, что @a установлен в число для второй строки. После
выполнения SELECT @a
расценена как число для следующего запроса.
Чтобы избежать проблем с этим поведением, не назначайте значение и не
читайте значение той же самой переменной в пределах единственного запроса
или иначе устанавливайте переменную в 0 ,
0.0 или '' , чтобы
определить тип прежде, чем Вы будете использовать это.
В запросе SELECT
каждое выражение оценено только когда послано клиенту. Это означает, что
HAVING , GROUP BY или ORDER BY ,
относящихся к переменной, которой назначают значение в избранном списке
выражения, НЕ работает как ожидалось:
mysql> SELECT (@aa:=id) AS a, (@aa+3) AS b FROM
tbl_name HAVING b=5;
Ссылка на b в HAVING
относится к псевдониму для выражения в избранном списке, который использует
@aa . Это не работает как ожидалось: @aa содержит
значение id из предыдущей выбранной строки, а не от текущей.
Пользовательские переменные предназначены, чтобы обеспечить значения
данных. Они не могут использоваться непосредственно в запросе SQL как
идентификатор или как часть идентификатора, как в контекстах, где имя таблицы
или базы данных ожидаются, или как зарезервированное слово, например,
SELECT . Это истина, даже если
переменная заключена в кавычки, как показано в следующем примере:
mysql> SELECT c1 FROM t;
+----+
| c1 |
+----+
| 0 |
+----+
| 1 |
+----+
2 rows in set (0.00 sec)
mysql> SET @col = "c1";
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @col FROM t;
+------+
| @col |
+------+
| c1 |
+------+
1 row in set (0.00 sec)
mysql> SELECT `@col` FROM t;
ERROR 1054 (42S22): Unknown column '@col' in 'field list'
mysql> SET @col = "`c1`";
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @col FROM t;
+------+
| @col |
+------+
| `c1` |
+------+
1 row in set (0.00 sec)
Исключение к этому принципу, что пользовательские переменные не могут
использоваться, чтобы обеспечить идентификаторы: когда Вы создаете строку для
использования в качестве готового запроса, чтобы выполнить позже.
В этом случае пользовательские переменные могут использоваться, чтобы
обеспечить любую часть запроса. Следующий пример иллюстрирует, как это
может быть сделано:
mysql> SET @c = "c1";
Query OK, 0 rows affected (0.00 sec)
mysql> SET @s = CONCAT("SELECT ", @c, " FROM t");
Query OK, 0 rows affected (0.00 sec)
mysql> PREPARE stmt FROM @s;
Query OK, 0 rows affected (0.04 sec)
Statement prepared
mysql> EXECUTE stmt;
+----+
| c1 |
+----+
| 0 |
+----+
| 1 |
+----+
2 rows in set (0.00 sec)
mysql> DEALLOCATE PREPARE stmt;
Query OK, 0 rows affected (0.00 sec)
См. раздел 14.5.
Подобный метод может использоваться в приложениях, чтобы создать запросы
SQL, используя переменные программы, как показано здесь, используя PHP 5:
<?php
$mysqli = new mysqli("localhost", "user", "pass", "test");
if (mysqli_connect_errno())
die("Connection failed: %s\n", mysqli_connect_error());
$col = "c1";
$query = "SELECT $col FROM t";
$result = $mysqli->query($query);
while($row = $result->fetch_assoc()) {
echo "<p>" . $row["$col"] . "</p>\n";
}
$result->close();
$mysqli->close();
?>
Сборка запроса SQL этим способом иногда известна как
динамический SQL.
10.5. Синтаксис выражения
Следующие правила определяют синтаксис выражения в MySQL. Грамматика,
показанная здесь, основана на файле sql/sql_yacc.yy
исходных текстов MySQL.
expr :
expr OR expr
| expr || expr
| expr XOR expr
| expr AND expr
| expr && expr
| NOT expr
| ! expr
| boolean_primary IS [NOT] {TRUE | FALSE | UNKNOWN}
| boolean_primary
boolean_primary :
boolean_primary IS [NOT] NULL
| boolean_primary <=> predicate
| boolean_primary comparison_operator predicate
| boolean_primary comparison_operator
{ALL | ANY} (subquery )
| predicate
comparison_operator : = | >= | > | <= | < | <> | !=
predicate :
bit_expr [NOT] IN (subquery )
| bit_expr [NOT] IN (expr [,
expr ] ...)
| bit_expr [NOT] BETWEEN bit_expr AND
predicate
| bit_expr SOUNDS LIKE bit_expr
| bit_expr [NOT] LIKE simple_expr
[ESCAPE simple_expr ]
| bit_expr [NOT] REGEXP bit_expr
| bit_expr
bit_expr :
bit_expr | bit_expr
| bit_expr & bit_expr
| bit_expr << bit_expr
| bit_expr >> bit_expr
| bit_expr + bit_expr
| bit_expr - bit_expr
| bit_expr * bit_expr
| bit_expr / bit_expr
| bit_expr DIV bit_expr
| bit_expr MOD bit_expr
| bit_expr % bit_expr
| bit_expr ^ bit_expr
| bit_expr + interval_expr
| bit_expr - interval_expr
| simple_expr
simple_expr :
literal
| identifier
| function_call
| simple_expr COLLATE collation_name
| param_marker
| variable
| simple_expr || simple_expr
| + simple_expr
| - simple_expr
| ~ simple_expr
| ! simple_expr
| BINARY simple_expr
| (expr [, expr ] ...)
| ROW (expr , expr [,
expr ] ...)
| (subquery )
| EXISTS (subquery )
| {identifier expr }
| match_expr
| case_expr
| interval_expr
Для приоритета операторов см.
раздел 13.3.1.
Для синтаксиса буквального значения см.
раздел 10.1.
Для синтаксиса идентификатора см.
раздел 10.2.
Переменные могут быть пользовательскими, системными или
местными переменными или параметрами сохраненной программы:
param_marker это ? как использующийся в
готовых запросах для заполнителей. См.
раздел 14.5.1.
(subquery ) указывает на подзапрос,
который возвращает единственное значение, то есть, скалярный подзапрос. См.
раздел 14.2.10.1.
{identifier expr }
синтаксис escape ODBC и принят для совместимости с ODBC. Значение
expr . Фигурные скобки в синтаксисе должны быть написаны
буквально: они не метасинтаксис, как используются в другом
месте в описаниях синтаксиса.
match_expr указывает на выражение
MATCH . См.
раздел 13.9.
case_expr указывает на выражение
CASE . См.
раздел 13.4.
interval_expr представляет временной интервал.
Синтаксис: INTERVAL expr unit
, где unit такой спецификатор, как
HOUR , DAY или WEEK .
Для полного списка спецификаторов unit см. описание
функции DATE_ADD() в
разделе 13.7.
Значение некоторых операторов зависит от режима SQL:
См. раздел 6.1.8.
10.6. Синтаксис комментария
MySQL Server поддерживает три стиля комментария:
Следующий пример демонстрирует все три стиля комментария:
mysql> SELECT 1+1; # This comment continues to the end of line
mysql> SELECT 1+1; -- This comment continues to the end of line
mysql> SELECT 1 /* this is an in-line comment */ + 1;
mysql> SELECT 1+
/*
this is a
multiple-line comment
*/
1;
Вложенные комментарии не поддержаны. При некоторых условиях вложенные
комментарии могли бы быть разрешены, но обычно нет, и пользователи
должны избежать их.
MySQL Server поддерживает некоторые разновидности комментариев C-стиля.
Они позволяют Вам написать код, который включает расширения MySQL, но все еще
портативен, при использовании комментариев следующей формы:
/*! MySQL-specific code */
В этом случае сервер MySQL разбирает и выполняет код в пределах комментария,
как если бы это был, любой другой запрос SQL, но другие SQL-серверы
проигнорируют расширения. Например, сервер MySQL признает ключевое слово
STRAIGHT_JOIN в следующем запросе, но другие серверы не будут:
SELECT /*! STRAIGHT_JOIN */ col1 FROM table1,table2 WHERE ...
Если Вы добавляете номер версии после символа ! ,
синтаксис в пределах комментария выполнен, только если версия MySQL больше
чем или равна указанному номеру версии. Ключевое слово
KEY_BLOCK_SIZE=1024 в следующем комментарии выполнено только
серверами MySQL 5.1.10 или выше:
CREATE TABLE t1(a INT, KEY (a)) /*!50110 KEY_BLOCK_SIZE=1024 */;
Синтаксис комментария относится к тому, как сервер
mysqld
разбирает запросы SQL. Программа клиента
mysql также выполняет некоторый парсинг запросов
прежде, чем послать их в сервер. Это делается, чтобы решить, где границы
запроса в случае многострочного запроса.
Комментарии в этом формате, /*!12345 ... */ , не сохранены на
сервере. Если этот формат будет использоваться, чтобы прокомментировать
сохраненные программы, то комментарии не будут сохранены на сервере.
Другая разновидность синтаксиса комментария C-стиля используется, чтобы
определить подсказки оптимизатора. Комментарии подсказки включают
символ + после вводной последовательности комментария
/* . Пример:
SELECT /*+ BKA(t1) */ FROM ... ;
См. раздел 9.9.3.
Использование кратких команд
mysql таких,
как \C , в пределах многострочного комментария /* ... */
пока не поддерживается.
|
|