Khắc phục sự cố Kết hợp bất hợp pháp của lỗi collations Lỗi trong mysql


210

Đang nhận được lỗi dưới đây khi cố gắng thực hiện lựa chọn thông qua một thủ tục được lưu trữ trong MySQL.

Kết hợp bất hợp pháp các collations (latin1_general_cs, IMPLICIT) và (latin1_general_ci, IMPLICIT) cho hoạt động '='

Bất cứ ý tưởng về những gì có thể đi sai ở đây?

Đối chiếu của bảng là latin1_general_civà của cột trong mệnh đề where latin1_general_cs.


2
Tôi đã sử dụng nhiều loại cơ sở dữ liệu trong một khoảng thời gian lớn (kể từ năm 1990) và việc sử dụng tính đối chiếu anìd do NyQuery tạo ra là "điên rồ", cơ sở dữ liệu giải quyết các vấn đề áp đặt bộ ký tự "ONE" cho cơ sở dữ liệu, sau đó các thủ tục nhập / xuất để chuyển đổi từ / sang bộ ký tự duy nhất được sử dụng bởi cơ sở dữ liệu. Các giải pháp lựa chọn Mysql là một giải pháp gây gián đoạn, bởi vì trộn lẫn "các vấn đề ứng dụng" (chuyển đổi bộ ký tự) với vấn đề cơ sở dữ liệu (sử dụng đối chiếu). Tại sao không "loại bỏ" các tính năng ngớ ngẩn và cồng kềnh đó khỏi cơ sở dữ liệu để nó trở nên hữu dụng và dễ kiểm soát hơn bởi một
Maurizio Pievaioli

Câu trả lời:


216

Điều này thường được gây ra bằng cách so sánh hai chuỗi đối chiếu không tương thích hoặc bằng cách cố gắng chọn dữ liệu đối chiếu khác nhau vào một cột kết hợp.

Mệnh đề COLLATEcho phép bạn chỉ định đối chiếu được sử dụng trong truy vấn.

Ví dụ: WHEREmệnh đề sau sẽ luôn đưa ra lỗi bạn đã đăng:

WHERE 'A' COLLATE latin1_general_ci = 'A' COLLATE latin1_general_cs

Giải pháp của bạn là chỉ định đối chiếu được chia sẻ cho hai cột trong truy vấn. Dưới đây là một ví dụ sử dụng COLLATEmệnh đề:

SELECT * FROM table ORDER BY key COLLATE latin1_general_ci;

Một tùy chọn khác là sử dụng BINARYtoán tử:

BIN BIN là cách viết tắt của CAST (str AS BINary).

Giải pháp của bạn có thể trông giống như thế này:

SELECT * FROM table WHERE BINARY a = BINARY b;

hoặc là,

SELECT * FROM table ORDER BY BINARY a;

2
Cảm ơn. Trên thực tế, nó có vẻ như là hành vi khá kỳ lạ trong trường hợp của tôi. Khi tôi chạy truy vấn như hiện tại, thông qua trình duyệt truy vấn, nó sẽ tìm nạp cho tôi kết quả. Nhưng sử dụng một thủ tục được lưu trữ sẽ đưa ra một lỗi.
dùng355562

5
Nhị phân dường như là giải pháp tốt nhất cho tôi. Nó cũng có thể là tốt nhất cho bạn nếu bạn không sử dụng bất kỳ bộ lọc khó khăn nào.
Adam F

Tôi có cùng một vấn đề, cách tôi giải quyết vấn đề này được tạo lại từ đầu. Tôi đã thử thay đổi đối chiếu nhưng khi tôi tham gia vẫn gặp lỗi, vì vậy tôi đã thử theo cách đó. cmiiw
Bobby Z

Xin lưu ý rằng có một lỗi trong MariaDB sử dụng COLLATE latin1_general_ci gây ra một lỗi khác: COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'latin1''- ngay cả khi bạn không có một cột với CHARACTER SET 'latin1'! Giải pháp là sử dụng dàn diễn viên BINary. Xem thêm câu hỏi này
Mel_T

154

TL; DR

