Cuándo usar comillas simples, comillas dobles y backticks en MySQL

633

Estoy tratando de aprender la mejor manera de escribir consultas. También entiendo la importancia de ser consistente. Hasta ahora, he usado al azar comillas simples, comillas dobles y backticks sin ningún pensamiento real.

Ejemplo:

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

Además, en el ejemplo anterior, debe tener en cuenta que table, col1, val1, etc., pueden ser variables.

¿Cuál es el estándar para esto? ¿Qué haces?

He estado leyendo respuestas a preguntas similares aquí durante aproximadamente 20 minutos, pero parece que no hay una respuesta definitiva a esta pregunta.

Nate
fuente
16
Tenga en cuenta que esta es una pregunta muy específica de MySQL. SQL en general (es decir, ISO / ANSI SQL) tiene un conjunto diferente de comillas: las comillas dobles son para identificadores delimitados, por ejemplo "tablename", y las comillas simples son para literales, por ejemplo 'this is a some text'. Los back-ticks nunca se usan en SQL estándar. (Si necesita incluir una comilla doble en un identificador, "odd""tablename"'Conan O''Brien'
escríbala

Respuestas:

611

Los backticks deben usarse para los identificadores de tabla y columna, pero solo son necesarios cuando el identificador es una palabra clave reservada de MySQL , o cuando el identificador contiene espacios en blanco o caracteres más allá de un conjunto limitado (ver más abajo) A menudo se recomienda evitar el uso de palabras clave reservadas como identificadores de columna o tabla cuando sea posible, evitando el problema de las citas.

Las comillas simples deben usarse para valores de cadena como en la VALUES()lista. MySQL también admite las comillas dobles para los valores de cadena, pero las comillas simples son más ampliamente aceptadas por otros RDBMS, por lo que es un buen hábito usar comillas simples en lugar de dobles.

MySQL también espera DATEy DATETIMEvalores literales a ser de un solo citado como cadenas como '2001-01-01 00:00:00'. Consulte la documentación de Literales de fecha y hora para obtener más detalles, en particular alternativas para usar el guión -como delimitador de segmento en las cadenas de fecha.

Entonces, usando su ejemplo, yo doble comillas la cadena PHP y usar comillas simples en los valores 'val1', 'val2'. NULLes una palabra clave de MySQL y un valor especial (no), y por lo tanto no está entre comillas.

Ninguno de estos identificadores de tabla o columna son palabras reservadas o hacen uso de caracteres que requieren comillas, pero de todos modos las he citado con comillas invertidas (más sobre esto más adelante ...).

Las funciones nativas del RDBMS (por ejemplo, NOW()en MySQL) no se deben citar, aunque sus argumentos están sujetos a la misma cadena o reglas de cotización de identificador ya mencionadas.

Retroceso (`)
tabla y columna ───────┬─────┬──┬──┬──┬────┬──┬────┬──┬────┬──┬ ───────┐
                      ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
$ query = " INSERTAR EN` table` (`id`,` col1`, `col2`,` date`, `updated`)
                       VALUES (NULL, 'val1', 'val2', '2001-01-01', NOW ()) ";
                               ↑↑↑↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑↑↑↑↑ 
Palabra clave sin comillas ─────┴┴┴┘ │ │ │ │ │ │ │││││
Cadenas entre comillas simples (') ───────────┴────┴──┴────┘ │ │ │││││
Comillas simples (') FECHA ───────────────────────────┴──────────┘ ││││ │
Función sin comillas ─────────────────────────────────────────┴┴┴┴┘    

Interpolación variable

Los patrones de comillas para las variables no cambian, aunque si tiene la intención de interpolar las variables directamente en una cadena, debe ser entre comillas dobles en PHP. Solo asegúrese de haber escapado correctamente de las variables para su uso en SQL. ( En su lugar, se recomienda utilizar una API que admita declaraciones preparadas, como protección contra la inyección de SQL ).

// Lo mismo con algunos reemplazos variables
// Aquí, un nombre de tabla variable $ table está entre comillas y las variables
// en la lista VALUES están entre comillas simples 
$ query = "INSERTAR EN` $ table` (`id`,` col1`, `col2`,` date`) VALUES (NULL, '$ val1' , '$ val2' , '$ date' ) ";

Declaraciones preparadas

Cuando trabaje con declaraciones preparadas, consulte la documentación para determinar si se deben citar o no los marcadores de posición de la declaración. Las API más populares disponibles en PHP, PDO y MySQLi, esperan marcadores de posición sin comillas , al igual que las API de declaraciones más preparadas en otros idiomas:

// 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 (?, ?, ?, ?)";

Caracteres que requieren comillas de comillas en los identificadores:

De acuerdo con la documentación de MySQL , no necesita citar identificadores (retroceso) utilizando el siguiente conjunto de caracteres:

ASCII: [0-9,a-z,A-Z$_](letras latinas básicas, dígitos 0-9, dólar, guión bajo)

Puede usar caracteres más allá de ese conjunto como identificadores de tabla o columna, incluido el espacio en blanco, por ejemplo, pero luego debe citarlos (hacer retroceso).

Michael Berkowski
fuente
43
" pero las comillas simples son más ampliamente aceptadas por otros RDBMS " - el uso del uso de comillas simples para literales de cadena está definido (y es requerido) por el estándar SQL
a_horse_with_no_name
@a_horse_with_no_name casi nadie usa ANSI MySQL ('|' para string concat - ¿en serio?)
Buena persona
3
esto no es cierto: "MySQL también espera que los valores literales DATE y DATETIME sean entrecomillados como cadenas como '2001-01-01 00:00:00'"
Kick_the_BUCKET
3
@evilReiko Los documentos MySQL no parecen abordar el alias entre comillas claramente. Aceptará un solo, doble o retroceso para los alias, pero eso puede verse afectado por diferentes modos ANSI SQL. No estoy seguro de lo que requiere la especificación SQL para las comillas de alias: Preferencia personal: por coherencia, las cito igual que los identificadores de columna, es decir, las anulo en reversa si es necesario o las dejo sin comillas si no. No uso comillas simples o dobles en los alias.
Michael Berkowski
2
@GuneyOzsan Sí, muy vulnerable. Nunca use una variable para un nombre de tabla a menos que se haya validado con una lista de nombres de tabla aceptables: cree una matriz de nombres permitidos y verifique que la variable coincida con algo en la lista para que sea segura de usar. De lo contrario, no puede escapar con seguridad de una variable de nombre de tabla para su uso.
Michael Berkowski
121

Hay dos tipos de citas en MySQL:

  1. ' para encerrar literales de cadena
  2. ` para encerrar identificadores como nombres de tabla y columna

Y luego está "cuál es un caso especial. Podría usarse para uno de los propósitos mencionados anteriormente a la vez, dependiendo del servidor MySQL sql_mode:

  1. Por defecto, el "carácter se puede utilizar para encerrar literales de cadena al igual que'
  2. En ANSI_QUOTESmodo, el "carácter se puede usar para encerrar identificadores como`

La siguiente consulta producirá diferentes resultados (o errores) dependiendo del modo SQL:

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

ANSI_QUOTES deshabilitado

La consulta seleccionará el literal de cadena "column"donde la columna fooes igual a cadena"bar"

ANSI_QUOTES habilitado

La consulta seleccionará la columna columndonde la columna fooes igual a la columnabar

Cuándo usar qué

  • Sugiero que evite usar "para que su código se vuelva independiente de los modos SQL
  • Siempre cita los identificadores ya que es una buena práctica (bastantes preguntas sobre SO discuten esto)
Salman A
fuente
32

(Hay buenas respuestas anteriores con respecto a la naturaleza SQL de su pregunta, pero esto también puede ser relevante si es nuevo en PHP).

Quizás sea importante mencionar que PHP maneja cadenas entre comillas simples y dobles de manera diferente ...

Las cadenas entre comillas simples son 'literales' y son prácticamente cadenas WYSIWYG. PHP interpreta las cadenas entre comillas dobles para una posible sustitución de variables (los backticks en PHP no son exactamente cadenas; ejecutan un comando en el shell y devuelven el resultado).

Ejemplos:

$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
Chris Trahey
fuente
23

Los backticks se usan generalmente para indicar identifiery también estar a salvo de usar accidentalmente las palabras clave reservadas .

Por ejemplo:

Use `database`;

Aquí los backticks ayudarán al servidor a comprender que databasede hecho es el nombre de la base de datos, no el identificador de la base de datos.

Lo mismo se puede hacer para los nombres de tabla y nombres de campo. Este es un muy buen hábito si envuelve su identificador de base de datos con backticks.

Verifique esta respuesta para comprender más sobre los backticks.


Ahora sobre comillas dobles y comillas simples (Michael ya lo ha mencionado).

Pero, para definir un valor, debe usar comillas simples o dobles. Veamos otro ejemplo.

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

Aquí he olvidado deliberadamente envolverlo title1con comillas. Ahora el servidor tomará title1como un nombre de columna (es decir, un identificador). Entonces, para indicar que es un valor, debe usar comillas dobles o simples.

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

Ahora, en combinación con PHP, las comillas dobles y las comillas simples hacen que su consulta sea mucho más fácil. Veamos una versión modificada de la consulta en su pregunta.

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

Ahora, usando comillas dobles en PHP, creará las variables $val1y $val2usará sus valores creando así una consulta perfectamente válida. Me gusta

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

hará

INSERT INTO `table` (`id`, `col1`, `col2`) VALUES (NULL, 'my value 1', 'my value 2')
Starx
fuente
15

En MySQL, estos símbolos se usan para delimitar una consulta `, ", 'y ().

  1. "o 'se usan para encerrar valores similares a cadenas "26-01-2014 00:00:00"o '26-01-2014 00:00:00'. Estos símbolos son sólo para las cadenas, funciones de agregado no les gusta now, sumo max.

  2. ` se usa para encerrar nombres de tablas o columnas, p. ej. select `column_name` from `table_name` where id='2'

  3. (y )simplemente encierra partes de una consulta, por ejemplo select `column_name` from `table_name` where (id='2' and gender='male') or name='rakesh'.

Kumar Rakesh
fuente
13

Los literales de cadena en MySQL y PHP son los mismos.

Una cadena es una secuencia de bytes o caracteres, encerrada entre comillas simples (“'”) o comillas dobles (“" ”).

Entonces, si su cadena contiene comillas simples, entonces podría usar comillas dobles para citar la cadena, o si contiene comillas dobles, entonces podría usar comillas simples para citar la cadena. Pero si su cadena contiene comillas simples y comillas dobles, debe escapar de la que solía citar la cadena.

Principalmente, usamos comillas simples para un valor de cadena SQL, por lo que necesitamos usar comillas dobles para una cadena PHP.

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

Y podría usar una variable en la cadena de comillas dobles de PHP:

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

Pero si $val1o $val2contiene comillas simples, eso hará que su SQL esté equivocado. Por lo tanto, debe escapar antes de que se use en sql; para eso sirve mysql_real_escape_string. (Aunque una declaración preparada es mejor).

xdazz
fuente
12

En combinación de PHP y MySQL, las comillas dobles y las comillas simples hacen que el tiempo de escritura de consultas sea mucho más fácil.

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

Ahora, suponga que está utilizando una variable de publicación directa en la consulta MySQL y luego úsela de esta manera:

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

Esta es la mejor práctica para usar variables PHP en MySQL.

vipul sorathiya
fuente
Por lo tanto, las comillas dobles son flexibles pero no se pueden usar como identificadores.
rhavendc
¡Nunca use directamente la entrada de usuario sin escape en su consulta!
jankal
@jankal Es solo un ejemplo. Especifiqué que si está utilizando la entrada directa del usuario, entonces n entonces ...........
vipul sorathiya
@vipulsorathiya Especifique en su respuesta que las variables POST deben escaparse. Ahora está apuntando a usarlos directamente en su consulta. Malo para los principiantes que prueban esto ...
RFLdev
12

Aquí ha habido muchas respuestas útiles, que generalmente culminan en dos puntos.

  1. Los BACKTICKS (`) se usan alrededor de los nombres de los identificadores.
  2. Las COTIZACIONES SIMPLES (') se usan alrededor de los valores.

Y como dijo @MichaelBerkowski

Los backticks deben usarse para los identificadores de tabla y columna, pero solo son necesarios cuando el identificador es una MySQLpalabra clave reservada, o cuando el identificador contiene espacios en blanco o caracteres más allá de un conjunto limitado (ver más abajo). A menudo se recomienda evitar el uso de palabras clave reservadas como identificadores de columna o tabla cuando sea posible, evitando el problema de las citas.

Sin embargo, hay un caso en el que un identificador no puede ser una palabra clave reservada o contener espacios en blanco o caracteres más allá de un conjunto limitado, sino que necesariamente requiere retrocesos a su alrededor.

EJEMPLO

123E10 es un nombre de identificador válido pero también un nombre válido INTEGER literal .

[Sin entrar en detalles sobre cómo obtendría un nombre de identificador de este tipo], suponga que quiero crear una tabla temporal llamada 123456e6.

Sin ERROR en backticks.

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

ERROR cuando no usa backticks.

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

Sin embargo, 123451a6es un nombre de identificador perfectamente fino (sin marcas de retroceso).

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

Esto es completamente porque 1234156e6también es un número exponencial.

MJ007
fuente
10

Si los valores y valores de la tabla son variables, entonces hay dos formas:

Con comillas dobles ""la consulta completa:

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

O

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

Con comillas simples '':

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

Use garrapatas `` cuando el nombre de una columna / valor sea similar a una palabra clave reservada de MySQL.

Nota: Si está denotando un nombre de columna con el nombre de una tabla, use los ticks de regreso como este:

`table_name`. `column_name` <- Nota: excluir . de los ticks posteriores.

diEcho
fuente
8

Las comillas simples deben usarse para valores de cadena como en la lista VALUES ().

Los backticks se usan generalmente para indicar un identificador y también para evitar el uso accidental de las palabras clave reservadas.

En combinación de PHP y MySQL, las comillas dobles y las comillas simples hacen que su consulta sea mucho más fácil.

john igneel
fuente
4

Además de todas las respuestas (bien explicadas), no se ha mencionado lo siguiente y visito estas preguntas y respuestas con bastante frecuencia.

En una palabra; MySQL cree que desea hacer cálculos matemáticos en su propia tabla / columna e interpreta guiones como "correo electrónico" como e menos mail .


Descargo de responsabilidad: Entonces pensé que agregaría esto como un tipo de respuesta "FYI" para aquellos que son completamente nuevos en el trabajo con bases de datos y que pueden no entender los términos técnicos ya descritos.

Funk Forty Niner
fuente
1

Los servidores SQL y MySQL, PostgreySQL, Oracle no entienden las comillas dobles ("). Por lo tanto, su consulta debe estar libre de comillas dobles (") y solo debe usar comillas simples (').

Back-trip (`) es opcional para usar en SQL y se usa para nombre de tabla, nombre de base de datos y nombres de columna.

Si está intentando escribir una consulta en su back-end para llamar a MySQL, entonces puede usar comillas dobles (") o comillas simples (') para asignar consultas a una variable como:

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

Si hay un where declaración en su consulta y / o intenta insertun valor y / o un updatevalor que es una cadena, use comillas simples (') para estos valores como:

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.

Si desea mantenerse alejado de esta confusión sobre cuándo usar comillas dobles (") y comillas simples ('), le recomendamos que se quede con comillas simples ('), esto incluirá una barra diagonal inversa () como:

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

El problema con las comillas dobles (") o simples (') surge cuando tenemos que asignar un valor dinámico y realizar una concatenación de cadenas como:

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 + '\'';

Si necesita más autorización, siga las citas en JavaScript

NAVIN
fuente