Когда использовать одинарные, двойные и обратные кавычки в MySQL

633

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

Пример:

$query = 'INSERT INTO table (id, col1, col2) VALUES (NULL, val1, val2)';

Кроме того , в приведенном выше примере, считают , что table, col1, val1и т.д. , могут быть переменными.

Какой стандарт для этого? Чем ты занимаешься?

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

Nate
источник
16
Обратите внимание, что это очень специфический вопрос для MySQL. SQL в целом (т.е. ISO / ANSI SQL) имеет другой набор кавычек: двойные кавычки предназначены для идентификаторов с разделителями, например "tablename", и одинарные кавычки для литералов, например 'this is a some text'. Обратные галочки никогда не используются в стандартном SQL. (Если вам нужно включить двойную кавычку в идентификатор, введите его дважды, как "odd""tablename". Аналогично, двойные одинарные кавычки в литералах, например 'Conan O''Brien'.)
jarlh

Ответы:

611

Обратные метки должны использоваться для идентификаторов таблицы и столбца, но они необходимы только в том случае, если идентификатор является зарезервированным ключевым словом MySQL или когда идентификатор содержит пробельные символы или символы за пределами ограниченного набора (см. Ниже). Часто рекомендуется избегать использования зарезервированных ключевых слов. в качестве идентификаторов столбцов или таблиц, когда это возможно, избегая проблемы цитирования.

Одиночные кавычки должны использоваться для строковых значений, как в VALUES()списке. Двойные кавычки также поддерживаются MySQL для строковых значений, но одинарные кавычки более широко принимаются другими СУБД, поэтому рекомендуется использовать одинарные кавычки вместо двойных.

MySQL также ожидает DATEи DATETIMEбуквальные значения , чтобы быть в одинарных кавычках как строки , как '2001-01-01 00:00:00'. Обратитесь к документации по -датам даты и времени для получения более подробной информации, в частности, об альтернативах использованию дефиса в качестве разделителя сегмента в строках даты.

Поэтому, используя ваш пример, я бы заключил в кавычки строку PHP и использовал одинарные кавычки в значениях 'val1', 'val2'. NULLявляется ключевым словом MySQL и имеет специальное (не) -значение, и поэтому не заключено в кавычки.

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

Функции, родные для СУБД (например, NOW()в MySQL), не должны заключаться в кавычки, хотя их аргументы подчиняются той же самой строке или правилам цитирования идентификаторов, которые уже упоминались.