Hoặc thay đổi đối chiếu một (hoặc cả hai) chuỗi để chúng khớp hoặc nếu không thêm COLLATEmệnh đề vào biểu thức của bạn.


  1. Công cụ "đối chiếu" này là gì?

    Như tài liệu dưới Bộ ký tự và Bộ sưu tập nói chung :

    Một bộ ký tự là một tập hợp các ký hiệu và mã hóa. Đối chiếu là một bộ quy tắc để so sánh các ký tự trong một bộ ký tự. Hãy làm rõ sự khác biệt bằng một ví dụ về một bộ ký tự tưởng tượng.

    Giả sử chúng ta có một bảng chữ cái với bốn chữ: “ A”, “ B”, “ a”, “ b”. Chúng tôi cung cấp cho mỗi chữ cái a number: A“ ” = 0, B“ ” = 1 a“ ” 2 = b“ ” = 3. Bức thư “ A” là một biểu tượng, số 0 là mã hóa cho “ A”, và sự kết hợp của tất cả các bốn chữ cái và mã hóa của chúng là một bộ ký tự .

    Giả sử rằng chúng ta muốn so sánh hai giá trị chuỗi, phạm lỗi Avà phạm lỗi B. Cách đơn giản nhất để làm điều này là xem xét các bảng mã: 0 cho phạm lỗi Avà 1 cho phạm lỗi B. Bởi vì 0 nhỏ hơn 1, nên chúng tôi nói rằng gián Aít hơn so với B. Những gì chúng ta vừa làm là áp dụng đối chiếu cho bộ ký tự của chúng ta. Đối chiếu là một tập hợp các quy tắc (chỉ có một quy tắc trong trường hợp này): so sánh các mã hóa. Chúng tôi gọi điều này đơn giản nhất trong tất cả các đối chiếu có thể là đối chiếu nhị phân .

    Nhưng nếu chúng ta muốn nói rằng chữ thường và chữ in hoa là tương đương thì sao? Sau đó chúng ta sẽ có ít nhất hai quy tắc: (1) điều trị các chữ thường “ a” và “ b” như tương đương với “ A” và “ B”; (2) sau đó so sánh các bảng mã. Chúng tôi gọi đây là đối chiếu không phân biệt chữ hoa chữ thường . Nó phức tạp hơn một chút so với đối chiếu nhị phân.

    Trong cuộc sống thực, hầu hết các bộ ký tự có nhiều nhân vật: không chỉ là “ A” và “ B” nhưng toàn bộ bảng chữ cái, đôi khi nhiều bảng chữ cái hoặc hệ thống chữ viết phía đông với hàng ngàn nhân vật, cùng với nhiều biểu tượng đặc biệt và dấu chấm câu. Ngoài ra, trong cuộc sống thực, hầu hết các bộ sưu tập đều có nhiều quy tắc, không chỉ về việc có nên phân biệt chữ cái hay không, mà còn để phân biệt các dấu (một dấu trọng âm là một dấu hiệu gắn liền với một ký tự như trong Tiếng Đức Ö) và cho nhiều ký tự ánh xạ (chẳng hạn như quy tắc mà ÖNghi phạm = Nghi phạm OEở một trong hai đối chiếu của Đức).

    Các ví dụ khác được đưa ra dưới Ví dụ về Hiệu ứng đối chiếu .

  2. Được rồi, nhưng làm thế nào để MySQL quyết định sử dụng đối chiếu nào cho một biểu thức đã cho?

    Như tài liệu trong Collation of Expressions :

    Trong phần lớn các báo cáo, rõ ràng những gì đối chiếu mà MySQL sử dụng để giải quyết một hoạt động so sánh. Ví dụ, trong các trường hợp sau, cần phải rõ rằng đối chiếu là đối chiếu của cột charset_name:

    SELECT x FROM T ORDER BY x;
    SELECT x FROM T WHERE x = x;
    SELECT DISTINCT x FROM T;

    Tuy nhiên, với nhiều toán hạng, có thể có sự mơ hồ. Ví dụ:

    SELECT x FROM T WHERE x = 'Y';

    So sánh nên sử dụng đối chiếu của cột x, hoặc của chuỗi bằng chữ 'Y'? Cả hai x'Y'có collations, vậy collation nào được ưu tiên?

    SQL chuẩn giải quyết các câu hỏi như vậy bằng cách sử dụng cái được gọi là quy tắc cưỡng chế của cưỡng chế.

    [ xóa ]

    MySQL sử dụng các giá trị cưỡng chế với các quy tắc sau để giải quyết sự mơ hồ:

    • Sử dụng đối chiếu với giá trị cưỡng chế thấp nhất.

    • Nếu cả hai bên có cùng khả năng cưỡng chế, thì:

      • Nếu cả hai bên là Unicode hoặc cả hai bên đều không phải là Unicode, đó là một lỗi.

      • Nếu một trong các bên có bộ ký tự Unicode và một bên khác có bộ ký tự không phải là Unicode, thì bên có bộ ký tự Unicode sẽ thắng và chuyển đổi bộ ký tự tự động được áp dụng cho bên không phải là Unicode. Ví dụ: câu lệnh sau không trả về lỗi:

        SELECT CONCAT(utf8_column, latin1_column) FROM t1;

        Nó trả về một kết quả có một bộ ký tự utf8và đối chiếu giống như utf8_column. Các giá trị latin1_columnđược tự động chuyển đổi thành utf8trước khi nối.

      • Đối với một hoạt động với toán hạng từ bộ ký tự giống nhau nhưng điều đó trộn một _binđối chiếu và một _cihoặc _csđối chiếu, các _binđối chiếu được sử dụng. Điều này tương tự như cách các hoạt động trộn các chuỗi nhị phân và nhị phân đánh giá các toán hạng là các chuỗi nhị phân, ngoại trừ việc nó dành cho các đối chiếu thay vì các kiểu dữ liệu.

  3. Vì vậy, một "hỗn hợp bất hợp pháp" là gì?

    Một "hỗn hợp bất hợp pháp" xảy ra khi một biểu thức so sánh hai chuỗi các đối chiếu khác nhau nhưng có tính cưỡng chế bằng nhau và các quy tắc cưỡng chế không thể giúp giải quyết xung đột. Đây là tình huống được mô tả dưới dấu đầu dòng thứ ba trong đoạn trích dẫn trên.

    Lỗi cụ thể được đưa ra trong câu hỏi, Illegal mix of collations (latin1_general_cs,IMPLICIT) and (latin1_general_ci,IMPLICIT) for operation '='cho chúng ta biết rằng có một so sánh bằng nhau giữa hai chuỗi không Unicode có khả năng cưỡng chế bằng nhau. Ngoài ra, nó còn cho chúng ta biết rằng các đối chiếu không được đưa ra rõ ràng trong câu lệnh mà là được ngụ ý từ các nguồn của chuỗi (chẳng hạn như siêu dữ liệu cột).

  4. Điều đó rất tốt, nhưng làm thế nào để giải quyết các lỗi như vậy?

    Như các trích xuất thủ công được trích dẫn ở trên cho thấy, vấn đề này có thể được giải quyết theo một số cách, trong đó hai cách hợp lý và được khuyến nghị:

    • Thay đổi đối chiếu của một (hoặc cả hai) chuỗi để chúng khớp và không còn bất kỳ sự mơ hồ nào.

      Làm thế nào điều này có thể được thực hiện tùy thuộc vào nơi chuỗi đã đến: Các biểu thức bằng chữ lấy đối chiếu được chỉ định trong collation_connectionbiến hệ thống; các giá trị từ các bảng lấy đối chiếu được chỉ định trong siêu dữ liệu cột của chúng.

    • Buộc một chuỗi để không bị ép buộc.

      Tôi đã bỏ qua các trích dẫn sau đây ở trên:

      MySQL gán các giá trị cưỡng chế như sau:

      • Một COLLATEmệnh đề rõ ràng có độ cưỡng chế bằng 0. (Không cưỡng chế được chút nào.)

      • Sự kết hợp của hai chuỗi với các đối chiếu khác nhau có độ cưỡng chế là 1.

      • Đối chiếu của một cột hoặc một tham số thường trình được lưu trữ hoặc biến cục bộ có khả năng cưỡng chế là 2.

      • Một hằng số hệ thống của NỀN TẢNG (chuỗi được trả về bởi các hàm như USER()hoặc VERSION()) có khả năng cưỡng chế là 3.

      • Đối chiếu của một nghĩa đen có độ cưỡng chế là 4.

      • NULLhoặc một biểu thức có nguồn gốc từ NULLcó độ cưỡng chế là 5.

      Do đó, chỉ cần thêm một COLLATEmệnh đề vào một trong các chuỗi được sử dụng trong so sánh sẽ buộc sử dụng đối chiếu đó.

    Trong khi những người khác sẽ thực hành tồi tệ khủng khiếp nếu họ được triển khai chỉ để giải quyết lỗi này:

    • Buộc một (hoặc cả hai) chuỗi phải có một số giá trị cưỡng chế khác để một chuỗi được ưu tiên.

      Việc sử dụng CONCAT()hoặc CONCAT_WS()sẽ dẫn đến một chuỗi có độ cưỡng chế là 1; và (nếu trong một thói quen được lưu trữ) việc sử dụng các tham số / biến cục bộ sẽ dẫn đến các chuỗi có khả năng cưỡng chế là 2.

    • Thay đổi mã hóa của một (hoặc cả hai) chuỗi để một chuỗi là Unicode và chuỗi còn lại thì không.

      Điều này có thể được thực hiện thông qua chuyển mã với ; hoặc thông qua thay đổi bộ ký tự cơ bản của dữ liệu (ví dụ: sửa đổi cột, thay đổi giá trị bằng chữ hoặc gửi chúng từ máy khách trong một mã hóa khác và thay đổi / thêm một bộ giới thiệu bộ ký tự). Lưu ý rằng việc thay đổi mã hóa sẽ dẫn đến các vấn đề khác nếu một số ký tự mong muốn không thể được mã hóa trong bộ ký tự mới.CONVERT(expr USING transcoding_name)character_set_connectioncharacter_set_client

    • Thay đổi mã hóa của một (hoặc cả hai) chuỗi để chúng giống nhau và thay đổi một chuỗi để sử dụng _binđối chiếu có liên quan .

      Phương pháp thay đổi mã hóa và đối chiếu đã được trình bày chi tiết ở trên. Cách tiếp cận này sẽ ít được sử dụng nếu một người thực sự cần áp dụng các quy tắc đối chiếu nâng cao hơn so với _binđối chiếu.


