Quando utilizzare virgolette singole, virgolette doppie e backtick in MySQL


633

Sto cercando di imparare il modo migliore per scrivere query. Capisco anche l'importanza di essere coerenti. Fino ad ora, ho usato casualmente virgolette singole, doppie virgolette e backtick senza alcun pensiero reale.

Esempio:

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

Inoltre, nel precedente esempio, si consideri che table, col1, val1, ecc possono essere variabili.

Qual è lo standard per questo? cosa fai?

Ho letto le risposte a domande simili qui per circa 20 minuti, ma sembra che non ci sia una risposta definitiva a questa domanda.


16
Nota che questa è una domanda specifica per MySQL. SQL in generale (ovvero ISO / ANSI SQL) ha un diverso insieme di virgolette: le virgolette doppie sono per identificatori delimitati, ad es "tablename". E le virgolette singole sono per letterali, ad es 'this is a some text'. I segni di spunta non vengono mai utilizzati in SQL standard. (Se è necessario includere una doppia virgoletta in un identificatore, digitarla due volte come "odd""tablename". Allo stesso modo, raddoppiare le virgolette singole in letterali, come 'Conan O''Brien'.)
jarlh

Risposte:


611

I backtick devono essere utilizzati per identificatori di tabelle e colonne, ma sono necessari solo quando l'identificatore è una parola chiave riservata MySQL o quando l'identificatore contiene caratteri di spazi bianchi o caratteri oltre un set limitato (vedere di seguito) Si consiglia spesso di evitare l'uso di parole chiave riservate come identificatori di colonne o tabelle quando possibile, evitando il problema di quotazione.

Le virgolette singole dovrebbero essere utilizzate per i valori di stringa come VALUES()nell'elenco. Le virgolette doppie sono supportate da MySQL anche per i valori di stringa, ma le virgolette singole sono più ampiamente accettate da altri RDBMS, quindi è una buona abitudine utilizzare virgolette singole anziché doppie.

MySQL anche aspetta DATEe DATETIMEvalori letterali di essere single-citato come stringhe come '2001-01-01 00:00:00'. Consultare la documentazione letterali di data e ora per maggiori dettagli, in particolare le alternative all'uso del trattino -come delimitatore di segmento nelle stringhe di date.

Quindi, usando il tuo esempio, citerei due volte la stringa PHP e userei virgolette singole sui valori 'val1', 'val2'. NULLè una parola chiave MySQL e un valore speciale (non), quindi non quotato.

Nessuno di questi identificatori di tabelle o colonne sono parole riservate o fanno uso di caratteri che richiedono una citazione, ma li ho comunque citati con i backtick (ne parleremo più avanti ...).

Le funzioni native di RDBMS (ad esempio, NOW()in MySQL) non devono essere citate, sebbene i loro argomenti siano soggetti alla stessa stringa o identificatore delle regole di quotazione già menzionate.

