Kiedy używać pojedynczych cudzysłowów, podwójnych cudzysłowów i tylnych wskazów w MySQL

Próbuję nauczyć się jak najlepiej pisać zapytania. Rozumiem również znaczenie bycia konsekwentnym. Do tej pory losowo używałem pojedynczych cudzysłowów, podwójnych cudzysłowów i tylnych wskazów bez żadnej prawdziwej myśli.

Przykład:

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

W powyższym przykładzie należy również wziąć pod uwagę, że "table," "col[n]," and "val[n]" mogą być zmiennymi.

Jaki jest standard tego? Czym się zajmujesz?

czytam odpowiedzi na podobne pytania od około 20 minut, ale wydaje się, że tam nie ma jednoznacznej odpowiedzi na to pytanie.

Author: Nate, 2012-07-04

12 answers

Backticks są używane do identyfikatorów tabeli i kolumny, ale są niezbędne tylko wtedy, gdy identyfikator jest zarezerwowanym słowem kluczowym MySQL , lub gdy identyfikator zawiera białe znaki lub znaki poza ograniczonym zestawem (patrz poniżej) często zaleca się unikać używania zarezerwowanych słów kluczowych jako identyfikatorów kolumn lub tabeli, jeśli to możliwe, unikając problemu z cytowaniem.

Pojedyncze cudzysłowy powinny być używane do wartości łańcuchowych, jak na liście VALUES(). Podwójne cudzysłowy są obsługiwane przez MySQL również dla wartości łańcuchowych, ale pojedyncze cudzysłowy są szerzej akceptowane przez inne RDBM, więc dobrym nawykiem jest używanie pojedynczych cudzysłowów zamiast podwójnych.

MySQL oczekuje również, że wartości DATE i DATETIME będą pojedynczo cytowane jako ciągi znaków, takie jak '2001-01-01 00:00:00'. Więcej informacji można znaleźć w dokumentacji literałów daty i czasu , w szczególności w alternatywach dla używania myślnika- jako ogranicznika segmentów w łańcuchach dat.

Więc używając Twojego przykładu, zacytowałbym dwukrotnie PHP string i używać pojedynczych cudzysłowów na wartościach 'val1', 'val2'. NULL jest słowem kluczowym MySQL i specjalną (nie) wartością, dlatego nie jest cytowany.

Żaden z tych identyfikatorów tabeli lub kolumny nie jest słowem zastrzeżonym ani nie używa znaków wymagających cytowania, ale i tak zacytowałem je za pomocą backticks (więcej na ten temat później...).

Funkcje natywne dla RDBMS (na przykład NOW() W MySQL) nie powinny być cytowane, chociaż ich argumenty podlegają tym samym regułom cytowania łańcuchów lub identyfikatorów już wspomniałem.

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         ─────────────────────────────────────────┴┴┴┴┘    

Zmienna interpolacja

Wzorce cytowania zmiennych nie ulegają zmianie, chociaż jeśli zamierzasz interpolować zmienne bezpośrednio w łańcuchu znaków, musi on być dwukrotnie cytowany w PHP. Po prostu upewnij się, że poprawnie uniknąłeś zmiennych do użycia w SQL. (zaleca się zamiast tego użycie API obsługującego przygotowane instrukcje, jako zabezpieczenie przed SQL injection ).

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

Gotowe Oświadczenia

Podczas pracy w przypadku gotowych oświadczeń zapoznaj się z dokumentacją, aby ustalić, czy należy zacytować zastępcze oświadczenia. W przeciwieństwie do innych języków, w których nie można znaleźć żadnych informacji na temat tego, czy są one dostępne w PHP, PDO i MySQLi, można je znaleźć w plikach zastępczych unquoted, podobnie jak w przypadku większości preparowanych interfejsów API instrukcji w innych językach:

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

Znaki przypominające cytowanie w identyfikatorach:

Zgodnie z dokumentacją MySQL , nie trzeba cytować (backtick) identyfikatorów za pomocą następującego znaku zestaw:

ASCII: [0-9,a-z,A-Z$_] (podstawowe litery łacińskie, cyfry 0-9, Dolar, podkreślenie)

Możesz używać znaków poza tym zestawem jako identyfikatorów tabeli lub kolumny, w tym na przykład białych znaków, ale wtedy musisz cytować je (backtick).

 500
Author: Michael Berkowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-20 05:34:51

W MySQL istnieją dwa rodzaje cudzysłowów:

  1. ' do zamykania literałów ciągów
  2. ` do załączania identyfikatorów, takich jak nazwy tabel i kolumn

I jest ", który jest szczególnym przypadkiem. Może być używany do jednego z wyżej wymienionych celów w zależności od serwera MySQL sql_mode:

  1. domyślnie znak " może być używany do zamykania literałów łańcuchowych, tak jak '
  2. W ANSI_QUOTES tryb znak " może być używany do załączania identyfikatorów tak jak `

Poniższe zapytanie spowoduje różne wyniki (lub błędy) w zależności od trybu SQL:

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

Ansi_quotes

Zapytanie wybierze ciąg znaków "column" gdzie kolumna {[11] } jest równa łańcuchowi "bar"