4
Lưu ý rằng "kết hợp bất hợp pháp" cũng có thể phát sinh khi không có sự mơ hồ về việc sử dụng đối chiếu nào, nhưng chuỗi được ép buộc phải được chuyển mã thành mã hóa trong đó một số ký tự của nó không thể được biểu diễn. Tôi đã thảo luận về trường hợp này trong một câu trả lời trước .
eggyal

5
Câu trả lời chính xác. Điều này nên được tiếp tục, bởi vì nó đi sâu vào những gì các nhà phát triển nên thực sự biết; không chỉ là cách khắc phục nó, mà thực sự hiểu lý do tại sao mọi thứ đang diễn ra theo cách chúng đang xảy ra.
đánh dấu

Cảm ơn anh bạn, bạn đã dạy tôi một cái gì đó ngày hôm nay.
briankip

66

Thêm 2c của tôi vào cuộc thảo luận cho các nhân viên của Google trong tương lai.

Tôi đã nghiên cứu một vấn đề tương tự khi tôi gặp lỗi sau khi sử dụng các hàm tùy chỉnh nhận được tham số varchar:

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

Sử dụng truy vấn sau:

mysql> show variables like "collation_database";
    +--------------------+-----------------+
    | Variable_name      | Value           |
    +--------------------+-----------------+
    | collation_database | utf8_general_ci |
    +--------------------+-----------------+

