2010-02-14 16 views
7

Daha iyi anlamak istediğim davranışı sergileyen bir MySQL veritabanına sahibim. Neden bir INT alanına eklenmiş bir CHAR değeri arayabilirim? INT tipinde bir alanım var ama karakter değerlerini kaydedebiliyor gibi görünüyor, bu nasıl mümkün olabilir? Neden MySQL int alanına karakterler ekleyebilirsin?

Bir INT ve VARCHAR ile bir veritabanı oluşturarak sorunu izole edilmesi için çalışılmıştır. INT değerine "TEST1" ekledim, ancak hala ID dizesi değerini kullanarak satırı arayabiliyordum. Dizgiyi ID değerine ekledikten sonra uyarı,

ancak bu değeri hala araştırmıştım. Bunun neden mümkün olduğunu anlamak isterim.

mysql> CREATE TABLE test1(ID int, DATA varchar(255)); 
Query OK, 0 rows affected (0.18 sec) 

mysql> INSERT INTO test1(ID,DATA) VALUES('TEST1', 'TEST1'); 
Query OK, 1 row affected, 1 warning (0.00 sec) 

mysql> SELECT * FROM test1 WHERE ID = 'TEST1'; 
+------+-------+ 
| ID | DATA | 
+------+-------+ 
| 0 | TEST1 | 
+------+-------+ 
1 row in set, 1 warning (0.00 sec) 

seçtikten sonra uyarı

| Warning | 1366 | Incorrect integer value: 'TEST1' for column 'ID' at row 1 | 

ama sonuçları hala doğrudur.

Yukarıda SEÇ 0 sonuç bulmak beklenir, ama bu durum böyle değil, neden?

YANIT: Aşağıda Asaph cevabı cevap artık aşikar görünüyor Pekka yorumlarının yardımıyla

.

INSERT sırasında, MySQL bir INT alanına 0 değerini koyması için karakter değerini ekleyemedi. Bu nedenle SELECT sırasında aynı şey oldu. Bu nedenle, herhangi bir karakter değeri için ID = 0 üzerinde SELECT yapıyordum. arıyordu. Gerçekten arka uç

SELECT * FROM test1 WHERE ID = 0; 

olarak çalıştığı beri benim ilk seçme aynı sonucu verir

mysql> SELECT * FROM test1 WHERE ID = 'SOMETHING_OTHER_THAN_TEST1'; 
+------+-------+ 
| ID | DATA | 
+------+-------+ 
| 0 | TEST1 | 
+------+-------+ 
1 row in set, 1 warning (0.00 sec) 

.

Her durumda en iyi uygulama = sql_mode kullanılır 'STRICT_ALL_TABLES' MySQL yapılandırma dosyası veya SQL deyimindeki kendisi gibi görünüyor.

genellikle /etc/my.cnf

[mysqld] 
... 
... 
... 
sql-mode=STRICT_ALL_TABLES 
+1

Eğer sorgu yürütülürken MySQL '1 warning' yayınladı dikkat ettin .. Belki de ne olduğunu bilmek güzel ...? – Romain

+0

Soruyu uyarı sonuçlarını kullanarak güncelledim, ancak sonuç hala doğru, merak ettiğim şey bu. –

cevap

8
bulunur, my.cnf dosyasındaki [mysqld] başlığı altında aşağıdaki eklemeniz gerekir MySQL sunucusundaki tüm SQL sorguları için STRICT_ALL_TABLES etkinleştirmek için

sen my.cnf veya anında ayarlanabilir STRICT_ALL_TABLES modunu ayarlayarak ilk etapta girmesini engelleyecek şekilde anlamsız değerleri önleyebilir:

mysql> SET sql_mode = 'STRICT_ALL_TABLES'; 
Query OK, 0 rows affected (0.00 sec) 

mysql> CREATE TABLE test1(ID int, DATA varchar(255)); 
Query OK, 0 rows affected (0.42 sec) 

mysql> INSERT INTO test1(ID,DATA) VALUES('TEST1', 'TEST1'); 
ERROR 1264 (22003): Out of range value adjusted for column 'ID' at row 1 
mysql> SELECT * FROM test1 WHERE ID = 'TEST1'; 
Empty set (0.00 sec) 

mysql> SELECT * FROM test1; 
Empty set (0.00 sec) 
+1

Teşekkür ederim, bunu en iyi uygulama gibi görünen veritabanı yapılandırmamıza ekledim, ancak SELECT'in neden doğru sonuçları döndürdüğünü hala bilmek isterim. –

+1

+1: bunu bilmek harika :) – Sarfraz

+1

@Michael İlk dönüşümün (ID için) yanlış gittiğini ve varsayılan değerine geri döndüğünü varsayalım. –

İlgili konular