Ansi_quotes enabled

Zapytanie wybierze kolumnę column gdzie kolumna foo jest równa kolumnie bar

Kiedy używać czego

  • sugeruję, abyś unikał używania ", aby Twój kod stał się niezależny od trybów SQL
  • zawsze Cytuj identyfikatory, ponieważ jest to dobra praktyka (sporo pytań na ten temat)
 100
Author: Salman A,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-20 23:45:06

(istnieją dobre odpowiedzi powyżej dotyczące charakteru SQL twojego pytania, ale może to być również istotne, jeśli jesteś nowy w PHP.)

Być może warto wspomnieć, że PHP obsługuje pojedyncze i podwójne cytowane ciągi w różny sposób...

Pojedyncze cytowane ciągi są literałami i są w zasadzie ciągami WYSIWYG. Podwójnie cytowane łańcuchy są interpretowane przez PHP w celu ewentualnego podstawiania zmiennych (backticki w PHP nie są dokładnie łańcuchami; wykonują polecenie w powłoce i zwraca wynik).

Przykłady:

$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
Author: Chris Trahey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-26 11:13:10

Backticki są zwykle używane do wskazania identifier, a także do bezpiecznego przed przypadkowym użyciem zarezerwowanych słów kluczowych.

Na przykład:

Use `database`;

Tutaj backticki pomogą serwerowi zrozumieć, że database jest w rzeczywistości nazwą bazy danych, a nie identyfikatorem bazy danych.

To samo można zrobić dla nazw tabel i pól. Jest to bardzo dobry nawyk Jeśli owijasz swój identyfikator bazy danych z backticks.

Sprawdź TA odpowiedź, aby dowiedzieć się więcej o backticks.


Teraz o podwójnych cytatach i Pojedynczych cytatach (Michael już o tym wspomniał).

Ale, aby zdefiniować wartość, musisz użyć pojedynczego lub podwójnego cudzysłowu. Zobaczmy inny przykład.

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

Tutaj celowo zapomniałem zawinąć title1 cytatami. Teraz serwer przyjmie title1 jako nazwę kolumny (tj. identyfikator). Tak więc, aby wskazać, że jest to wartość, którą musisz użyć podwójnych lub pojedynczych cudzysłowów.

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

Teraz, w połączeniu z PHP, podwójne cytaty i pojedyncze cytaty znacznie ułatwiają pisanie zapytań. Zobaczmy zmodyfikowaną wersję zapytania w twoim pytaniu.

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

Teraz, używając podwójnych cudzysłowów w PHP, stworzysz zmienne $val1 i $val2, aby użyć ich wartości, tworząc w ten sposób doskonale poprawne zapytanie. Jak

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

Zrobi

INSERT INTO `table` (`id`, `col1`, `col2`) VALUES (NULL, 'my value 1', 'my value 2')
 19
Author: Starx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-20 22:04:05

Zasadniczo w Mysql są takie rodzaje identyfikatorów używane w zapytaniach ` ," ,' i ().

  1. " lub ' używać do zamykania łańcuchów takich jak wartości "26-01-2014 00:00:00" lub '26-01-2014 00:00:00'. Te identyfikatory używają tylko dla ciągu znaków, a nie funkcji agregującej, jak now() or sum ,max itd.

  2. ` służy do załączania tabeli lub kolumny tabeli np. select column_name from table_name where id='2'

  3. () są używane tylko dla tylko części zapytania np. select column_name from table_name where (id= ' 2 'and gender= 'male') or name= 'rakesh'.

 12
Author: Kumar Rakesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-27 19:31:23

Literały łańcuchów w MySQL i PHP są takie same.

Łańcuch jest sekwencją bajtów lub znaków, zamkniętych w jednym pojedyncze znaki cudzysłowu ( """ ) lub podwójne znaki cudzysłowu (""").

Więc jeśli twój łańcuch zawiera pojedyncze cudzysłowy, możesz użyć podwójnych cudzysłowów do zacytowania łańcucha, lub jeśli zawiera podwójne cudzysłowy, możesz użyć pojedynczych cudzysłowów do zacytowania łańcucha. Ale jeśli twój ciąg zawiera zarówno pojedyncze cudzysłowy, jak i podwójne cudzysłowy, musisz uciec od jednego to kiedyś cytowało ciąg znaków.

Najczęściej używamy pojedynczych cudzysłowów dla wartości ciągu SQL, więc musimy użyć podwójnych cudzysłowów Dla ciągu PHP.

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

I możesz użyć zmiennej w podwójnym cytowanym łańcuchu PHP:

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

Ale jeśli $val1 lub $val2 zawiera pojedyncze cudzysłowy, to Twój SQL będzie zły. Więc musisz uciec przed nim jest używany w sql; to jest to, co mysql_real_escape_string jest dla. (Chociaż przygotowane oświadczenie jest lepsze.)

 11
Author: xdazz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-26 11:26:05

W połączeniu z PHP i MySQL, podwójne cytaty i pojedyncze cytaty znacznie ułatwiają pisanie zapytań.

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

