Quando usar aspas simples, aspas duplas e reticulares no MySQL

633

Estou tentando aprender a melhor maneira de escrever consultas. Eu também entendo a importância de ser consistente. Até agora, usei aleatoriamente aspas simples, aspas duplas e reticulares sem nenhum pensamento real.

Exemplo:

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

Além disso, no exemplo acima, considere que table, col1, val1, etc. podem ser variáveis.

Qual é o padrão para isso? O que você faz?

Eu tenho lido respostas para perguntas semelhantes aqui por cerca de 20 minutos, mas parece que não há resposta definitiva para essa pergunta.

Nate
fonte
16
Note que esta é uma pergunta muito específica do MySQL. O SQL em geral (ie ISO / ANSI SQL) possui um conjunto diferente de aspas: aspas duplas são para identificadores delimitados, por exemplo "tablename", e aspas simples são para literais, por exemplo 'this is a some text'. Os back-ticks nunca são usados ​​no SQL padrão. (Se você precisa incluir aspas duplas em um identificador, digite-o duas vezes "odd""tablename"Da mesma forma, plicas duplas em literais, como. 'Conan O''Brien'.)
jarlh

Respostas:

610

Os backticks devem ser usados ​​para identificadores de tabela e coluna, mas são necessários apenas quando o identificador é uma palavra-chave reservada do MySQL , ou quando o identificador contém caracteres de espaço em branco ou caracteres além de um conjunto limitado (veja abaixo). É recomendável evitar o uso de palavras-chave reservadas como identificadores de coluna ou tabela, quando possível, evitando o problema de citação.

Aspas simples devem ser usadas para valores de sequência, como na VALUES()lista. As aspas duplas também são suportadas pelo MySQL para valores de string, mas as aspas simples são mais amplamente aceitas por outros RDBMS, portanto, é um bom hábito usar aspas simples em vez de duplo.

MySQL também espera DATEe DATETIMEvalores literais para ser single-citado como strings como '2001-01-01 00:00:00'. Consulte a documentação Literais de data e hora para obter mais detalhes, em particular alternativas ao uso do hífen -como delimitador de segmento nas cadeias de datas.

Então, usando o seu exemplo, aspas duplas na string PHP e uso aspas simples nos valores 'val1', 'val2'. NULLé uma palavra-chave do MySQL e um valor especial (não) e, portanto, não é citado.

Nenhum desses identificadores de tabela ou coluna são palavras reservadas ou utiliza caracteres que requerem citação, mas as citei de qualquer maneira com backticks (mais sobre isso mais adiante ...).

As funções nativas do RDBMS (por exemplo, NOW()no MySQL) não devem ser citadas, embora seus argumentos estejam sujeitos às mesmas regras de citação de string ou identificador já mencionadas.