Backtick (`)
стол и столбец ───────┬─────┬──┬──┬──┬────┬─────┬┬───────┬──┬ ───────┐
                      ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
$ query = " INSERT INTO` table` (`id`,` col1`, `col2`,` date`, `updated`)
                       VALUES (NULL, 'val1', 'val2', '2001-01-01', NOW ()) ";
                               ↑↑↑↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑↑↑↑↑ 
Ключевое слово без кавычек ─────┴┴┴┘ │ │ │ │ │ │ │││││
Строки в одинарных кавычках (') ───────────┴────┴──┴────┘ │ │ │││││
Одиночная кавычка (') ДАТА ──────────────────────────┴──────────┘ ││││ │
Функция без кавычек ──────────────────────────────────────────────┴┴┴┴┘    

Переменная интерполяция

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

// То же самое с некоторыми заменами переменных
// Здесь имя переменной таблицы $ table заключено в кавычки, а переменные
// в списке ЗНАЧЕНИЙ одинарные кавычки 
$ query = "INSERT INTO` $ table` (`id`,` col1`, `col2`,` date`) VALUES (NULL, '$ val1' , '$ val2' , '$ date' ) ";

Подготовленные заявления

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

// PDO example with named parameters, unquoted
$query = "INSERT INTO `table` (`id`, `col1`, `col2`, `date`) VALUES (:id, :col1, :col2, :date)";

// MySQLi example with ? parameters, unquoted
$query = "INSERT INTO `table` (`id`, `col1`, `col2`, `date`) VALUES (?, ?, ?, ?)";

Символы, требующие использования кавычек в идентификаторах:

Согласно документации MySQL , вам не нужно заключать в кавычки (backtick) идентификаторы, используя следующий набор символов:

ASCII: [0-9,a-z,A-Z$_](основные латинские буквы, цифры 0-9, доллар, подчеркивание)

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

Майкл Берковски
источник
43
« но одинарные кавычки более широко принимаются другими СУБД » - использование одинарных кавычек для строковых литералов определяется (и требуется) стандартом SQL
a_horse_with_no_name
@a_horse_with_no_name почти никто не использует ANSI MySQL ('|' для строки concat - правда?)
Хороший человек
3
это не так: «MySQL также ожидает, что литеральные значения DATE и DATETIME будут заключены в одинарные кавычки в виде строк, таких как '2001-01-01 00:00:00'"
Kick_the_BUCKET
3
@evilReiko Документы MySQL, кажется, не обращаются к псевдониму, цитирующему ясно. Он будет принимать одинарные, двойные или обратные символы для псевдонимов, но это может зависеть от различных режимов ANSI SQL. Я не уверен, что спецификация SQL требуется для кавычек псевдонимов - Личные предпочтения: для согласованности я цитирую их так же, как идентификаторы столбцов - то есть я либо возвращаю их обратно, если нужно, либо оставляю их без кавычек, если нет. Я не использую одинарные или двойные кавычки на псевдонимах.
Майкл Берковски
2
@GuneyOzsan Да, очень уязвимы. Никогда не используйте переменную для имени таблицы, если она не была проверена по списку допустимых имен таблиц - создайте массив допустимых имен и проверьте, соответствует ли переменная чему-либо в списке, чтобы сделать его безопасным для использования. В противном случае вы не сможете безопасно экранировать переменную имени таблицы для использования.
Майкл Берковски
121

В MySQL есть два типа кавычек:

  1. ' для включения строковых литералов
  2. ` для включения идентификаторов, таких как имена таблиц и столбцов

И тут есть "особый случай. Это может использоваться для одной из вышеупомянутых целей одновременно в зависимости от сервера MySQL sql_mode:

  1. По умолчанию" символ может быть использован , чтобы приложить строковые литералы так же , как'
  2. В ANSI_QUOTESрежиме "символ может быть использован для включения идентификаторов так же, как`

Следующий запрос выдаст разные результаты (или ошибки) в зависимости от режима SQL:

SELECT "column" FROM table WHERE foo = "bar"

ANSI_QUOTES отключен

Запрос выберет строковый литерал, "column"где столбец fooравен строке"bar"

ANSI_QUOTES включен

Запрос выберет столбец, columnгде столбец fooравен столбцуbar

Когда использовать что

  • Я предлагаю вам избегать использования, "чтобы ваш код стал независимым от режимов SQL
  • Всегда заключайте в кавычки идентификаторы, так как это хорошая практика (довольно много вопросов по SO обсуждают это)
Салман А
источник
32

(Выше приведены хорошие ответы относительно природы вашего вопроса в SQL, но это также может быть актуально, если вы новичок в PHP.)

Возможно, важно отметить, что PHP обрабатывает одинарные и двойные кавычки по-разному ...

Строки в одинарных кавычках являются «литералами» и в значительной степени являются строками WYSIWYG. Строки в двойных кавычках интерпретируются PHP для возможной подстановки переменных (обратные пометки в PHP не совсем строки; они выполняют команду в оболочке и возвращают результат).

Примеры:

$foo = "bar";
echo 'there is a $foo'; // There is a $foo
echo "there is a $foo"; // There is a bar
echo `ls -l`; // ... a directory list
Крис Трейхи
источник
23

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

Например:

Use `database`;

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

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

Проверьте этот ответ, чтобы понять больше о кавычках.


Теперь о двойных кавычках и одинарных кавычках (Майкл уже упоминал об этом).

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

INSERT INTO `tablename` (`id, `title`) VALUES ( NULL, title1);

Здесь я намеренно забыл завернуть в title1кавычки. Теперь сервер примет title1имя столбца (т. Е. Идентификатор). Таким образом, чтобы указать, что это значение, вы должны использовать либо двойные, либо одинарные кавычки.

INSERT INTO `tablename` (`id, `title`) VALUES ( NULL, 'title1');

Теперь, в сочетании с PHP, двойные кавычки и одинарные кавычки значительно упрощают процесс написания запросов. Давайте посмотрим модифицированную версию запроса в вашем вопросе.

$query = "INSERT INTO `table` (`id`, `col1`, `col2`) VALUES (NULL, '$val1', '$val2')";

Теперь, используя двойные кавычки в PHP, вы будете создавать переменные $val1и $val2использовать их значения, создавая тем самым совершенно правильный запрос. подобно

$val1 = "my value 1";
$val2 = "my value 2";
$query = "INSERT INTO `table` (`id`, `col1`, `col2`) VALUES (NULL, '$val1', '$val2')";

сделаю

INSERT INTO `table` (`id`, `col1`, `col2`) VALUES (NULL, 'my value 1', 'my value 2')
Starx
источник
15

В MySQL, эти символы используются для разделения запроса `, ", 'и ().

  1. "или 'используются для включения строковых значений "26-01-2014 00:00:00"или '26-01-2014 00:00:00'. Эти символы только для строк, не агрегатные функции , такие как now, sumили max.

  2. ` используется для включения имен таблиц или столбцов, например select `column_name` from `table_name` where id='2'

  3. (и )просто заключить части запроса, например select `column_name` from `table_name` where (id='2' and gender='male') or name='rakesh'.

Кумар Ракеш
источник
13

Строковые литералы в MySQL и PHP одинаковы.

Строка - это последовательность байтов или символов, заключенная в одинарные кавычки («'») или двойные кавычки («» »).

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

В основном, мы используем одинарные кавычки для значения строки SQL, поэтому нам нужно использовать двойные кавычки для строки PHP.

$query = "INSERT INTO table (id, col1, col2) VALUES (NULL, 'val1', 'val2')";

И вы можете использовать переменную в строке двойных кавычек PHP:

$query = "INSERT INTO table (id, col1, col2) VALUES (NULL, '$val1', '$val2')";

Но если $val1или $val2содержит одинарные кавычки, это сделает ваш SQL ошибочным. Так что вам нужно избежать его, прежде чем он будет использован в SQL; вот mysql_real_escape_stringдля чего. (Хотя подготовленное утверждение лучше.)

xdazz
источник
12

В сочетании с PHP и MySQL двойные кавычки и одинарные кавычки значительно упрощают процесс написания запросов.

$query = "INSERT INTO `table` (`id`, `col1`, `col2`) VALUES (NULL, '$val1', '$val2')";

Теперь, предположим, что вы используете прямую переменную post в запросе MySQL, используйте ее следующим образом:

$query = "INSERT INTO `table` (`id`, `name`, `email`) VALUES (' ".$_POST['id']." ', ' ".$_POST['name']." ', ' ".$_POST['email']." ')";

Это лучший способ использования PHP-переменных в MySQL.

Vipul Sorathiya
источник
Поэтому двойные кавычки являются гибкими, но не могут использоваться в качестве идентификаторов.
Равендк
Пожалуйста, никогда не используйте в своем запросе неэкранированный пользовательский ввод!
jankal
@jankal Это просто пример. Я указал, что если вы используете прямой пользовательский ввод, то тогда n ...........
vipul sorathiya
@vipulsorathiya Пожалуйста, укажите в своем ответе, что переменные POST должны быть экранированы. Теперь вы указываете на использование их непосредственно в вашем запросе. Плохо для начинающих, которые пытаются это ...
RFLdev
12

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

  1. BACKTICKS (`) используются вокруг имен идентификаторов.
  2. ЕДИНЫЕ ЦИТАТЫ (') используются вокруг значений.

И как сказал @MichaelBerkowski

Обратные метки должны использоваться для идентификаторов таблицы и столбца, но они необходимы только в том случае, если идентификатор является MySQLзарезервированным ключевым словом или когда идентификатор содержит пробельные символы или символы за пределами ограниченного набора (см. Ниже). Часто рекомендуется избегать использования зарезервированных ключевых слов как идентификаторы столбцов или таблиц, когда это возможно, избегая проблемы цитирования.

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

ПРИМЕР

123E10является допустимым именем идентификатора, но также действительным INTEGERлитералом.

[Не вдаваясь в подробности, как вы могли бы получить такое имя идентификатора], предположим, я хочу создать временную таблицу с именем 123456e6.

Нет ошибок на спинах.

DB [XXX]> create temporary table `123456e6` (`id` char (8));
Query OK, 0 rows affected (0.03 sec)

ОШИБКА, когда не используется обратная пометка.

DB [XXX]> create temporary table 123451e6 (`id` char (8));
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '123451e6 (`id` char (8))' at line 1

Тем не менее, 123451a6это идеально точное имя идентификатора (без обратной галочки).

DB [XXX]> create temporary table 123451a6 (`id` char (8));
Query OK, 0 rows affected (0.03 sec)

Это полностью потому, что 1234156e6это также экспоненциальное число.

MJ007
источник
10

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

С двойными кавычками ""полный запрос:

$query = "INSERT INTO $table_name (id, $col1, $col2)
                 VALUES (NULL, '$val1', '$val2')";

Или

 $query = "INSERT INTO ".$table_name." (id, ".$col1.", ".$col2.")
               VALUES (NULL, '".$val1."', '".$val2."')";

С одинарными кавычками '':

$query = 'INSERT INTO '.$table_name.' (id, '.$col1.', '.$col2.')
             VALUES (NULL, '.$val1.', '.$val2.')';

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

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

`table_name`, `column_name` <- Примечание: исключить . из обратных тиков.

diEcho
источник
8

Одиночные кавычки должны использоваться для строковых значений, как в списке VALUES ().

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

В сочетании с PHP и MySQL двойные кавычки и одинарные кавычки значительно ускоряют процесс написания запроса.

Джон Игнил
источник
4

Помимо всех (хорошо объясненных) ответов, не было упомянуто следующего, и я часто посещаю эти вопросы и ответы.

В двух словах; MySQL думает, что вы хотите заняться математикой для своей таблицы / столбца, и интерпретирует такие дефисы, как «электронная почта», как e минус mail .


Отказ от ответственности: поэтому я подумал, что добавлю это как ответ типа «FYI» для тех, кто совершенно новичок в работе с базами данных и может не понимать уже описанные технические термины.

Funk Forty Niner
источник
1

SQL-серверы и MySQL, PostgreySQL, Oracle не понимают двойные кавычки ("). Таким образом, ваш запрос не должен содержать двойных кавычек (") и должен использовать только одинарные кавычки (').

Back-trip (`) необязательно использовать в SQL и используется для имени таблицы, имени БД и имени столбца.

Если вы пытаетесь написать запрос в своем бэкэнде для вызова MySQL, то вы можете использовать двойные кавычки (") или одинарные кавычки (') для назначения запроса переменной, например:

let query = "select id, name from accounts";
//Or
let query = 'select id, name from accounts';

Если whereв вашем запросе есть оператор и / или пытающийся insertполучить значение и / или updateзначение, которое является строкой, используйте одинарную кавычку (') для таких значений, как:

let querySelect = "select id, name from accounts where name = 'John'";
let queryUpdate = "update accounts set name = 'John' where id = 8";
let queryInsert = "insert into accounts(name) values('John')";

//Please not that double quotes are only to be used in assigning string to our variable not in the query
//All these below will generate error

let querySelect = 'select id, name from accounts where name = "John"';
let queryUpdate = 'update accounts set name = "John" where id = 8';
let queryInsert = 'insert into accounts(name) values("John")';

//As MySQL or any SQL doesn't understand double quotes("), these all will generate error.

Если вы хотите избежать путаницы при использовании двойных кавычек (") и одинарных кавычек ('), рекомендую придерживаться одинарных кавычек ('), это будет включать обратную косую черту (), например:

let query = 'select is, name from accounts where name = \'John\'';

Проблема с двойными (") или одиночными (') кавычками возникает, когда нам нужно было присвоить какое-то значение динамически и выполнить некоторую конкатенацию строк, например:

let query = "select id, name from accounts where name = " + fName + " " + lName;
//This will generate error as it must be like name = 'John Smith' for SQL
//However our statement made it like name = John Smith

//In order to resolve such errors use
let query = "select id, name from accounts where name = '" + fName + " " + lName + "'";

//Or using backslash(\)
let query = 'select id, name from accounts where name = \'' + fName + ' ' + lName + '\'';

Если требуется дальнейшая очистка, следуйте цитатам в JavaScript

Навин
источник