Backtick (`)
tabella e colonna ───────┬─────┬──┬──┬──┬────┬──┬────┬──┬─────┬──┬ ───────┐
                      ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
$ query = " INSERISCI IN` table` (`id`,` col1`, `col2`,` date`, `updated`)
                       VALUES (NULL, 'val1', 'val2', '2001-01-01', NOW ()) ";
                               ↑↑↑↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑↑↑↑↑ 
Parola chiave non quotata ─────┴┴┴┘ │ │ │ │ │ │ │││││
Stringhe a virgoletta singola (') ───────────┴────┴──┴────┘ │ │ │││││
DATA (') a virgoletta singola ────────────────────────────┴───────────┘ ││││ │
Funzione non quotata ───────────────────────────────────────────┴┴┴┴┘    

Interpolazione variabile

I modelli di quotazione per le variabili non cambiano, anche se se si intende interpolare le variabili direttamente in una stringa, è necessario che siano doppie virgolette in PHP. Assicurati solo di essere sfuggito correttamente alle variabili per l'uso in SQL. ( Si consiglia invece di utilizzare un'API che supporti le istruzioni preparate, come protezione contro l'iniezione SQL ).

// Stessa cosa con alcune sostituzioni variabili
// In questo caso, il nome di una tabella $ table viene quotato a rovescio e variabili
// nell'elenco VALORI sono a virgoletta singola 
$ query = "INSERISCI IN` $ table` (`id`,` col1`, `col2`,` date`) VALUES (NULL, '$ val1' , '$ val2' , '$ date' ) ";

Dichiarazioni preparate

Quando si lavora con dichiarazioni preparate, consultare la documentazione per determinare se i segnaposto della dichiarazione devono essere quotati o meno. Le API più popolari disponibili in PHP, DOP e MySQLi si aspettano segnaposti non quotati, così come le API delle dichiarazioni più preparate in altre lingue:

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

Caratteri che richiedono il backtick tra virgolette negli identificatori:

Secondo la documentazione di MySQL , non è necessario citare gli identificativi (backtick) utilizzando il seguente set di caratteri:

ASCII: [0-9,a-z,A-Z$_](lettere latine di base, cifre 0-9, dollaro, trattino basso)

È possibile utilizzare caratteri oltre quell'insieme come identificatori di tabella o colonna, incluso ad esempio spazi bianchi, ma è necessario citarli (backtick).


43
" ma le virgolette singole sono più ampiamente accettate dagli altri RDBMS " - l'uso delle virgolette singole per i letterali di stringa è definito (e richiesto) dallo standard SQL
a_horse_with_no_name

@a_horse_with_no_name quasi nessuno usa ANSI MySQL ('|' per la stringa concat - davvero?)
Brava persona

3
questo non è vero: "MySQL si aspetta anche che i valori letterali DATE e DATETIME siano citati come stringhe come '2001-01-01 00:00:00'"
Kick_the_BUCKET

3
@evilReiko I documenti di MySQL non sembrano indirizzare chiaramente gli alias. Accetterà singoli, doppi o backtick per gli alias ma che potrebbero essere influenzati da diverse modalità ANSI SQL. Non sono sicuro di cosa richiedano le specifiche SQL per le virgolette alias - Preferenza personale: per coerenza le cito allo stesso modo degli identificatori di colonna - cioè, le inserisco di nuovo se necessario, o le lascio non quotate in caso contrario. Non uso virgolette singole o doppie sugli alias.
Michael Berkowski,

2
@GuneyOzsan Sì, molto vulnerabile. Non usare mai una variabile per un nome di tabella a meno che non sia stata convalidata rispetto a un elenco di nomi di tabella accettabili: crea un array di nomi consentiti e controlla che la variabile corrisponda a qualcosa nell'elenco per renderlo sicuro da usare. Altrimenti non è possibile evitare in modo sicuro l'uso di una variabile di nome tabella
Michael Berkowski,

121

Esistono due tipi di citazioni in MySQL:

  1. ' per racchiudere letterali stringa
  2. ` per racchiudere identificatori come nomi di tabelle e colonne

E poi c'è "un caso speciale. Potrebbe essere utilizzato per uno dei suddetti scopi alla volta a seconda del server MySQL sql_mode:

  1. Per impostazione predefinita, il "carattere può essere utilizzato per racchiudere i letterali di stringa proprio come'
  2. In ANSI_QUOTESmodalità il "personaggio può essere usato per racchiudere identificatori proprio come`

La query seguente produrrà risultati (o errori) diversi a seconda della modalità SQL:

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

ANSI_QUOTES disabilitato

La query selezionerà la stringa letterale in "column"cui la colonna fooè uguale alla stringa"bar"

ANSI_QUOTES abilitato

La query selezionerà la colonna in columncui la colonna fooè uguale alla colonnabar

Quando usare cosa

  • Ti suggerisco di evitare l'uso in "modo che il tuo codice diventi indipendente dalle modalità SQL
  • Cita sempre gli identificatori poiché è una buona pratica (alcune domande su SO ne discutono)

32

(Ci sono buone risposte sopra riguardo alla natura SQL della tua domanda, ma questo può essere rilevante anche se non conosci PHP.)

Forse è importante menzionare che PHP gestisce le stringhe tra virgolette singole e doppie in modo diverso ...

Le stringhe a virgoletta singola sono "letterali" e sono praticamente stringhe WYSIWYG. Le stringhe tra virgolette vengono interpretate da PHP per una possibile sostituzione di variabili (i backtick in PHP non sono esattamente stringhe; eseguono un comando nella shell e restituiscono il risultato).

Esempi:

$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

Backticks sono generalmente utilizzati per indicare una identifiere così essere sicuri di utilizzare accidentalmente Parole chiave riservate .

Per esempio:

Use `database`;

Qui i backtick aiuteranno il server a capire che databasein realtà è il nome del database, non l'identificatore del database.

Lo stesso può essere fatto per i nomi delle tabelle e dei campi. Questa è un'abitudine molto buona se si avvolge l'identificatore del database con backtick.

Controlla questa risposta per saperne di più sui backtick.


Ora su citazioni doppie e virgolette singole (Michael ha già detto che).

Ma, per definire un valore devi usare virgolette singole o doppie. Vediamo un altro esempio.

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

Qui ho deliberatamente dimenticato di avvolgere le title1virgolette. Ora il server prenderà il title1nome di una colonna (cioè un identificatore). Quindi, per indicare che è un valore devi usare virgolette doppie o singole.

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

Ora, in combinazione con PHP, le virgolette doppie e le virgolette singole rendono il tempo di scrittura delle query molto più semplice. Vediamo una versione modificata della query nella tua domanda.

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

Ora, usando le doppie virgolette nel PHP, creerai le variabili $val1e $val2utilizzerai i loro valori creando così una query perfettamente valida. Piace

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

15

In MySQL, questi simboli sono usati per delimitare una query `, ", 'e ().

  1. "o 'sono usati per racchiudere valori simili a stringhe "26-01-2014 00:00:00"o '26-01-2014 00:00:00'. Questi simboli sono solo per le stringhe, funzioni non aggregate piace now, sumo max.

  2. ` viene utilizzato per racchiudere i nomi di tabelle o colonne, ad es select `column_name` from `table_name` where id='2'

  3. (e )semplicemente racchiudere parti di una query, ad es select `column_name` from `table_name` where (id='2' and gender='male') or name='rakesh'.


13

I valori letterali delle stringhe in MySQL e PHP sono gli stessi.

Una stringa è una sequenza di byte o caratteri, racchiusa tra virgolette singole (“'”) o virgolette doppie (“" ”).

Pertanto, se la stringa contiene virgolette singole, è possibile utilizzare virgolette doppie per citare la stringa o se contiene virgolette doppie, è possibile utilizzare virgolette singole per citare la stringa. Ma se la tua stringa contiene sia virgolette singole che doppie, è necessario sfuggire a quella utilizzata per citare la stringa.

Principalmente, usiamo virgolette singole per un valore di stringa SQL, quindi dobbiamo usare virgolette doppie per una stringa PHP.

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

E potresti usare una variabile nella stringa tra virgolette doppie di PHP:

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

Ma se $val1o $val2contiene virgolette singole, ciò renderà il tuo SQL errato. Quindi è necessario fuggire prima che venga utilizzato in sql; questo è ciò che mysql_real_escape_stringserve. (Anche se una dichiarazione preparata è migliore.)


12

In combinazione tra PHP e MySQL, le virgolette doppie e le virgolette singole rendono il tempo di scrittura delle query molto più semplice.

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

Ora supponiamo che tu stia usando una variabile post diretta nella query MySQL, quindi usala in questo modo:

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

Questa è la migliore pratica per l'utilizzo delle variabili PHP in MySQL.


Pertanto le virgolette doppie sono flessibili ma non possono essere utilizzate come identificatori.
rhavendc,

Per favore, mai e poi mai, direttamente nella tua query, utilizzare direttamente input utente senza caratteri di escape!
jankal,

@jankal È solo un esempio. Ho specificato che se si sta utilizzando l'input diretto dell'utente, allora n allora ...........
vipul sorathiya,

@vipulsorathiya Si prega di specificare nella risposta che le variabili POST devono essere salvate. Ora stai indicando di usarli direttamente nella tua query. Male per i principianti che provano questo ...
RFLdev

12

Ci sono state molte risposte utili qui, che in genere sono culminate in due punti.

  1. I BACKTICK (`) sono usati attorno ai nomi degli identificativi.
  2. PREVENTIVI SINGOLI (') vengono utilizzati attorno ai valori.

E come ha detto @MichaelBerkowski

I backtick devono essere utilizzati per identificatori di tabelle e colonne, ma sono necessari solo quando l'identificatore è una MySQLparola chiave riservata o quando l'identificatore contiene caratteri di spazi bianchi o caratteri oltre un set limitato (vedere di seguito) Si consiglia spesso di evitare l'uso di parole chiave riservate come identificatori di colonne o tabelle quando possibile, evitando il problema di quotazione.

Esiste tuttavia un caso in cui un identificatore non può essere né una parola chiave riservata né contenere spazi bianchi o caratteri oltre l'insieme limitato, ma richiede necessariamente backtick attorno ad essi.

ESEMPIO

123E10è un nome identificativo valido ma anche un valore INTEGERletterale valido .

[Senza entrare nel dettaglio di come si otterrebbe un nome identificativo simile], supponiamo che io voglia creare una tabella temporanea denominata 123456e6.

Nessun errore sui backtick.

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

ERRORE quando non si usano i backtick.

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

Tuttavia, 123451a6è un nome identificativo perfettamente preciso (senza segni di spunta).

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

Questo è completamente perché 1234156e6è anche un numero esponenziale.


10

Se i valori e le colonne della tabella sono variabili, esistono due modi:

Con virgolette doppie ""la query 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 virgolette singole '':

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

Utilizzare i segni di spunta indietro ``quando un nome di colonna / valore è simile a una parola chiave riservata MySQL.

Nota: se si sta indicando un nome di colonna con un nome di tabella, utilizzare i segni di spunta in questo modo:

`table_name`. `column_name` <- Nota: escludi . dalle zecche posteriori.


8

Le virgolette singole devono essere utilizzate per valori stringa come nell'elenco VALUES ().

I backtick vengono generalmente utilizzati per indicare un identificatore e per evitare l'uso accidentale delle parole chiave riservate.

In combinazione tra PHP e MySQL, le virgolette doppie e le virgolette singole rendono il tempo di scrittura delle query molto più semplice.


4

Oltre a tutte le risposte (ben spiegate), non è stato menzionato quanto segue e visito queste domande e risposte abbastanza spesso.

In poche parole; MySQL pensa di voler fare matematica sulla propria tabella / colonna e interpreta trattini come "e-mail" come e meno mail .


Disclaimer: Quindi ho pensato di aggiungere questo come tipo di risposta "FYI" per coloro che sono completamente nuovi a lavorare con i database e che potrebbero non comprendere i termini tecnici già descritti.


1

I server SQL e MySQL, PostgreySQL, Oracle non comprendono le doppie virgolette ("). Pertanto, la query deve essere libera da virgolette doppie (") e deve utilizzare solo virgolette singole (').

Back-trip (`) è facoltativo da utilizzare in SQL e viene utilizzato per il nome della tabella, il nome db e i nomi delle colonne.

Se stai provando a scrivere query nel tuo back-end per chiamare MySQL, puoi usare virgolette doppie (") o virgolette singole (') per assegnare una query a una variabile come:

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

Se c'è whereun'istruzione nella tua query e / o prova a insertun valore e / o un updatevalore che è stringa usa virgoletta singola (') per questi valori come:

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 vuoi rimanere fuori da questa confusione quando usi le virgolette doppie (") e le virgolette singole ('), ti consigliamo di attenersi alle virgolette singole (') questo includerà una barra rovesciata () come:

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

Il problema con le virgolette doppie (") o singole (') sorge quando abbiamo dovuto assegnare un valore dinamico ed eseguire una concatenazione di stringhe come:

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 hai bisogno di ulteriore autorizzazione, segui le virgolette in JavaScript

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.