Załóżmy, że używasz zmiennej direct post do zapytania MySQL, użyj jej w ten sposób:

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

Jest to najlepsza praktyka używania zmiennych PHP do MySQL.

 10
Author: vipul sorathiya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-22 04:59:24

Jeśli table cols i values są zmiennymi, to są dwa sposoby:

Z podwójnymi cudzysłowami "" pełne zapytanie:

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

Lub

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

Z pojedynczymi cudzysłowami '':

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

Użyj tylnych wskazów ``, gdy nazwa kolumny/wartości jest podobna do słowa kluczowego zarezerwowanego przez MySQL.

Uwaga: Jeśli oznaczasz nazwę kolumny nazwą tabeli, użyj tylnych wskazań w następujący sposób:

`table_name`. `column_name` . from back ticks.

 9
Author: diEcho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-20 22:11:38

Było tu wiele pomocnych odpowiedzi, ogólnie rzecz biorąc, prowadzących do dwóch punktów.

  1. BACKTICKS ('`są używane wokół nazw identyfikatorów.
  2. pojedyncze cudzysłowy(') są używane wokół wartości.

I jak powiedział @ MichaelBerkowski

Backticki mają być używane do identyfikatorów tabeli i kolumny, ale są konieczne tylko wtedy, gdy identyfikator jest zarezerwowanym słowem kluczowym MySQL, lub gdy identyfikator zawiera białe znaki lub znaki beyond a ograniczony zestaw (patrz poniżej) często zaleca się unikać używanie zarezerwowanych słów kluczowych jako identyfikatorów kolumn lub tabeli, jeśli to możliwe, unikanie kwestii cytowania.

Istnieje jednak przypadek, w którym identyfikator nie może być zarezerwowanym słowem kluczowym lub zawierać białych znaków lub poza ograniczonym zestawem, ale koniecznie wymaga wokół nich backtików.

Przykład

123E10 jest poprawną nazwą identyfikatora, ale także poprawną INTEGER dosłownie.

[nie wdając się w szczegóły, w jaki sposób można uzyskać taką nazwę identyfikatora], Załóżmy, że chcę utworzyć tymczasową tabelę o nazwie 123456e6.

Brak błędów na backsticach.

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

Błąd, gdy nie używasz 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

Jednak 123451a6 jest idealnie dokładną nazwą identyfikatora (bez tylnych wskazań).

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

Jest to całkowicie dlatego, że 1234156e6 jest również liczbą wykładniczą.

 8
Author: MPJ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-07 07:11:28

Pojedyncze cudzysłowy powinny być używane do wartości łańcuchowych, jak w liście VALUES ().

Backticki są zwykle używane do wskazania identyfikatora, a także są bezpieczne przed przypadkowym użyciem zarezerwowanych słów kluczowych.

W połączeniu z PHP i MySQL, podwójne cytaty i pojedyncze cytaty znacznie ułatwiają pisanie zapytań.

 7
Author: john igneel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-26 12:27:13

Poza wszystkimi (dobrze wyjaśnionymi) odpowiedziami, nie wspomniano poniżej i często odwiedzam to pytanie.

W skrócie; MySQL myśli, że chcesz zrobić matematykę na własnej tabeli/kolumnie i interpretuje myślniki takie jak "e-mail" jako e minus mail.


Zastrzeżenie: więc pomyślałem, że dodam to jako odpowiedź typu "FYI" dla tych, którzy są zupełnie nowi w pracy z bazami danych i którzy mogą nie rozumieć terminów technicznych już opisane.

 2
Author: Funk Forty Niner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-18 22:10:23

Serwery SQL i MySQL, PostgreySQL, Oracle nie rozumieją podwójnych cudzysłowów("). Dlatego Twoje zapytanie powinno być wolne od cudzysłowów podwójnych(") i powinno używać tylko pojedynczych cudzysłowów (").

Back-trip(`) jest opcjonalny do użycia w SQL i jest używany do nazw tabel, nazw db i nazw kolumn.

Jeśli próbujesz napisać zapytanie w back-endzie, aby wywołać MySQL, możesz użyć podwójnego cudzysłowu(") lub pojedynczego cudzysłowu ( " ), aby przypisać zapytanie do zmiennej takiej jak:

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

Jeśli jest to where stwierdzenie w Twoim zapytanie i / lub próba insert wartości i / lub update wartości, która jest ciągiem, użyj pojedynczego cudzysłowu(') dla tych wartości, takich jak:

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.

Jeśli chcesz trzymać się z dala od tego zamieszania, kiedy używać podwójnych cudzysłowów ( " ) i pojedynczych cudzysłowów ('), zaleca się trzymanie się pojedynczych cudzysłowów (') będzie to zawierać odwrotny ukośnik () jak:

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

Problem z cudzysłowami podwójnymi(") lub pojedynczymi ( " ) pojawia się, gdy musieliśmy przypisać jakąś dynamikę wartości i wykonać konkatenację łańcuchową, jak:

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

W razie potrzeby więcej informacji można znaleźć w cudzysłowach w języku JavaScript

 0
Author: NAVIN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-22 06:47:23