web-dev-qa-db-fra.com

Quand utiliser des guillemets simples, des guillemets doubles et des ticks arrière dans MySQL

J'essaie d'apprendre le meilleur moyen d'écrire des requêtes. Je comprends aussi l'importance d'être cohérent. Jusqu'à présent, j'ai utilisé de manière aléatoire des guillemets simples, des guillemets doubles et des ticks arrière sans aucune pensée réelle.

Exemple:

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

En outre, dans l'exemple ci-dessus, considérons que "table," "col[n]," and "val[n]" peut être une variable.

Quelle est la norme pour cela? Que faire?

Je lis des réponses à des questions similaires ici depuis environ 20 minutes, mais il semble qu’il n’ya pas de réponse définitive à cette question.

546
Nate

Les pseudonymes doivent être utilisés pour les identifiants de table et de colonne, mais ils ne sont nécessaires que si l'identifiant est un mot clé réservé MySQL , ou si l'identifiant contient des caractères d'espacement ou des caractères dépassant un ensemble limité (voir ci-dessous) évitez autant que possible d'utiliser des mots clés réservés comme identificateurs de colonne ou de table, en évitant le problème de la citation.

Les guillemets simples doivent être utilisés pour les valeurs de chaîne, comme dans la liste VALUES(). Les guillemets doubles sont également pris en charge par MySQL pour les valeurs de chaîne, mais les guillemets simples sont plus largement acceptés par les autres SGBDR. Il est donc bon d’utiliser des guillemets simples au lieu de doubles.

MySQL s'attend également à ce que les valeurs littérales DATE et DATETIME soient entre guillemets simples sous forme de chaînes telles que '2001-01-01 00:00:00'. Consultez les littéraux de date et d'heure pour plus de détails, en particulier sur les alternatives à l'utilisation du trait d'union - comme délimiteur de segment dans les chaînes de date.

Donc, en utilisant votre exemple, je citerais deux fois la chaîne PHP et utiliserais des guillemets simples pour les valeurs 'val1', 'val2'. NULL est un mot-clé MySQL et une valeur (non) spéciale, et n'est donc pas cité.

Aucun de ces identifiants de table ou de colonne ne sont des mots réservés ou n'utilisent des caractères nécessitant des guillemets, mais je les ai quand même cités avec des guillemets (plus à ce sujet plus tard ...).

Les fonctions natives du SGBDR (par exemple, NOW() dans MySQL) ne doivent pas être citées, bien que leurs arguments soient soumis aux mêmes règles de citation de chaîne ou d'identifiant déjà mentionnées.

