MySQL'de tek tırnak, çift tırnak ve ters tırnak ne zaman kullanılır?


633

Sorgu yazmanın en iyi yolunu öğrenmeye çalışıyorum. Ayrıca tutarlı olmanın önemini de anlıyorum. Şimdiye kadar, herhangi bir gerçek düşünce olmadan rastgele tek tırnak, çift tırnak ve ters tırnak kullandım.

Misal:

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

Aynı zamanda, yukarıdaki örnekte, düşünün table, col1, val1vb değişkenler olabilir.

Bunun için standart nedir? Ne yaparsın?

Yaklaşık 20 dakikadır burada benzer soruların cevaplarını okuyorum, ancak bu sorunun kesin bir cevabı yok gibi görünüyor.


16
Bunun çok MySQL'e özgü bir soru olduğunu unutmayın. SQL genel olarak (örn. ISO / ANSI SQL) farklı bir tırnak setine sahiptir: çift tırnaklar sınırlandırılmış tanımlayıcılar içindir, örneğin "tablename"tek tırnaklar değişmez değerler içindir 'this is a some text'. Geri keneler hiçbir zaman standart SQL'de kullanılmaz. (Bir tanımlayıcıya çift tırnak eklemeniz gerekiyorsa, bunu iki kez olarak yazın "odd""tablename". Benzer şekilde, değişmez değerlerde çift tek tırnak işareti gibi 'Conan O''Brien'.)
jarlh

Yanıtlar:


610

Backticks tablo ve sütun tanımlayıcıları için kullanılmalıdır, ancak yalnızca tanımlayıcı MySQL ayrılmış bir anahtar kelime olduğunda veya tanımlayıcı, sınırlı bir kümenin ötesinde boşluk karakterleri veya karakterler içerdiğinde gereklidir (aşağıya bakın) Ayrılmış anahtar kelimeler kullanmaktan kaçınılması önerilir tırnak işaretinden kaçınarak mümkün olduğunda sütun veya tablo tanımlayıcıları olarak.

VALUES()Listedeki gibi dize değerleri için tek tırnak kullanılmalıdır . Çift tırnaklar da dize değerleri için MySQL tarafından desteklenir, ancak tek tırnaklar diğer RDBMS tarafından daha yaygın olarak kabul edilir, bu nedenle çift yerine tek tırnak kullanmak iyi bir alışkanlıktır.

MySQL ayrıca değişmez değerler DATEve DATETIMEdeğişmez değerlerin dize gibi tek tırnak içine alınmasını bekler '2001-01-01 00:00:00'. Consult Tarih ve Zaman Değişmez tire kullanarak özellikle alternatiflerde daha fazla ayrıntı için dokümantasyon, -tarih dizeleri bir segmenti ayırıcı olarak.

Yani örneğinizi kullanarak, ben PHP dize çift tırnak ve değerleri tek tırnak kullanırsınız 'val1', 'val2'. NULLbir MySQL anahtar kelimesi ve özel (non) bir değerdir ve bu nedenle alıntı yapılmamıştır.

Bu tablo veya sütun tanımlayıcılarının hiçbiri ayrılmış sözcük değildir veya tırnak işareti gerektiren karakterleri kullanmaz, ancak yine de bunları ters tırnaklarla alıntıladım (daha sonra bu konuda ...).

RDBMS'ye özgü işlevler (örneğin, NOW()MySQL'de), bağımsız değişkenleri daha önce belirtilenle aynı dizeye veya tanımlayıcı alıntı kurallarına tabi olmasına rağmen alıntı yapılmamalıdır.