Tôi đã có thể nói rằng DB đã sử dụng utf8_general_ci , trong khi các bảng được xác định bằng utf8_unicode_ci :

mysql> show table status;
    +--------------+-----------------+
    | Name         | Collation       |
    +--------------+-----------------+
    | my_view      | NULL            |
    | my_table     | utf8_unicode_ci |
    ...

Lưu ý rằng các khung nhìn có đối chiếu NULL . Dường như các khung nhìn và các hàm có các định nghĩa đối chiếu mặc dù truy vấn này hiển thị null cho một khung nhìn. Đối chiếu được sử dụng là đối chiếu DB được xác định khi chế độ xem / chức năng được tạo.

Giải pháp đáng buồn là cả hai thay đổi đối chiếu db và tạo lại các khung nhìn / hàm để buộc chúng sử dụng đối chiếu hiện tại.

  • Thay đổi đối chiếu của db:

    ALTER DATABASE mydb DEFAULT COLLATE utf8_unicode_ci;
  • Thay đổi đối chiếu bảng:

    ALTER TABLE mydb CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Tôi hy vọng điều này sẽ giúp được ai đó.


12
Đối chiếu cũng có thể được đặt ở cấp cột. Bạn có thể xem nó với:show full columns from my_table;
Jonathan Tran