Backtick (`)
tabela e coluna ───────┬──────────┬──┬────┬─────────────────────────────┬──┬ ───────┐
                      ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
$ query = " INSERT INTO` tabela` (`id`,` col1`, `col2`,` data`, `atualizada`)
                       VALUES (NULL, 'val1', 'val2', '2001-01-01', NOW ()) ";
                               ↑↑↑↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑↑↑↑↑ 
Palavra-chave não citada ─────┴┴┴┘ │ │ │ │ │ │ │││││
Sequências de aspas simples (') ───────────────┴──┴────┘ │ │ │││││
Aspas simples (') DATA ───────────────────────────────────────────┘ ││││ │
Função não citada ───────────────────────────────────────    

Interpolação variável

Os padrões de citação para variáveis ​​não mudam, embora se você pretender interpolar as variáveis ​​diretamente em uma string, ela deve ser citada duas vezes no PHP. Apenas certifique-se de que você escapou corretamente das variáveis ​​para uso no SQL. ( É recomendável usar uma API que suporte instruções preparadas, como proteção contra injeção de SQL ).

// O mesmo ocorre com algumas substituições de variáveis
// Aqui, um nome de tabela variável $ table é citado por backtick e variáveis
// na lista VALUES são aspas simples 
$ query = "INSERIR EM` $ tabela` (`id`,` col1`, `col2`,` data`) VALORES (NULL, '$ val1' , '$ val2' , '$ date' ) ";

Declarações preparadas

Ao trabalhar com instruções preparadas, consulte a documentação para determinar se os espaços reservados da declaração devem ou não ser citados. As APIs mais populares disponíveis no PHP, PDO e MySQLi esperam espaços reservados não citados, assim como as APIs de declaração mais preparadas em outros 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 requerem backtick entre aspas nos identificadores:

De acordo com a documentação do MySQL , você não precisa citar identificadores (backtick) usando o seguinte conjunto de caracteres:

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

Você pode usar caracteres além desse conjunto como identificadores de tabela ou coluna, incluindo espaços em branco, por exemplo, mas depois deve citá-los (backtick).

Michael Berkowski
fonte
43
" Mas aspas simples são mais amplamente aceite por outros RDBMS " - usando aspas simples para strings literais é definido (e necessário) pelo padrão SQL
a_horse_with_no_name
@a_horse_with_no_name quase ninguém usa o ANSI MySQL ('|' para concat de strings - realmente?)
Boa pessoa
3
isso não é verdade: "O MySQL também espera que os valores literais DATE e DATETIME sejam citados como strings como '2001-01-01 00:00:00'"
#
3
@evilReiko Os documentos do MySQL não parecem resolver o alias citando claramente. Ele aceitará single, double ou backtick para aliases, mas isso pode ser afetado por diferentes modos ANSI SQL. Não tenho certeza do que a especificação SQL exige para aspas de alias - preferência pessoal: por consistência, cito-as da mesma forma que os identificadores de coluna - ou seja, eu as recomponho se necessário ou as deixo sem aspas. Não uso aspas simples ou duplas em aliases.
Michael Berkowski
2
@GuneyOzsan Sim, muito vulnerável. Nunca use uma variável para um nome de tabela, a menos que tenha sido validada em uma lista de nomes de tabela aceitáveis ​​- crie uma matriz de nomes permitidos e verifique se a variável corresponde a algo na lista para torná-la segura. Caso contrário, você não poderá escapar com segurança de uma variável de nome da tabela para uso.
Michael Berkowski 27/10/2018
121

Existem dois tipos de citações no MySQL:

  1. ' para incluir literais de cadeia de caracteres
  2. ` para incluir identificadores, como nomes de tabela e coluna

E depois há "um caso especial. Pode ser usado para um dos propósitos mencionados acima, dependendo do servidor MySQL sql_mode:

  1. Por padrão, o "caractere pode ser usado para incluir literais de string, assim como'
  2. No ANSI_QUOTESmodo, o "caractere pode ser usado para incluir identificadores como`

A consulta a seguir produzirá resultados diferentes (ou erros), dependendo do modo SQL:

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

ANSI_QUOTES desativado

A consulta selecionará a string literal "column"onde coluna fooé igual a string"bar"

ANSI_QUOTES ativado

A consulta selecionará a coluna columnonde coluna fooé igual a colunabar

Quando usar o que

  • Sugiro que você evite usar "para que seu código se torne independente dos modos SQL
  • Sempre cite os identificadores, pois é uma boa prática (algumas perguntas sobre SO discutem isso)
Salman A
fonte
32

(Existem boas respostas acima sobre a natureza SQL da sua pergunta, mas isso também pode ser relevante se você é novo no PHP.)

Talvez seja importante mencionar que o PHP lida com seqüências de caracteres simples e duplas de maneira diferente ...

As strings de aspas simples são 'literais' e são basicamente strings WYSIWYG. Strings com aspas duplas são interpretadas pelo PHP para possível substituição de variável (backticks no PHP não são exatamente strings; eles executam um comando no shell e retornam o resultado).

Exemplos:

$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
fonte
23

Os backticks são geralmente usados ​​para indicar identifiere também a segurança de usar acidentalmente as palavras-chave reservadas .

Por exemplo:

Use `database`;

Aqui, os backticks ajudarão o servidor a entender que esse databaseé realmente o nome do banco de dados, não o identificador do banco de dados.

O mesmo pode ser feito para os nomes de tabela e nomes de campo. Esse é um hábito muito bom se você agrupar seu identificador de banco de dados com reticulares.

Verifique esta resposta para entender mais sobre backticks.


Agora, sobre aspas duplas e aspas simples (Michael já mencionou isso).

Mas, para definir um valor, você deve usar aspas simples ou duplas. Vamos ver outro exemplo.

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

Aqui, esqueci-me deliberadamente de colocar as title1aspas. Agora, o servidor usará o title1nome como coluna (ou seja, um identificador). Portanto, para indicar que é um valor, você deve usar aspas duplas ou simples.

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

Agora, em combinação com o PHP, aspas duplas e aspas simples facilitam muito o tempo de escrita da consulta. Vamos ver uma versão modificada da consulta na sua pergunta.

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

Agora, usando aspas duplas no PHP, você criará as variáveis $val1e $val2usará seus valores, criando assim uma consulta perfeitamente válida. Gostar

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

fará

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

No MySQL, esses símbolos são usados para delimitar uma consulta `, ", 'e ().

  1. "ou 'são usados ​​para incluir valores semelhantes a cadeias "26-01-2014 00:00:00"ou '26-01-2014 00:00:00'. Estes símbolos são apenas para cordas, funções não agregados gosta now, sumou max.

  2. ` é usado para incluir nomes de tabelas ou colunas, por exemplo select `column_name` from `table_name` where id='2'

  3. (e )simplesmente coloque partes de uma consulta, por exemplo select `column_name` from `table_name` where (id='2' and gender='male') or name='rakesh'.

Kumar Rakesh
fonte
13

Os literais de string no MySQL e PHP são os mesmos.

Uma cadeia de caracteres é uma sequência de bytes ou caracteres, entre aspas simples (“'”) ou aspas duplas (“” ”).

Portanto, se sua string contiver aspas simples, você poderá usar aspas duplas para citá-la ou, se contiver aspas duplas, poderá usar aspas simples para aspas. Mas se sua string contiver aspas simples e aspas duplas, você precisará escapar da que costumava aspas a string.

Geralmente, usamos aspas simples para um valor de string SQL, portanto, precisamos usar aspas duplas para uma string PHP.

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

E você pode usar uma variável na string de aspas duplas do PHP:

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

Mas se $val1ou $val2contiver aspas simples, isso fará com que seu SQL esteja errado. Então você precisa escapar antes que seja usado no sql; é para isso que mysql_real_escape_stringserve. (Embora uma declaração preparada seja melhor.)

xdazz
fonte
12

Em combinação com PHP e MySQL, aspas duplas e aspas simples facilitam muito o tempo de escrita da consulta.

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

Agora, suponha que você esteja usando uma variável de postagem direta na consulta do MySQL, use-a desta maneira:

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

Esta é a melhor prática para usar variáveis ​​PHP no MySQL.

vipul sorathiya
fonte
Portanto, aspas duplas são flexíveis, mas não podem ser usadas como identificadores.
Rhavendc 31/05
Por favor, nunca use diretamente a entrada do usuário sem escape em sua consulta!
jankal
@jankal É apenas example.I especifiquei que se você estiver usando entrada direta do usuário, então n então ...........
vipul sorathiya
@vipulsorathiya Especifique na sua resposta que as variáveis ​​POST devem ser escapadas. Agora você está apontando para usá-los diretamente em sua consulta. Bad para iniciantes que tentam isso ...
RFLdev
12

Houve muitas respostas úteis aqui, geralmente culminando em dois pontos.

  1. BACKTICKS (`) são usados ​​em torno dos nomes dos identificadores.
  2. CITAÇÕES ÚNICAS (') são usadas em torno de valores.

E como @MichaelBerkowski disse

Os backticks devem ser usados ​​para identificadores de tabela e coluna, mas são necessários apenas quando o identificador é uma MySQLpalavra-chave reservada, ou quando o identificador contém caracteres de espaço em branco ou caracteres além de um conjunto limitado (veja abaixo). É recomendável evitar o uso de palavras-chave reservadas como identificadores de coluna ou tabela, quando possível, evitando o problema de citação.

No entanto, existe um caso em que um identificador não pode ser uma palavra - chave reservada ou conter espaços em branco ou caracteres além de um conjunto limitado, mas requer necessariamente backticks ao seu redor.

EXEMPLO

123E10é um nome de identificador válido, mas também um INTEGERliteral válido .

[Sem entrar em detalhes como você obteria esse nome de identificador], suponha que eu queira criar uma tabela temporária chamada 123456e6.

Sem ERRO nos backticks.

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

ERRO quando não estiver usando 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

No entanto, 123451a6é um nome de identificador perfeitamente adequado (sem marcas de retorno).

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

Isso é completamente porque 1234156e6também é um número exponencial.

MJ007
fonte
10

Se valores e colunas da tabela são variáveis, existem duas maneiras:

Com aspas duplas, ""a consulta completa:

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

Ou

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

Com aspas simples '':

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

Use back ticks ``quando um nome de coluna / valor for semelhante a uma palavra-chave reservada do MySQL.

Nota: Se você estiver indicando um nome de coluna com um nome de tabela, use ticks de volta como este:

`table_name`. `column_name` <- Nota: excluir . dos ticks anteriores.

diEcho
fonte
8

Aspas simples devem ser usadas para valores de sequência, como na lista VALUES ().

Os backticks são geralmente usados ​​para indicar um identificador e também protegem contra o uso acidental das palavras-chave reservadas.

Em combinação com PHP e MySQL, aspas duplas e aspas simples facilitam muito o tempo de escrita da consulta.

john igneel
fonte
4

Além de todas as respostas (bem explicadas), não houve o seguinte mencionado e eu visito essas perguntas e respostas com bastante frequência.

Em poucas palavras; O MySQL acha que você deseja fazer contas em sua própria tabela / coluna e interpreta hífens como "e-mail" como e menos mail .


Isenção de responsabilidade: Pensei em acrescentar isso como um tipo de resposta "para sua informação" para aqueles que são completamente novos em trabalhar com bancos de dados e que podem não entender os termos técnicos já descritos.

Funk Quarenta Niner
fonte
1

Servidores SQL e MySQL, PostgreySQL, Oracle não entendem aspas duplas ("). Portanto, sua consulta deve estar livre de aspas duplas (") e deve usar apenas aspas simples (').

O retorno (`) é opcional para uso no SQL e é usado para o nome da tabela, o nome do banco de dados e os nomes das colunas.

Se você está tentando escrever uma consulta no seu back-end para chamar o MySQL, pode usar aspas duplas (") ou aspas simples (') para atribuir consulta a uma variável como:

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

Se houver uma wheredeclaração na sua consulta e / ou tentar insertum valor e / ou updatevalor que seja string, use aspas simples (') para esses 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.

Se você quiser ficar de fora dessa confusão quando usar aspas duplas (") e aspas simples ('), recomendo ficar com aspas simples ('), isso incluirá barra invertida () como:

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

Problema com aspas duplas (") ou simples (') surge quando tivemos que atribuir algum valor dinâmico e executar alguma concatenação de cadeias, 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 + '\'';

Se precisar de mais espaço, siga as aspas em JavaScript

NAVIN
fonte