2010-02-20 11 views
15

Tôi muốn để có thể làm các truy vấn mà bình thường có dấu ký tự, do đó ví dụ:bình thường có dấu nhân vật trong MySQL truy vấn

é, è, and ê 

đều coi là 'e', ​​trong các truy vấn sử dụng '=' và thích'. Tôi có một hàng có trường tên người dùng được đặt thành 'rené' và tôi muốn có thể đối sánh trên đó với cả hai 'rene' và 'rené'.

Tôi đang cố thực hiện điều này với mệnh đề 'đối chiếu' trong MySQL 5.0.8. Tôi nhận được lỗi sau:

mysql> select * from User where username = 'rené' collate utf8_general_ci; 
ERROR 1253 (42000): COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'latin1' 

FWIW, bàn của tôi đã được tạo ra với:

CREATE TABLE `User` (
    `id` bigint(19) NOT NULL auto_increment, 
    `username` varchar(32) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `uniqueUsername` (`username`) 
) ENGINE=InnoDB AUTO_INCREMENT=56790 DEFAULT CHARSET=utf8 
+0

Điều gì sẽ xảy ra nếu bạn thay đổi ký tự bảng thành 'utf8'? – friedo

+0

friedo- không phải là những gì DEFAULT CHARSET = utf8 làm gì? (Tôi đã không thực sự tạo ra bảng này, tôi đảo ngược thiết kế nó thông qua 'hiển thị tạo bảng người dùng'). –

+0

Vâng, đó là những gì nó phải làm. Tôi không biết tại sao MySQL dường như nghĩ rằng các bảng xếp hạng là latin1 nếu bạn có nó thiết lập để utf8, mặc dù. – friedo

Trả lời

8

tôi đề nghị bạn nên lưu các phiên bản bình thường để bàn của bạn ngoài với tên người dùng thực sự. Việc thay đổi mã hóa khi đang chạy có thể tốn kém và bạn phải thực hiện chuyển đổi một lần nữa cho mỗi hàng trên mỗi tìm kiếm.

Nếu bạn đang sử dụng PHP, bạn có thể sử dụng iconv() để xử lý các chuyển đổi:

$username = 'rené'; 
$normalized = iconv('UTF-8', 'ASCII//TRANSLIT', $string); 

Sau đó, bạn sẽ chỉ cần lưu tất cả các phiên bản và sử dụng phiên bản bình thường để tìm kiếm và tên người dùng bình thường để trưng bày. So sánh và lựa chọn sẽ nhanh hơn rất nhiều từ cột bình thường, miễn là bạn bình thường hóa chuỗi tìm kiếm thêm:

$search = mysql_real_escape_string(iconv('UTF-8', 'ASCII//TRANSLIT', $_GET['search'])); 
mysql_query("SELECT * FROM User WHERE normalized LIKE '%".$search."%'"); 

Tất nhiên phương pháp này có thể không khả thi nếu bạn có nhiều cột cần normalizations, nhưng trong trường hợp cụ thể của bạn điều này có thể làm việc hoàn toàn.

+0

Hmm, tôi hơi ngại giữ dữ liệu ở nhiều nơi (DRY), trừ khi nó chứng tỏ là một nút cổ chai. Trong trường hợp này, nó sẽ liên quan đến 3 trường hiện có - tên người dùng, firstName và lastName (tôi đã đơn giản hóa cấu trúc bảng của tôi với mục đích đặt một câu hỏi đơn giản). –

+0

Tôi sử dụng PHP không hoạt động ... u cần thêm 1 dòng tiếp theo 'str_replace ("?", "%", $ Normalized); '.. thích! – KingRider

2
$normalized = iconv('UTF-8', 'ASCII//TRANSLIT', $string); 

là giải pháp php hoàn hảo, nhưng trong mysql? ĐỔI?

trong mysql

SELECT 'Álvaro José' as accented, (CONVERT ('Álvaro José' USING ascii)) as notaccented 

Sản xuất:

Álvaro José  ?lvaro Jos? 

Những lời có dấu không được chuyển thành không từ có dấu, nó không phải là tương đương với một translit của iconv.

RegExp không hoạt động với UTF-8.

Không có giải pháp nào.

+1

Đây không phải là câu trả lời mà là nhận xét có thông tin hữu ích –

5

tôi đã thực hiện một chức năng strtr php/tr lệnh unix trong MySQL bạn có thể lấy nguồn here

Bạn có thể sử dụng như:

SELECT tr(name, 'áäèëî', 'aaeei') FROM persons 

hoặc dải một số nhân vật

SELECT tr(name, 'áäèëî', null) FROM persons 
9

Lý do lỗi không phải là bảng nhưng ký tự của đầu vào của bạn, tức là 'rené' trong truy vấn của bạn.Các hành vi phụ thuộc vào character_set_connection biến:

The character set used for literals that do not have a character set introducer and for number-to-string conversion.

Sử dụng Client MySQL, thay đổi nó bằng cách sử SET NAMES:

A SET NAMES 'charset_name' statement is equivalent to these three statements:

SET character_set_client = charset_name; 
SET character_set_results = charset_name; 
SET character_set_connection = charset_name; 

(từ http://dev.mysql.com/doc/refman/5.5/en/charset-connection.html)

Ví dụ đầu ra:

mysql> set names latin1; 
Query OK, 0 rows affected (0.00 sec) 

mysql> select * from User where username = 'rené' collate utf8_general_ci; 
ERROR 1253 (42000): COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'latin1' 

mysql> set names utf8; 
Query OK, 0 rows affected (0.00 sec) 

mysql> select * from User where username = 'rené' collate utf8_general_ci; 
Empty set (0.00 sec) 

Altenatively, sử dụng một cách rõ ràng có thể thiết lập các bộ ký tự sử dụng một 'bộ ký tự người giới thiệu':

mysql> set names latin1; 
Query OK, 0 rows affected (0.00 sec) 

mysql> select * from User where username = _utf8'rené' collate utf8_general_ci; 
Empty set (0.00 sec) 

Tôi biết câu hỏi này là khá cũ nhưng kể từ khi Google đưa tôi vào đây để một câu hỏi liên quan, tôi mặc dù nó vẫn xứng đáng câu trả lời :)