Cảm ơn bạn. Tôi vừa bỏ lược đồ và tạo lại nó với đối chiếu mặc định chính xác và nhập lại mọi thứ.
JRun

1
@JonathanTran Cảm ơn bạn! Tôi đã thiết lập bộ ký tự và đối chiếu trên tất cả các bảng, cơ sở dữ liệu và kết nối, nhưng nó vẫn báo lỗi! Đối chiếu không được đặt trên một cột! Tôi đã sửa nó bằngalter table <TABLE> modify column <COL> varchar(255) collate utf8_general_ci;
Chloe

2
Sidenote cho các nhân viên Google trong tương lai: Ngay cả khi cơ sở dữ liệu, bảng và trường của bạn có cùng đối chiếu, bạn cũng phải đảm bảo rằng kết nối của bạn đang sử dụng cùng một đối chiếu. Mọi thứ đều có »utf8mb4_unicode_ci« nhưng SHOW session variables like '%collation%';cho bạn biết rằng »collation_connection« là »utf8mb4_general_ci«? Sau đó chạy SET collation_connection = utf8mb4_unicode_citrước.
pixelbrackets 30/03/2017

Cảm ơn bạn! Mất một lúc để theo dõi điều này. Các bảng không chỉ phải đối chiếu giống nhau, mà DB cũng vậy!
moto

15

Đôi khi có thể nguy hiểm khi chuyển đổi bộ ký tự, đặc biệt trên cơ sở dữ liệu với lượng dữ liệu khổng lồ. Tôi nghĩ tùy chọn tốt nhất là sử dụng toán tử "nhị phân":

e.g : WHERE binary table1.column1 = binary table2.column1

10

Tôi gặp vấn đề tương tự, đã cố gắng sử dụng thủ tục FIND_IN_SET với biến chuỗi .

SET @my_var = 'string1,string2';
SELECT * from my_table WHERE FIND_IN_SET(column_name,@my_var);

và đã nhận được lỗi

Mã lỗi: 1267. Kết hợp bất hợp pháp các collations (utf8_unicode_ci, IMPLICIT) và (utf8_general_ci, IMPLICIT) cho hoạt động 'find_in_set'

Câu trả lời ngắn:

Không cần thay đổi bất kỳ biến collation_YYYY nào, chỉ cần thêm đối chiếu chính xác bên cạnh khai báo biến của bạn , nghĩa là

SET @my_var = 'string1,string2' COLLATE utf8_unicode_ci;
SELECT * from my_table WHERE FIND_IN_SET(column_name,@my_var);

Câu trả lời dài:

Lần đầu tiên tôi kiểm tra các biến đối chiếu:

mysql> SHOW VARIABLES LIKE 'collation%';
    +----------------------+-----------------+
    | Variable_name        | Value           |
    +----------------------+-----------------+
    | collation_connection | utf8_general_ci |
    +----------------------+-----------------+
    | collation_database   | utf8_general_ci |
    +----------------------+-----------------+
    | collation_server     | utf8_general_ci |
    +----------------------+-----------------+

Sau đó, tôi đã kiểm tra đối chiếu bảng:

mysql> SHOW CREATE TABLE my_table;

