Kapan menggunakan tanda kutip tunggal, tanda kutip ganda, dan backticks di MySQL

633

Saya mencoba mempelajari cara terbaik untuk menulis pertanyaan. Saya juga mengerti pentingnya konsisten. Sampai sekarang, saya secara acak menggunakan tanda kutip tunggal, tanda kutip ganda, dan backticks tanpa pemikiran nyata.

Contoh:

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

Juga, dalam contoh di atas, pertimbangkan bahwa table, col1, val1, dll mungkin variabel.

Apa standar untuk ini? Apa yang kamu kerjakan?

Saya sudah membaca jawaban untuk pertanyaan serupa di sini selama sekitar 20 menit, tetapi sepertinya tidak ada jawaban pasti untuk pertanyaan ini.

Nate
sumber
16
Perhatikan bahwa ini adalah pertanyaan khusus untuk MySQL. SQL secara umum (yaitu ISO / ANSI SQL) memiliki serangkaian tanda kutip yang berbeda: tanda kutip ganda untuk pengidentifikasi terbatas, misalnya "tablename", dan tanda kutip tunggal untuk literal, misalnya 'this is a some text'. Back-ticks tidak pernah digunakan dalam SQL standar. (Jika Anda perlu menyertakan tanda kutip ganda dalam pengenal, ketikkan dua kali sebagai "odd""tablename". Demikian pula, tanda kutip tunggal tunggal dalam literal, misalnya 'Conan O''Brien'.)
jarlh

Jawaban:

610

Backticks harus digunakan untuk pengidentifikasi tabel dan kolom, tetapi hanya diperlukan ketika pengidentifikasi adalah kata kunci yang disediakan oleh MySQL , atau ketika pengidentifikasi berisi karakter spasi putih atau karakter di luar rangkaian terbatas (lihat di bawah) Sering disarankan untuk menghindari menggunakan kata kunci yang dipesan. sebagai pengidentifikasi kolom atau tabel bila memungkinkan, hindari masalah penawaran.

Kutipan tunggal harus digunakan untuk nilai string seperti dalam VALUES()daftar. Kutipan ganda didukung oleh MySQL untuk nilai string juga, tetapi tanda kutip tunggal lebih banyak diterima oleh RDBMS lain, jadi itu kebiasaan yang baik untuk menggunakan tanda kutip tunggal, bukan ganda.

MySQL juga mengharapkan DATEdan DATETIMEnilai-nilai literal dikutip secara tunggal sebagai string seperti '2001-01-01 00:00:00'. Lihat dokumentasi Literal Tanggal dan Waktu untuk detail lebih lanjut, khususnya alternatif untuk menggunakan tanda hubung -sebagai pembatas segmen dalam string tanggal.

Jadi, dengan menggunakan contoh Anda, saya akan mengutip dua kali string PHP dan menggunakan tanda kutip tunggal pada nilai-nilai 'val1', 'val2'. NULLadalah kata kunci MySQL, dan nilai khusus (bukan), dan karenanya tidak dikutip.

Tak satu pun dari pengidentifikasi tabel atau kolom ini adalah kata-kata yang dicadangkan atau menggunakan karakter yang memerlukan penawaran, tetapi saya tetap mengutipnya dengan backticks (lebih lanjut tentang ini nanti ...).

Fungsi asli RDBMS (misalnya, NOW()dalam MySQL) tidak boleh dikutip, meskipun argumen mereka tunduk pada string yang sama atau aturan mengutip pengidentifikasi yang telah disebutkan.