Backtick (`) 
 Table et colonne ───────┬─────┬──┬──┬──┬────┬──┬────┬──┬─ 
 __ __ __ __ 
 $ Query = "INSERT INTO `table` (` id`, `col1`,` col2`, `date`,` mis à jour`) 
 VALEURS (NULL, 'val1', 'val2', '2001-01-01', NOW ())"; 
 ↑↑↑↑ ↑ ↑ ↑ ↑ ↑ ↑↑↑↑↑ 
 Mot-clé non cité ─────┴┴┴┘ │ 
 Unique- guillemets (') chaînes │ │││││ 
 Single-quoted (') DATE ────────────────────────┴──────────┘ │││││ 
 Fonction non cotée 

Interpolation variable

Les modèles de cotation pour les variables ne changent pas, bien que si vous avez l'intention d'interpoler les variables directement dans une chaîne, celle-ci doit être double entre PHP. Assurez-vous simplement que vous avez correctement échappé aux variables à utiliser dans SQL. ( Il est recommandé d'utiliser plutôt une API prenant en charge les instructions préparées, comme protection contre l'injection SQL ).

// Même chose avec quelques remplacements de variable
// Ici, un nom de table de variables $ table est cité par un backtick, et les variables
// dans la liste VALUES sont entre guillemets simples 
 `$ table`  (`id`,` col1`, `col2`,` date`) VALUES (NULL, '$ val1''$ val2''$ date') "; 

Déclarations préparées

Lorsque vous travaillez avec des déclarations préparées, consultez la documentation pour déterminer si les espaces réservés de la déclaration doivent être cités ou non. Les API les plus populaires disponibles en PHP, PDO et MySQLi, s’attendent à des espaces réservés non précisés, comme le font les API d’instruction les plus préparées dans d’autres langues:

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

Caractères nécessitant des guillemets dans les identifiants:

Selon la documentation MySQL , vous n'avez pas besoin de citer les identificateurs (backtick) à l'aide du jeu de caractères suivant:

ASCII: [0-9,a-z,A-Z$_] (lettres latines de base, chiffres 0 à 9, dollar, trait de soulignement)

Vous pouvez utiliser des caractères autres que ceux définis en tant qu'identificateurs de table ou de colonne, y compris les espaces, par exemple, mais vous les {devez} _ les citer (les reprendre à la volée).

536
Michael Berkowski

Il existe deux types de citations dans MySQL:

  1. ' pour inclure des littéraux de chaîne
  2. ` pour les identifiants tels que les noms de table et de colonne

Et puis il y a " qui est un cas particulier. Cela pourrait être utilisé pour un des buts mentionnés ci-dessus à la fois en fonction du sql_mode :

  1. Par défaut, le caractère " peut être utilisé pour entourer les littéraux de chaîne de la même manière que '
  2. Dans ANSI_QUOTES mode, le caractère " peut être utilisé pour entourer des identifiants exactement comme `

La requête suivante produira différents résultats (ou erreurs) en fonction du mode SQL:

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

ANSI_QUOTES désactivé

La requête sélectionnera le littéral de chaîne "column" où la colonne foo est égale à la chaîne "bar"

ANSI_QUOTES activé

La requête sélectionnera la colonne column où la colonne foo est égale à la colonne bar

Quand utiliser quoi

  • Je suggère que vous évitiez d'utiliser " afin que votre code devienne indépendant des modes SQL
  • Citez toujours les identifiants car c'est une bonne pratique (quelques questions sur SO en discuteront)
105
Salman A

(Il existe de bonnes réponses ci-dessus concernant la nature SQL de votre question, mais cela peut également être pertinent si vous êtes débutant en PHP.)

Peut-être est-il important de mentionner que PHP gère différemment les chaînes entre guillemets simples et doubles ...

Les chaînes à guillemet simple sont des «littéraux» et sont en gros des chaînes WYSIWYG. Les chaînes entre guillemets sont interprétées par PHP pour une substitution de variable possible (les backticks dans PHP ne sont pas exactement des chaînes; ils exécutent une commande dans le shell et renvoient le résultat).

Exemples:

$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
29
Chris Trahey

Les backticks sont généralement utilisés pour indiquer une identifier et éviter safe d'utiliser accidentellement les Mots-clés réservés

Par exemple:

Use `database`;

Ici, les backticks aideront le serveur à comprendre que la variable database correspond en fait au nom de la base de données et non à son identificateur.

La même chose peut être faite pour les noms de table et les noms de champs. Ceci est une très bonne habitude si vous recouvrez l'identifiant de votre base de données de backticks.

Cochez this answer pour en savoir plus sur les backticks.


Parlons maintenant des citations doubles et des citations simples (Michael a déjà mentionné cela).

Mais pour définir une valeur, vous devez utiliser des guillemets simples ou doubles. Voyons un autre exemple.

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

Ici, j’ai délibérément oublié d’emballer le title1 avec des guillemets. Maintenant, le serveur prendra le title1 en tant que nom de colonne (c'est-à-dire un identifiant). Ainsi, pour indiquer qu'il s'agit d'une valeur, vous devez utiliser des guillemets simples ou doubles.

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

Maintenant, en combinaison avec PHP, les guillemets doubles et les guillemets simples facilitent considérablement le temps d'écriture d'une requête. Voyons une version modifiée de la requête dans votre question.

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

Maintenant, en utilisant des guillemets dans PHP, vous allez obliger les variables $val1 et $val2 à utiliser leurs valeurs, créant ainsi une requête parfaitement valide. Comme

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

fera

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

Dans MySQL, ces symboles sont utilisés pour délimiter une requête `, ", ' et ().

  1. " ou ' sont utilisés pour inclure des valeurs de type chaîne "26-01-2014 00:00:00" ou '26-01-2014 00:00:00'. Ces symboles ne concernent que les chaînes et non les fonctions d'agrégation telles que now, sum ou max.

  2. ` est utilisé pour entourer des noms de table ou de colonne, par exemple. select `column_name` from `table_name` where id='2'

  3. ( et ) entourent simplement des parties d'une requête, par exemple. select `column_name` from `table_name` where (id='2' and gender='male') or name='rakesh'.

12
Kumar Rakesh

Les littéraux de chaîne dans MySQL et PHP sont identiques.

Une chaîne de caractères est une séquence d'octets ou de caractères, enfermés dans l'un des deux fichiers guillemets simples ("'") ou guillemets doubles ("" ").

Ainsi, si votre chaîne contient des guillemets simples, vous pouvez utiliser des guillemets doubles pour la citer ou si elle contient des guillemets doubles, vous pouvez utiliser des guillemets simples pour la citer. Mais si votre chaîne contient à la fois des guillemets simples et des guillemets doubles, vous devez échapper à celui qui citait la chaîne.

La plupart du temps, nous utilisons des guillemets simples pour une valeur de chaîne SQL. Nous devons donc utiliser des guillemets doubles pour une chaîne PHP.

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

Et vous pourriez utiliser une variable dans la chaîne à double guillemet PHP:

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

Mais si $val1 ou $val2 contient des guillemets simples, votre code SQL sera erroné. Vous devez donc y échapper avant de l’utiliser dans SQL; C'est ce que mysql_real_escape_string est pour. (Bien qu'une déclaration préparée soit meilleure.)

11
xdazz

En combinant PHP et MySQL, les guillemets doubles et les guillemets simples facilitent grandement votre temps d'écriture de requête. 

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

Supposons maintenant que vous utilisez une variable de publication directe dans la requête MySQL, utilisez-la comme suit:

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

Il est recommandé d’utiliser des variables PHP dans MySQL.

10
vipul sorathiya

Si les colonnes et les valeurs de table sont des variables, il existe deux méthodes:

Avec des guillemets doubles "" la requête complète:

$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."')";

Avec guillemets simples '':

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

Utilisez back ticks `` quand un nom de colonne/valeur est similaire à un mot clé réservé MySQL.

Remarque: Si vous indiquez un nom de colonne avec un nom de table, utilisez les ticks arrière comme ceci:

`table_name`. `column_name` <- Remarque: excluez . des ticks arrières.

9
diEcho

Il y a eu beaucoup de réponses utiles ici, aboutissant généralement à deux points.

  1. Les BACKTICKS (`) sont utilisés autour des noms d'identifiant.
  2. LES CITATIONS SIMPLES (') sont utilisées autour des valeurs. 

ET comme @MichaelBerkowski a dit

Les backticks doivent être utilisés pour les identificateurs de table et de colonne, mais sont nécessaire uniquement lorsque l'identifiant est un mot clé réservé MySQL, ou lorsque l'identifiant contient des caractères d'espacement ou des caractères au-delà d'un nombre limité (voir ci-dessous). Il est souvent recommandé d'éviter en utilisant des mots-clés réservés comme identificateurs de colonnes ou de tables, lorsque possible, éviter le problème de la citation.

Il existe un cas cependant où un identifiant ne peut être ni un mot clé réservé, ni contenir un espace, ni des caractères supérieurs à l'ensemble défini, mais nécessite nécessairement des contrecoups autour d'eux.

EXEMPLE

123E10 est un nom d'identifiant valide, mais également un littéral INTEGER valide.

[Sans entrer dans les détails, comment obtenir un tel nom d'identifiant], supposons que je veuille créer une table temporaire nommée 123456e6.

Pas d'erreur sur les backticks.

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

ERREUR lorsque vous n'utilisez pas de 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

Cependant, 123451a6 est un nom d’identificateur parfaitement précis (sans tick arrière).

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

C'est complètement parce que 1234156e6 est aussi un nombre exponentiel.

9
user5574289

Les guillemets simples doivent être utilisés pour les valeurs de chaîne, comme dans la liste VALUES ().

Les backticks sont généralement utilisés pour indiquer un identifiant et pour éviter d’utiliser accidentellement les mots-clés réservés.

En combinant PHP et MySQL, les guillemets doubles et les guillemets simples facilitent grandement la rédaction de votre requête.

7
john igneel

En plus de toutes les réponses (bien expliquées), il n’a pas été mentionné ce qui suit et je visite souvent ce Q & A.

En un mot; MySQL pense que vous voulez faire des mathématiques sur sa propre table/colonne et interprète les traits d'union tels que "e-mail" comme étant e moins mail


Disclaimer: Alors j'ai pensé ajouter ceci comme un type de réponse "FYI" pour ceux qui sont complètement nouveaux dans le travail avec des bases de données et qui peuvent ne pas comprendre les termes techniques déjà décrits.

2
Funk Forty Niner

Les serveurs SQL et MySQL, PostgreySQL et Oracle ne comprennent pas les guillemets ("). Ainsi, votre requête doit être exempte de guillemets (") et ne doit utiliser que des guillemets simples (').

Back-trip (`) est facultatif à utiliser dans SQL et est utilisé pour le nom de la table, le nom de la base de données et le nom des colonnes.

Si vous essayez d'écrire une requête dans votre back-end pour appeler MySQL, vous pouvez utiliser des guillemets doubles (") ou des guillemets simples (') pour affecter une requête à une variable du type:

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

S'il y a une instruction where dans votre requête et/ou si vous essayez de insert une valeur et/ou une update de valeur qui est une chaîne, utilisez un guillemet simple (') pour ces valeurs, comme:

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 vous voulez éviter cette confusion lorsque vous utilisez des guillemets doubles (") et des guillemets simples ('), nous vous recommandons de vous en tenir aux guillemets simples ('), cela inclura une barre oblique inverse () comme:

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

Un problème avec les guillemets simples (") ou simples (') survient lorsque nous avons dû attribuer une valeur dynamique et effectuer une concaténation de chaîne comme:

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 besoin est, suivez quotes en JavaScript

0
NAVIN