Backtick (`)
tablo ve sütun ───────┬─────┬──┬──┬──┬────┬──┬────┬──┬────┬──┬ ───────┐
                      ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
$ query = " Tabloya GİRİN" (`id`,` col1`, "col2`," tarih`, "güncellendi`)
                       DEĞERLER (NULL, 'val1', 'val2', '2001-01-01', ŞİMDİ ()) ";
                               ↑↑↑↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑↑↑↑↑ 
Alıntı yapılmayan anahtar kelime ─────┴┴┴┘ │ │ │ │ │ │ │││││
Tek tırnaklı (') dizeler ───────────┴────┴──┴────┘ │ │ │││││
Tek tırnaklı (') DATE ───────────────────────────┴──────────┘ ││││ │
Belirtilmemiş işlev ─────────────────────────────────────────┴┴┴┴┘    

Değişken enterpolasyon

Değişkenler için tırnak kalıpları değişmez, ancak değişkenleri doğrudan bir dizede enterpole etmek istiyorsanız, PHP'de çift tırnak içine alınmalıdır. SQL'de kullanmak için değişkenlerden düzgün bir şekilde kaçtığınızdan emin olun. ( Bunun yerine SQL enjeksiyonuna karşı koruma olarak hazırlanan ifadeleri destekleyen bir API kullanılması önerilir ).

// Bazı değişken değişimlerle aynı şey
// Burada, değişken tablosu adı $ tablosu ters tırnak işaretli ve değişkenler
// DEĞERLER listesindeki tek tırnak 
$ query = " $ table` (IN id`, `col1`,` col2`, `date`) VALUES (NULL, '$ val1' , '$ val2' , '$ date' )";

Hazırlanan ifadeler

Hazırlanan ifadelerle çalışırken, ifadenin yer tutucularının alıntılanması gerekip gerekmediğini belirlemek için belgelere bakın. PHP, PDO ve MySQLi'de mevcut olan en popüler API'ler, diğer dillerde hazırlanan en hazır deyim API'leri gibi alıntılanmamış yer tutucular bekler :

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

Tanımlayıcılarda backtick tırnak işareti gerektiren karakterler:

MySQL belgelerine göre , aşağıdaki karakter kümesini kullanarak tanımlayıcıları alıntılamanıza (backtick) gerek yoktur:

ASCII: [0-9,a-z,A-Z$_](temel Latin harfleri, 0-9 arası rakamlar, dolar, alt çizgi)

Örneğin boşluklar dahil tablo veya sütun tanımlayıcıları, ayarlarındakinden ötesinde karakterleri kullanabilirsiniz, ancak o zaman gerekir (backtick) onlardan alıntı.


43
" ancak tek tırnak diğer RDBMS tarafından daha yaygın olarak kabul edilir " - dize değişmez değerleri için tek tırnak kullanmak SQL standardı tarafından tanımlanır (ve gereklidir)
a_horse_with_no_name

@a_horse_with_no_name neredeyse hiç kimse ANSI MySQL kullanmıyor (string concat için '|' - gerçekten?)
İyi Kişi

3
bu doğru değil: "MySQL ayrıca DATE ve DATETIME değişmez değerlerinin '2001-01-01 00:00:00' gibi dizeler olarak tek tırnak içinde olmasını bekliyor
Kick_the_BUCKET

3
@evilReiko MySQL dokümanları takma adın açıkça belirtildiği anlamına gelmiyor. Takma adlar için tek, çift veya ters tıklamayı kabul eder, ancak bu farklı ANSI SQL modlarından etkilenebilir. SQL spec diğer adı tırnaklar için ne gerektirir emin değilim - Kişisel tercih: tutarlılık için ben onları sütun tanımlayıcıları ile aynı teklif - yani, ben ya onları gerekirse backtick, ya da değilse tırnaksız bırakın. Takma adlarda tek veya çift tırnak işareti kullanmıyorum.
Michael Berkowski

2
@GuneyOzsan Evet, çok savunmasız. Kabul edilebilir tablo adları listesiyle doğrulanmadıysa hiçbir zaman tablo adı için bir değişken kullanmayın - izin verilen adlar dizisi oluşturun ve değişkenin listedeki bir şeyle eşleştiğini kontrol ederek güvenli olmasını sağlayın. Aksi takdirde, bir tablo adı değişkeninden kullanım için güvenli bir şekilde kaçamazsınız.
Michael Berkowski

121

MySQL'de iki tür tırnak vardır:

  1. ' dizgi değişmezlerini kapatmak için
  2. ` tablo ve sütun adları gibi tanımlayıcıları içine almak için

Ve sonra "özel bir durum var. MySQL sunucusuna bağlı olarak bir kerede yukarıda belirtilen amaçlardan biri için kullanılabilir sql_mode:

  1. Varsayılan olarak "karakter, tıpkı dize değişmezlerini içine almak için kullanılabilir'
  2. In ANSI_QUOTESmodunda "karakter gibi tanımlayıcıları çevrelemek için kullanılabilir`

Aşağıdaki sorgu SQL moduna bağlı olarak farklı sonuçlar (veya hatalar) üretir:

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

ANSI_QUOTES devre dışı

Sorgu, "column"sütunun foodizeye eşit olduğu dizgi değişmezini seçer"bar"

ANSI_QUOTES etkin

Sorgu, sütunun columnsütuna fooeşit olduğu sütunu seçerbar

Ne zaman kullanılır

  • "Kodunuzun SQL modlarından bağımsız olması için kullanmaktan kaçınmanızı öneririm
  • Her zaman tanımlayıcıları alıntılayın çünkü iyi bir uygulamadır (SO hakkında oldukça birkaç soru bunu tartışır)

32

(Sorunuzun SQL niteliğiyle ilgili yukarıda iyi yanıtlar vardır, ancak PHP'de yeniyseniz de bu geçerli olabilir.)

Belki PHP'nin tek ve çift tırnaklı dizgileri farklı şekilde ele aldığından bahsetmek önemlidir ...

Tek tırnaklı dizeler 'değişmez' ve hemen hemen WYSIWYG dizeleridir. Çift tırnaklı dizeler, olası değişken ikamesi için PHP tarafından yorumlanır (PHP'deki backticks tam olarak dizgi değildir; kabukta bir komut yürütür ve sonucu döndürür).

Örnekler:

$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 genellikle , Ayrılmış Anahtar Kelimeler'i belirtmek identifierve yanlışlıkla kullanmaktan güvenli olmak için kullanılır .

Örneğin:

Use `database`;

Burada backticks sunucunun databaseaslında veritabanı tanımlayıcısı değil, veritabanı adı olduğunu anlamasına yardımcı olacaktır .

Tablo adları ve alan adları için de aynı şey yapılabilir. Veritabanı tanımlayıcınızı geri tıklamayla sarmanız çok iyi bir alışkanlıktır .

Geri tepmeler hakkında daha fazla bilgi edinmek için bu cevabı kontrol edin .


Şimdi çift tırnak ve tek tırnak hakkında (Michael zaten bahsetti).

Ancak, bir değer tanımlamak için tek veya çift tırnak kullanmanız gerekir. Bir başka örneğe bakalım.

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

Burada kasten title1alıntılarla sarmayı unuttum . Şimdi sunucu title1bir sütun adı (yani bir tanımlayıcı) olarak alacaktır . Bu nedenle, bunun bir değer olduğunu belirtmek için çift veya tek tırnak kullanmanız gerekir.

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

Şimdi, PHP ile birlikte, çift tırnak ve tek tırnak sorgu yazma zamanınızı çok daha kolay hale getirir. Sorunuzda sorgunun değiştirilmiş bir sürümünü görelim.

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

Şimdi, PHP çift tırnak kullanarak, değişkenler yapacak $val1ve $val2onların değerlerini kullanmak böylece mükemmel geçerli bir sorgu oluşturmak. Sevmek

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

yapacak

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

15

MySQL, bu semboller bir sorgu sınırlamak için kullanılır `, ", 've ().

  1. "veya 'dize benzeri değerleri içine almak için kullanılır "26-01-2014 00:00:00"veya '26-01-2014 00:00:00'. Bu semboller toplama yapmayan fonksiyonları gibi, sadece dizeleri içindir now, sumya da max.

  2. ` tablo veya sütun adlarını içine almak için kullanılır, ör. select `column_name` from `table_name` where id='2'

  3. ( ve ) yalnızca bir sorgunun bölümlerini içine alın, ör select `column_name` from `table_name` where (id='2' and gender='male') or name='rakesh'.


13

MySQL ve PHP'deki dize değişmezleri aynıdır.

Dize, tek tırnak ("'") veya çift tırnak ("" ") karakterleri içine alınmış bir bayt veya karakter dizisidir.

Bu nedenle, dizeniz tek tırnak içeriyorsa, dizeyi tırnak içine almak için çift tırnak kullanabilirsiniz veya çift tırnak işareti içeriyorsa, dizeyi tırnak içine almak için tek tırnak kullanabilirsiniz. Ancak dizeniz hem tek tırnak hem de çift tırnak içeriyorsa, dizeyi alıntılamak için kullanılan tırnaktan kaçmanız gerekir.

Çoğunlukla, bir SQL dizesi değeri için tek tırnak kullanırız, bu yüzden bir PHP dizesi için çift tırnak kullanmamız gerekir.

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

PHP'nin çift tırnaklı dizesinde bir değişken kullanabilirsiniz:

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

Ancak $val1veya $val2tek tırnak varsa , SQL yanlış yapacak. Yani sql kullanılmadan önce kaçmak gerekir; bunun mysql_real_escape_stringiçin var. (Hazırlanmış bir ifade daha iyi olmasına rağmen.)


12

PHP ve MySQL'in birleşimiyle çift tırnak ve tek tırnak, sorgu yazma zamanınızı çok daha kolay hale getirir.

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

Şimdi, MySQL sorgusuna doğrudan bir yazı değişkeni kullandığınızı varsayalım, bu şekilde kullanın:

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

PHP değişkenlerini MySQL'de kullanmak için en iyi yöntem budur.


Bu nedenle, çift tırnaklar esnektir ancak tanımlayıcı olarak kullanılamaz.
rhavendc

Lütfen asla sorgunuzda doğrudan çıkış karakterini kullanmayın!
jankal

@jankal Sadece bir örnek.Doğrudan kullanıcı girişi kullanıyorsanız n sonra ...........
vipul sorathiya

@vipulsorathiya Lütfen yanıtınızda POST değişkenlerinin kaçması gerektiğini belirtin. Şimdi bunları doğrudan sorgunuzda kullanmayı işaret ediyorsunuz. Bunu
deneyen

12

Burada genellikle iki noktaya ulaşan pek çok yardımcı cevap vardı.

  1. BACKTICKS (`) tanımlayıcı adlarının çevresinde kullanılır.
  2. Değerlerin etrafında TEKLİ TEKLİFLER (') kullanılır.

AND @MichaelBerkowski'nin dediği gibi

Tablo ve sütun tanımlayıcıları için ters tırnaklar kullanılmalıdır, ancak yalnızca tanımlayıcı MySQLayrılmış bir anahtar kelime olduğunda veya tanımlayıcı, sınırlı bir kümenin ötesinde boşluk karakterleri veya karakterler içerdiğinde gereklidir (aşağıya bakın) Ayrılmış anahtar kelimelerin Sütun veya tablo tanımlayıcıları, mümkün olduğunda alıntı sorununu önler.

Bir tanımlayıcının ayrılmış bir anahtar kelime olamayacağı veya sınırlı kümenin ötesinde boşluk veya karakter içerebileceği, ancak mutlaka bunların etrafında geri tıklama gerektirdiği bir durum vardır.

MİSAL

123E10 geçerli bir tanımlayıcı adı, aynı zamanda geçerli bir INTEGER değişmez .

[Böyle bir tanımlayıcı adını nasıl alacağınız ayrıntısına girmeden], varsayalım adında geçici bir tablo oluşturmak istiyorum 123456e6.

Ters çentiklerde HATA yok.

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

İğne kullanmıyorken HATA.

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

Bununla birlikte, 123451a6mükemmel bir tanımlayıcı adıdır (arka keneler olmadan).

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

Bunun nedeni tamamen 1234156e6üstel bir sayı olmasıdır.


10

Tablo sütunları ve değerleri değişkense, iki yol vardır:

Çift tırnak işareti ""ile tam sorgu:

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

Veya

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

Tek tırnak işaretleri ile '':

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

Geri keneleri kullan ``Bir sütun / değer adı MySQL ayrılmış bir anahtar kelimeye benziyorsa .

Not: Tablo adı olan bir sütun adını belirtiyorsanız, aşağıdaki gibi keneler kullanın:

`table_name`. `column_name` <- Not: . arka kenelerden hariç tutunuz.


8

VALUES () listesindeki gibi dize değerleri için tek tırnak kullanılmalıdır.

Geri tıklamalar genellikle bir tanımlayıcıyı belirtmek için kullanılır ve ayrıca ayrılmış anahtar kelimeleri yanlışlıkla kullanmaktan da güvende olur.

PHP ve MySQL'in birleşimiyle çift tırnak ve tek tırnak, sorgu yazma zamanınızı çok daha kolay hale getirir.


4

Tüm (iyi açıklanmış) cevapların yanı sıra, aşağıda belirtilenler de yoktur ve bu soru ve cevapları oldukça sık ziyaret ediyorum.

Kısaca; MySQL kendi tablosunda / sütununda matematik yapmak istediğinizi düşünür ve "e-posta" gibi e tireleri eksi olarak yorumlar mail .


Feragatname: Bu yüzden bunu veritabanları ile çalışmaya tamamen yeni olan ve daha önce tarif edilen teknik terimleri anlayamayanlar için "FYI" tipi bir cevap olarak ekleyeceğimi düşündüm.


1

SQL sunucuları ve MySQL, PostgreySQL, Oracle çift tırnak (") anlamıyor. Bu nedenle sorgunuz çift tırnak (") içermemeli ve sadece tek tırnak (') kullanmalıdır.

Back-trip (`), SQL'de isteğe bağlıdır ve tablo adı, db adı ve sütun adları için kullanılır.

MySQL'i aramak için arka uçta sorgu yazmaya çalışıyorsanız, aşağıdaki gibi bir değişkene sorgu atamak için çift tırnak işareti (") veya tek tırnak işareti (') kullanabilirsiniz:

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

whereSorgunuzda bir ifade varsa insertve / veya updatedize olan bir değere ve / veya değere çalışmaya çalışıyorsa , aşağıdaki değerler için tek tırnak (') kullanın:

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.

Çift tırnak işareti (") ve tek tırnak işareti (') kullanıldığında bu karışıklıktan uzak durmak istiyorsanız, tek tırnak işareti (') ile yapışmasını öneririz.

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

Double (") veya single (') tırnak işaretleri ile ilgili bir sorun, dinamik bir değer atamamız ve şöyle dize birleştirmesi yapmamız gerektiğinde ortaya çıkar:

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

Daha fazla açıklığa ihtiyacınız varsa JavaScript'teki alıntıları takip edin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.