Backtick (`)
tabel & kolom ──────┬─────┬──┬──┬──┬────┬──┬──────┬────┬──┬ ───────┐
                      ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
$ query = " INSERT INTO` table` (`id`,` col1`, `col2`,` date`, `updated`)
                       VALUES (NULL, 'val1', 'val2', '2001-01-01', NOW ()) ";
                               ↑↑↑↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑↑↑↑↑ 
Kata kunci tanpa tanda kutip ─────┴┴┴┘ │ │ │ │ │ │ │││││
Kutipan tunggal (') ───────────┴──────┴────┘ │ │ │││││
Dikutip tunggal (') DATE ────────────────────────────────────┘ ┘ │
Fungsi tanpa tanda kutip ──────────────────────────────────────┴┴┴┴┘    

Interpolasi variabel

Pola kutip untuk variabel tidak berubah, meskipun jika Anda bermaksud untuk menginterpolasi variabel secara langsung dalam string, itu harus dikutip dua kali dalam PHP. Pastikan Anda telah benar-benar lolos dari variabel untuk digunakan dalam SQL. ( Disarankan menggunakan API yang mendukung pernyataan yang disiapkan, sebagai perlindungan terhadap injeksi SQL ).

// Hal yang sama dengan beberapa penggantian variabel
// Di sini, nama tabel variabel $ tabel dikutip dengan backtick, dan variabel
// dalam daftar VALUES adalah tanda kutip tunggal 
$ query = "INSERT INTO` $ table` (`id`,` col1`, `col2`,` date`) VALUES (NULL, '$ val1' , '$ val2' , '$ val2' , '$ date' ) ";

Pernyataan yang disiapkan

Saat bekerja dengan pernyataan yang disiapkan, bacalah dokumentasi untuk menentukan apakah placeholder pernyataan harus dikutip atau tidak. API paling populer yang tersedia di PHP, PDO dan MySQLi, mengharapkan placeholder yang tidak dikutip, seperti halnya API pernyataan paling siap dalam bahasa lain:

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

Karakter yang memerlukan backtick mengutip dalam pengidentifikasi:

Menurut dokumentasi MySQL , Anda tidak perlu mengutip (backtick) pengidentifikasi menggunakan set karakter berikut:

ASCII: [0-9,a-z,A-Z$_](huruf Latin dasar, angka 0-9, dolar, garis bawah)

Anda dapat menggunakan karakter di luar yang ditetapkan sebagai pengidentifikasi tabel atau kolom, termasuk spasi putih misalnya, tetapi kemudian Anda harus mengutip (backtick) mereka.

Michael Berkowski
sumber
43
" tetapi tanda kutip tunggal lebih diterima secara luas oleh RDBMS lain " - menggunakan tanda kutip tunggal untuk string literal didefinisikan (dan diperlukan) oleh standar SQL
a_horse_with_no_name
@a_horse_with_no_name hampir tidak ada yang menggunakan ANSI MySQL ('|' untuk string concat - really?)
Good Person
3
ini tidak benar: "MySQL juga mengharapkan nilai literal DATE dan DATETIME dikutip satu sebagai string seperti '2001-01-01 00:00:00'"
Kick_the_BUCKET
3
@evilReiko Dokumen MySQL sepertinya tidak menyebutkan alias mengutip dengan jelas. Ini akan menerima single, double, atau backtick untuk alias tetapi itu mungkin dipengaruhi oleh mode SQL ANSI yang berbeda. Saya tidak yakin apa yang dituntut oleh spesifikasi SQL untuk tanda kutip - Preferensi pribadi: untuk konsistensi, saya mengutipnya sama dengan pengidentifikasi kolom - yaitu, saya memilih kembali jika diperlukan, atau membiarkannya tanpa tanda kutip jika tidak. Saya tidak menggunakan tanda kutip tunggal atau ganda pada alias.
Michael Berkowski
2
@GuneyOzsan Ya, sangat rentan. Jangan pernah menggunakan variabel untuk nama tabel kecuali jika itu telah divalidasi terhadap daftar nama tabel yang dapat diterima - buat array nama yang diizinkan dan periksa variabel yang cocok dengan sesuatu dalam daftar untuk membuatnya aman untuk digunakan. Kalau tidak, Anda tidak bisa keluar dengan aman dari variabel nama tabel untuk digunakan.
Michael Berkowski
121

Ada dua jenis kutipan di MySQL:

  1. ' untuk melampirkan string string
  2. ` untuk melampirkan pengidentifikasi seperti nama tabel dan kolom

Dan kemudian ada "kasus khusus. Ini dapat digunakan untuk salah satu tujuan yang disebutkan di atas pada suatu waktu tergantung pada server MySQL sql_mode:

  1. Secara default yang "karakter dapat digunakan untuk menyertakan string literal seperti'
  2. Dalam ANSI_QUOTESmode "karakter dapat digunakan untuk menyertakan pengidentifikasi seperti`

Kueri berikut akan menghasilkan hasil yang berbeda (atau kesalahan) tergantung pada mode SQL:

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

ANSI_QUOTES dinonaktifkan

Kueri akan memilih string literal di "column"mana kolom foosama dengan string"bar"

ANSI_QUOTES diaktifkan

Kueri akan memilih kolom di columnmana kolom foosama dengan kolombar

Kapan harus menggunakan apa

  • Saya menyarankan Anda menghindari menggunakan "sehingga kode Anda menjadi independen dari mode SQL
  • Selalu mengutip pengidentifikasi karena ini adalah praktik yang baik (beberapa pertanyaan di SO membahas hal ini)
Salman A
sumber
32

(Ada jawaban yang bagus di atas mengenai sifat SQL dari pertanyaan Anda, tetapi ini mungkin juga relevan jika Anda baru mengenal PHP.)

Mungkin penting untuk menyebutkan bahwa PHP menangani string kutipan tunggal dan ganda secara berbeda ...

String yang dikutip tunggal adalah 'literal' dan cukup banyak string WYSIWYG. String yang dikutip ganda diinterpretasikan oleh PHP untuk kemungkinan penggantian-variabel (backtick dalam PHP bukan string yang tepat; mereka mengeksekusi sebuah perintah di shell dan mengembalikan hasilnya).

Contoh:

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

Backticks umumnya digunakan untuk menunjukkan identifierdan juga aman dari kecelakaan menggunakan Kata Kunci Cadangan .

Sebagai contoh:

Use `database`;

Di sini backticks akan membantu server untuk memahami bahwa databasesebenarnya nama database, bukan pengenal database.

Hal yang sama dapat dilakukan untuk nama tabel dan nama bidang. Ini adalah kebiasaan yang sangat baik jika Anda membungkus pengenal basis data Anda dengan backticks.

Periksa jawaban ini untuk memahami lebih banyak tentang backticks.


Sekarang tentang Kutipan Ganda & Kutipan Tunggal (Michael sudah menyebutkan itu).

Tapi, untuk menentukan nilai, Anda harus menggunakan tanda kutip tunggal atau ganda. Mari kita lihat contoh lain.

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

Di sini saya sengaja lupa membungkusnya title1dengan tanda kutip. Sekarang server akan mengambil title1sebagai nama kolom (yaitu pengidentifikasi). Jadi, untuk menunjukkan bahwa itu adalah nilai, Anda harus menggunakan tanda kutip ganda atau tunggal.

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

Sekarang, dalam kombinasi dengan PHP, tanda kutip ganda dan tanda kutip tunggal membuat waktu penulisan kueri Anda jauh lebih mudah. Mari kita lihat versi kueri yang dimodifikasi dalam pertanyaan Anda.

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

Sekarang, menggunakan tanda kutip ganda dalam PHP, Anda akan membuat variabel $val1, dan $val2menggunakan nilainya sehingga menciptakan kueri yang benar-benar valid. Suka

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

akan membuat

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

Dalam MySQL, simbol ini digunakan untuk membatasi query `, ", 'dan ().

  1. "atau 'digunakan untuk melampirkan nilai-nilai seperti string "26-01-2014 00:00:00"atau '26-01-2014 00:00:00'. Simbol-simbol ini hanya untuk string, fungsi tidak agregat suka now, sumatau max.

  2. ` digunakan untuk melampirkan nama tabel atau kolom, misalnya select `column_name` from `table_name` where id='2'

  3. (dan )cukup lampirkan bagian dari permintaan misalnya select `column_name` from `table_name` where (id='2' and gender='male') or name='rakesh'.

Kumar Rakesh
sumber
13

Literal string dalam MySQL dan PHP adalah sama.

String adalah urutan byte atau karakter, yang dilingkupi dalam karakter tanda kutip tunggal ("'") atau tanda kutip ganda ("" ").

Jadi jika string Anda berisi tanda kutip tunggal, maka Anda bisa menggunakan tanda kutip ganda untuk mengutip string, atau jika itu berisi tanda kutip ganda, maka Anda bisa menggunakan tanda kutip tunggal untuk mengutip string. Tetapi jika string Anda berisi tanda kutip tunggal dan ganda, Anda harus menghindari tanda kutip yang digunakan untuk mengutip string.

Sebagian besar, kami menggunakan tanda kutip tunggal untuk nilai string SQL, jadi kami perlu menggunakan tanda kutip ganda untuk string PHP.

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

Dan Anda bisa menggunakan variabel dalam string PHP yang dikutip ganda:

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

Tetapi jika $val1atau $val2mengandung tanda kutip tunggal, itu akan membuat SQL Anda salah. Jadi, Anda perlu menghindarinya sebelum digunakan dalam sql; itu untuk apa mysql_real_escape_string. (Meskipun pernyataan yang disiapkan lebih baik.)

xdazz
sumber
12

Dalam kombinasi PHP dan MySQL, tanda kutip ganda dan tanda kutip tunggal membuat waktu penulisan kueri Anda jauh lebih mudah.

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

Sekarang, anggap Anda menggunakan variabel pos langsung ke dalam kueri MySQL, gunakan cara ini:

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

Ini adalah praktik terbaik untuk menggunakan variabel PHP ke dalam MySQL.

vipul sorathiya
sumber
Oleh karena itu, kutipan ganda bersifat fleksibel tetapi tidak dapat digunakan sebagai pengidentifikasi.
rhavendc
Harap tidak pernah secara langsung menggunakan input pengguna yang tidak terhapus dalam permintaan Anda!
jankal
@jankal Ini hanya contoh. Saya menetapkan bahwa jika Anda menggunakan input pengguna langsung maka n maka ...........
vipul sorathiya
@vipulsorathiya Silakan tentukan dalam jawaban Anda bahwa variabel POST harus diloloskan. Anda sekarang menunjuk untuk menggunakannya secara langsung dalam permintaan Anda. Buruk untuk pemula yang mencoba ini ...
RFLdev
12

Ada banyak jawaban yang bermanfaat di sini, umumnya memuncak menjadi dua poin.

  1. BACKTICKS (`) digunakan di sekitar nama pengidentifikasi.
  2. SINGLE QUOTES (') digunakan di sekitar nilai.

DAN seperti kata @MichaelBerkowski

Backticks harus digunakan untuk pengidentifikasi tabel dan kolom, tetapi hanya diperlukan ketika pengidentifikasi adalah MySQLkata kunci yang dipesan, atau ketika pengidentifikasi berisi karakter spasi putih atau karakter di luar rangkaian terbatas (lihat di bawah) Sering disarankan untuk menghindari menggunakan kata kunci yang dipesan sebagai pengidentifikasi kolom atau tabel bila memungkinkan, hindari masalah penawaran.

Meskipun demikian, ada kasus di mana pengidentifikasi tidak dapat menjadi kata kunci yang dicadangkan atau berisi spasi atau karakter di luar batas yang ditentukan, tetapi harus mengharuskan backtick di sekitarnya.

CONTOH

123E10adalah nama pengidentifikasi yang valid tetapi juga INTEGERliteral yang valid .

[Tanpa merinci bagaimana Anda akan mendapatkan nama pengenal seperti itu], Misalkan saya ingin membuat tabel sementara bernama 123456e6.

Tidak ada KESALAHAN pada backticks.

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

GALAT saat tidak menggunakan 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

Namun, 123451a6adalah nama pengenal yang sangat baik (tanpa kutu belakang).

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

Ini sepenuhnya karena 1234156e6juga merupakan angka eksponensial.

MJ007
sumber
10

Jika tabel cols dan nilai adalah variabel maka ada dua cara:

Dengan tanda kutip ganda ""kueri lengkap:

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

Atau

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

Dengan kutipan tunggal '':

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

Gunakan tanda centang kembali ``ketika nama kolom / nilai mirip dengan kata kunci yang dipesan MySQL.

Catatan: Jika Anda menunjukkan nama kolom dengan nama tabel maka gunakan kembali tanda centang seperti ini:

`table_name`. `column_name` <- Catatan: kecualikan . dari kutu belakang.

diEcho
sumber
8

Kutipan tunggal harus digunakan untuk nilai string seperti dalam daftar VALUES ().

Backticks umumnya digunakan untuk menunjukkan pengidentifikasi dan juga aman dari kecelakaan menggunakan kata kunci yang dipesan.

Dalam kombinasi PHP dan MySQL, tanda kutip ganda dan tanda kutip tunggal membuat waktu penulisan kueri Anda jauh lebih mudah.

john igneel
sumber
4

Di samping semua jawaban (yang dijelaskan dengan baik), belum ada yang disebutkan berikut ini dan saya sering mengunjungi T&J ini.

Pendeknya; MySQL berpikir Anda ingin melakukan matematika pada tabel / kolomnya sendiri dan menafsirkan tanda hubung seperti "e-mail" sebagai e minus mail .


Penafian: Jadi saya pikir saya akan menambahkan ini sebagai jenis jawaban "FYI" bagi mereka yang benar-benar baru bekerja dengan database dan yang mungkin belum memahami istilah teknis yang sudah dijelaskan.

Funk Forty Niner
sumber
1

SQL server dan MySQL, PostgreySQL, Oracle tidak memahami tanda kutip ganda ("). Dengan demikian permintaan Anda harus bebas dari tanda kutip ganda (") dan hanya menggunakan tanda kutip tunggal (').

Back-trip (`) adalah opsional untuk digunakan dalam SQL dan digunakan untuk nama tabel, nama db dan nama kolom.

Jika Anda mencoba untuk menulis kueri di back-end Anda untuk memanggil MySQL maka Anda dapat menggunakan penawaran ganda (") atau kutipan tunggal (') untuk menetapkan permintaan ke variabel seperti:

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

Jika ada wherepernyataan dalam kueri Anda dan / atau mencoba insertnilai dan / atau updatenilai yang menggunakan string kutip tunggal (') untuk nilai-nilai ini seperti:

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.

Jika Anda ingin tetap keluar dari kebingungan ini ketika menggunakan tanda kutip ganda (") dan tanda kutip tunggal ('), akan merekomendasikan untuk tetap dengan tanda kutip tunggal (') ini akan mencakup backslash () seperti:

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

Masalah dengan tanda kutip ganda (") atau tunggal (') muncul ketika kami harus menetapkan beberapa nilai dinamis dan melakukan beberapa rangkaian string seperti:

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

Jika perlu izin lebih lanjut ikuti kutipan dalam JavaScript

NAVIN
sumber