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

512

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

Пример:

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

Кроме того, в приведенном выше примере рассмотрим, что "table," "col[n]," and "val[n]" могут быть переменными.

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

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

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

12 ответов

527
Лучший ответ

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

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

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

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

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

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

Backtick (`)
table & column ───────┬─────┬──┬──┬──┬────┬──┬────┬──┬────┬──┬───────┐
                      ↓     ↓  ↓  ↓  ↓    ↓  ↓    ↓  ↓    ↓  ↓       ↓
$query = "INSERT INTO `table` (`id`, `col1`, `col2`, `date`, `updated`) 
                       VALUES (NULL, 'val1', 'val2', '2001-01-01', NOW())";
                               ↑↑↑↑  ↑    ↑  ↑    ↑  ↑          ↑  ↑↑↑↑↑ 
Unquoted keyword          ─────┴┴┴┘  │    │  │    │  │          │  │││││
Single-quoted (') strings ───────────┴────┴──┴────┘  │          │  │││││
Single-quoted (') DATE    ───────────────────────────┴──────────┘  │││││
Unquoted function         ─────────────────────────────────────────┴┴┴┴┘    

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

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

// Same thing with some variable replacements
// Here, a variable table name $table is backtick-quoted, and variables
// in the VALUES list are single-quoted 
$query = "INSERT INTO `$table` (`id`, `col1`, `col2`, `date`) VALUES (NULL, '$val1', '$val2', '$date')";

Подготовленные утверждения

При работе с подготовленными инструкциями обратитесь к документации, чтобы определить, должны ли быть указаны тегизаторы заявления. Самые популярные API-интерфейсы, доступные в PHP, PDO и MySQLi, ожидают unquoted заполнители, как и большинство подготовленных 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, вам не нужно quote (backtick), используя следующий набор символов:

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

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

  • 37
    « но одинарные кавычки более широко принимаются другими СУБД » - использование одинарных кавычек для строковых литералов определяется (и требуется) стандартом SQL
  • 0
    @a_horse_with_no_name почти никто не использует ANSI MySQL ('|' для строки concat - правда?)
Показать ещё 9 комментариев
102

В 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 обсуждают это)
29

(Есть хорошие ответы выше, касающиеся характера вашего вопроса 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
19

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

Например:

Use `database`;

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

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

Отметьте этот ответ, чтобы узнать больше об обратных выводах.


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

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

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')
12

В 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'.

11

Строковые литералы в 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. (Хотя подготовленное заявление лучше.)

10

В сочетании 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.

  • 0
    Поэтому двойные кавычки являются гибкими, но не могут использоваться в качестве идентификаторов.
  • 0
    Пожалуйста, никогда не используйте в своем запросе неэкранированный ввод пользователя!
Показать ещё 2 комментария
9

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

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

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

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

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

ПРИМЕР

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

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

Нет ОШИБКИ на backticks.

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 также является экспоненциальным числом.

9

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

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

$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` < Примечание: исключить . из обратных тиков.

7

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

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

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

2

Помимо всех (хорошо объясненных) ответов, не было упомянутых ниже, и я часто бываю в этом Q & A.

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


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

0

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

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

Если вы пытаетесь написать запрос в своем back-end для вызова 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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню