Sự kết hợp bất hợp pháp của các đối chiếu Lỗi MySQL


124

Tôi gặp lỗi lạ này khi đang xử lý một số lượng lớn dữ liệu ...

Error Number: 1267

Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '='

SELECT COUNT(*) as num from keywords WHERE campaignId='12' AND LCASE(keyword)='hello again 昔 ã‹ã‚‰ ã‚ã‚‹ å ´æ‰€'

Tôi có thể làm gì để giải quyết vấn đề này? Tôi có thể thoát chuỗi bằng cách nào đó để không xảy ra lỗi này không hoặc tôi có cần phải thay đổi mã hóa bảng của mình bằng cách nào đó không, và nếu vậy, tôi nên thay đổi nó thành gì?


lỗi này, nó là một tiêm hay không?
hamza irizaj

1
Điều này có trả lời câu hỏi của bạn không? Lỗi kết hợp bất hợp pháp của lỗi đối chiếu trong MySql
Farhan

Câu trả lời:


288
SET collation_connection = 'utf8_general_ci';

sau đó cho cơ sở dữ liệu của bạn

ALTER DATABASE your_database_name CHARACTER SET utf8 COLLATE utf8_general_ci;

ALTER TABLE your_table_name CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

MySQL đôi khi lén lút xâm nhập vào đó mà không có lý do hợp lý.


3
@Ben: Cảm ơn bạn vì một giải pháp có thể sao chép trực tiếp. Đã tiết kiệm cho tôi rất nhiều thời gian.
Pistos

15
@Ben: Ban đầu nó được phát triển bởi một công ty Thụy Điển ... Đó là lý do đằng sau các thiết lập ban đầu latin1_swedish_ci gây phiền nhiễu .. :(
Vajk Hermecz

1
Tôi không có quyền làm báo cáo kết quả đầu tiên nhưng nó chỉ làm việc làm bàn
Rob Sedgwick

Yêu bạn vì điều này! : P
prateekkathal

Có vẻ như cách này hoạt động với nhiều người, nhưng rất tiếc là tôi vẫn gặp sự cố này ngay cả khi đã thử tất cả thiết bị trong chủ đề này. Đối chiếu mặc định trong cơ sở dữ liệu của tôi kiên quyết từ chối thay đổi từ 'ucs2_bin' vì vậy ngay cả khi đã thử thay đổi tất cả các bảng và đối chiếu kết nối thành 'usc2_bin' nhưng tôi vẫn gặp lỗi "Lỗi SQL (1267): Kết hợp bất hợp pháp các đối chiếu (utf8_general_ci, IMPLICIT) và (ucs2_bin, IMPLICIT) cho hoạt động '=' ".
bikeman868

15

Bạn nên đặt cả mã hóa bảng và mã hóa kết nối thành UTF-8:

ALTER TABLE keywords CHARACTER SET UTF8; -- run once

SET NAMES 'UTF8';
SET CHARACTER SET 'UTF8';

Cả hai điều này có cần thiết không, hay tôi có thể chỉ làm một trong số chúng?
Nhấp vào Ủng hộ

ALTER myDbDEFAULT CHARACTER SET utf8 COLLATE utf8_bin. Liệu điều đó có hiệu quả? Này được thực hiện vì vậy nó sẽ ảnh hưởng đến tất cả các bảng của tôi, không chỉ là một trong số họ
Click Upvote

1
ALTER DATABASE sẽ không thay đổi cài đặt bảng hiện tại của bạn, chỉ những cài đặt mới được tạo. Mặc dù vậy, việc thay đổi bộ ký tự mặc định cho cơ sở dữ liệu cũng không ảnh hưởng gì.
Quassnoi

SET NAMES và SET CHARACTER SET sẽ thay đổi mã hóa kết nối của bạn. Bạn cần đưa ra các lệnh này mỗi khi kết nối. Thư viện máy khách của bạn có thể hỗ trợ phương thức thanh lịch hơn để làm điều đó (php :: mysqli thì có, php :: mysql thì không).
Quassnoi

Có vẻ như bây giờ đã hoạt động, tôi sẽ chấp nhận sau một số thử nghiệm nữa. Các truy vấn thứ hai cần được chạy một lần hay ở đầu mỗi tập lệnh?
Nhấp vào ủng hộ

13
CONVERT(column1 USING utf8)

Giải quyết vấn đề của tôi. Trong đó column1 là cột gây ra lỗi này cho tôi.


Đối với tôi, điều này đã hoạt động: CONVERT ("column1" SỬ DỤNG LATIN1)
shasi kanth

4

Sử dụng câu lệnh sau nếu bị lỗi

hãy cẩn thận về việc sao lưu dữ liệu của bạn nếu dữ liệu có trong bảng.

 ALTER TABLE your_table_name CHUYỂN ĐỔI THÀNH NHÂN VẬT ĐẶT utf8 COLLATE utf8_general_ci;

2

Nói chung, cách tốt nhất là Thay đổi đối chiếu bảng. Tuy nhiên, tôi có một ứng dụng cũ và không thực sự có thể ước tính kết quả liệu điều này có tác dụng phụ hay không. Do đó, tôi đã cố gắng bằng cách nào đó để chuyển đổi chuỗi thành một số định dạng khác để giải quyết vấn đề đối chiếu. Những gì tôi thấy hoạt động là thực hiện so sánh chuỗi bằng cách chuyển đổi các chuỗi thành một biểu diễn thập lục phân của các ký tự của nó. Trên cơ sở dữ liệu, điều này được thực hiện vớiHEX(column). Đối với PHP, bạn có thể sử dụng chức năng này:

public static function strToHex($string)
{
    $hex = '';
    for ($i=0; $i<strlen($string); $i++){
        $ord = ord($string[$i]);
        $hexCode = dechex($ord);
        $hex .= substr('0'.$hexCode, -2);
    }
    return strToUpper($hex);
}

Khi thực hiện truy vấn cơ sở dữ liệu, chuỗi UTF8 ban đầu của bạn phải được chuyển đổi đầu tiên thành một chuỗi iso (ví dụ: sử dụng utf8_decode()trong PHP) trước khi sử dụng nó trong DB. Do kiểu đối chiếu, cơ sở dữ liệu không thể có các ký tự UTF8 bên trong nên sự kiện so sánh sẽ hoạt động mặc dù điều này thay đổi chuỗi ban đầu (chuyển đổi các ký tự UTF8 không tồn tại thêm vào trong bộ ký tự ISO dẫn đến kết quả là? Hoặc chúng bị loại bỏ hoàn toàn). Chỉ cần đảm bảo rằng khi bạn ghi dữ liệu vào cơ sở dữ liệu, bạn sử dụng cùng một chuyển đổi UTF8 sang ISO.


2

Tôi đã tạo bảng của mình ban đầu bằng CHARSET = latin1 . Sau khi chuyển đổi bảng thành utf8, một số cột không được chuyển đổi, tuy nhiên điều đó không thực sự rõ ràng. Bạn có thể thử chạy SHOW CREATE TABLE my_table;và xem cột nào chưa được chuyển đổi hoặc chỉ sửa bộ ký tự không chính xác trên cột có vấn đề với truy vấn bên dưới (thay đổi độ dài varchar và CHARSET và COLLATE theo nhu cầu của bạn):

 ALTER TABLE `my_table` CHANGE `my_column` `my_column` VARCHAR(10) CHARSET utf8 
 COLLATE utf8_general_ci NULL;

2

Thay đổi bộ ký tự của bảng thành utf8

ALTER TABLE your_table_name CHUYỂN ĐỔI THÀNH NHÂN VẬT ĐẶT utf8


0

Sau khi thực hiện các chỉnh sửa được liệt kê trong câu trả lời trên cùng, hãy thay đổi cài đặt mặc định của máy chủ của bạn.

Trong " /etc/my.cnf.d/server.cnf " của bạn hoặc nơi nó được đặt, hãy thêm các giá trị mặc định vào phần [mysqld] để nó trông giống như sau:

[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci

Nguồn: https://dev.mysql.com/doc/refman/5.7/en/charset-application.html


0

Tôi thấy rằng sử dụng cast()là giải pháp tốt nhất cho tôi:

cast(Format(amount, "Standard") AS CHAR CHARACTER SET utf8) AS Amount

Ngoài ra còn có một convert()chức năng. Thêm chi tiết về nó ở đây

Một nguồn khác ở đây


0

Tài khoản người dùng của tôi không có quyền thay đổi cơ sở dữ liệu và bảng, như được đề xuất trong giải pháp này .

Nếu, giống như tôi, bạn không quan tâm đến việc đối chiếu ký tự (bạn đang sử dụng toán tử '='), bạn có thể áp dụng sửa chữa ngược lại. Chạy điều này trước khi CHỌN của bạn:

SET collation_connection = 'latin1_swedish_ci';
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.