CREATE TABLE `my_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `column_name` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=125 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Điều này có nghĩa là biến của tôi được cấu hình với đối chiếu mặc định là utf8_general_ci trong khi bảng của tôi được định cấu hình là utf8_unicode_ci .

Bằng cách thêm lệnh COLLATE bên cạnh khai báo biến, đối chiếu biến phù hợp với đối chiếu được cấu hình cho bảng.



2

Giải pháp nếu chữ có liên quan.

Tôi đang sử dụng Pentaho Data Integration và không nhận được cú pháp sql. Việc sử dụng một tra cứu DB rất đơn giản đã gây ra lỗi "Hỗn hợp các bộ sưu tập bất hợp pháp (cp850_general_ci, COERCIBLE) và (latin1_swbur_ci, COERCIBLE) cho hoạt động '='"

Mã được tạo là "CHỌN DATA_DATE AS mới nhất_DATA_DATE TỪ hr_cc_n normalised_data_date_v WHERE PSEUDO_KEY =?"

Cắt ngắn câu chuyện tra cứu là để xem và khi tôi ban hành

mysql> show full columns from hr_cc_normalised_data_date_v;
+------------+------------+-------------------+------+-----+
| Field      | Type       | Collation         | Null | Key |
+------------+------------+-------------------+------+-----+
| PSEUDO_KEY | varchar(1) | cp850_general_ci  | NO   |     |
| DATA_DATE  | varchar(8) | latin1_general_cs | YES  |     |
+------------+------------+-------------------+------+-----+

trong đó giải thích 'cp850_general_ci' đến từ đâu.

Chế độ xem được tạo đơn giản với 'CHỌN' X ', ......' Theo các chữ thủ công như thế này sẽ kế thừa tập ký tự và đối chiếu của chúng từ cài đặt máy chủ được xác định chính xác là 'latin1' và 'latin1_general_cs' như thế này rõ ràng đã không xảy ra tôi đã buộc nó trong việc tạo ra quan điểm

CREATE OR REPLACE VIEW hr_cc_normalised_data_date_v AS
SELECT convert('X' using latin1) COLLATE latin1_general_cs        AS PSEUDO_KEY
    ,  DATA_DATE
FROM HR_COSTCENTRE_NORMALISED_mV
LIMIT 1;

bây giờ nó hiển thị latin1_general_cs cho cả hai cột và lỗi đã biến mất. :)


1

MySQL thực sự không thích các bộ sưu tập trộn trừ khi nó có thể ép buộc chúng vào cùng một bộ phận (điều này rõ ràng là không khả thi trong trường hợp của bạn). Bạn có thể chỉ ép buộc đối chiếu tương tự được sử dụng thông qua mệnh đề COLLATE không? (hoặc BINARYphím tắt đơn giản hơn nếu có ...).


Đây có phải là duy nhất cho MySQL? Làm thế nào để các hệ thống khác xử lý hỗn hợp các đối chiếu không tương thích có mức độ ưu tiên rõ ràng bằng nhau?
eggyal

Liên kết của bạn không hợp lệ.
Benubird

1

Nếu các cột mà bạn gặp sự cố là "băm", thì hãy xem xét các điều sau ...

Nếu "hàm băm" là một chuỗi nhị phân, bạn thực sự nên sử dụng BINARY(...)kiểu dữ liệu.

Nếu "hàm băm" là một chuỗi hex, bạn không cần utf8 và nên tránh như vậy vì kiểm tra ký tự, v.v. Ví dụ, MySQL MD5(...)mang lại chuỗi hex 32 byte có độ dài cố định. SHA1(...)đưa ra một chuỗi hex 40 byte. Điều này có thể được lưu trữ vào CHAR(32) CHARACTER SET ascii(hoặc 40 cho sha1).

Hoặc, tốt hơn, lưu trữ UNHEX(MD5(...))vào BINARY(16). Điều này cắt giảm một nửa kích thước của cột. (Tuy nhiên, nó làm cho nó khá không thể in được.) SELECT HEX(hash) ...Nếu bạn muốn nó có thể đọc được.

So sánh hai BINARYcột không có vấn đề đối chiếu.


1

Rất thú vị ... Bây giờ, hãy sẵn sàng. Tôi đã xem xét tất cả các giải pháp "thêm đối chiếu" và với tôi, đó là những giải pháp hỗ trợ ban nhạc. Thực tế là thiết kế cơ sở dữ liệu là "xấu". Vâng, những thay đổi tiêu chuẩn và những điều mới được thêm vào, blah blah, nhưng nó không thay đổi thực tế thiết kế cơ sở dữ liệu xấu. Tôi từ chối đi theo lộ trình thêm "đối chiếu" trên tất cả các câu lệnh SQL chỉ để truy vấn của tôi hoạt động. Giải pháp duy nhất phù hợp với tôi và hầu như sẽ loại bỏ nhu cầu chỉnh sửa mã của tôi trong tương lai là thiết kế lại cơ sở dữ liệu / bảng để phù hợp với bộ ký tự mà tôi sẽ sống và nắm lấy trong tương lai lâu dài. Trong trường hợp này, tôi chọn đi với bộ ký tự " utf8mb4 ".

Vì vậy, giải pháp ở đây khi bạn gặp phải thông báo lỗi "bất hợp pháp" đó là thiết kế lại cơ sở dữ liệu và bảng của bạn. Nó là dễ dàng hơn nhiều và nhanh hơn sau đó nó âm thanh. Xuất dữ liệu của bạn và nhập lại từ CSV thậm chí có thể không được yêu cầu. Thay đổi bộ ký tự của cơ sở dữ liệu và đảm bảo tất cả bộ ký tự của các bảng của bạn khớp.

Sử dụng các lệnh này để hướng dẫn bạn:

SHOW VARIABLES LIKE "collation_database";
SHOW TABLE STATUS;

Bây giờ, nếu bạn thích thêm "đối chiếu" ở đây và ở đó và tăng cường mã của bạn với các lực lượng "ghi đè", hãy đoán tôi.



0

Một nguồn khác của vấn đề với collations là mysql.procbảng. Kiểm tra các bộ sưu tập các quy trình và chức năng lưu trữ của bạn:

SELECT
  p.db, p.db_collation, p.type, COUNT(*) cnt
FROM mysql.proc p
GROUP BY p.db, p.db_collation, p.type;

Cũng chú ý đến mysql.proc.collation_connectionmysql.proc.character_set_clientcột.


0

Nếu bạn đã cài đặt phpMyAdmin, bạn có thể làm theo các hướng dẫn được cung cấp trong liên kết sau: https://mediatemple.net/community/products/dv/204403914/default-mysql-character-set-and-collation Bạn phải khớp với đối chiếu của cơ sở dữ liệu với tất cả các bảng, cũng như các trường của các bảng và sau đó biên dịch lại tất cả các thủ tục và hàm được lưu trữ. Với điều đó mọi thứ nên hoạt động trở lại.


-1

Tôi đã sử dụng ALTER DATABASE mydb DEFAULT COLLATE utf8_unicode_ci;, nhưng không làm việc.

Trong truy vấn này:

Select * from table1, table2 where table1.field = date_format(table2.field,'%H');

Công việc này đối với tôi:

Select * from table1, table2 where concat(table1.field) = date_format(table2.field,'%H');

Vâng, chỉ có một concat.


Kiểm tra đối chiếu các bảng của bạn và các cột của chúng (hiển thị trạng thái bảng; và hiển thị các cột đầy đủ từ bảng1;). Sử dụng cơ sở dữ liệu thay đổi sẽ không hoạt động nếu các bảng đã được tạo với đối chiếu sai.
Ariel T

THAY ĐỔI CƠ SỞ mydb DEFAULT THU ... đã làm việc cho tôi, vì vậy hãy nâng cấp. Có lẽ tôi đã có một lợi thế vì tôi có thể thả và tạo lại cơ sở dữ liệu và tải từ các bản sao lưu.
tobixen

-2

Mã này cần được đặt bên trong Chạy truy vấn / truy vấn SQL trên cơ sở dữ liệu

SQL QUERY WINDOW

ALTER TABLE `table_name` CHANGE `column_name` `column_name`   VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL;

Vui lòng thay thế tên_bảng và tên_bảng bằng tên thích hợp.

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.