ข้อผิดพลาด MySQL ผสมกันอย่างผิดกฎหมาย


124

ฉันได้รับข้อผิดพลาดแปลก ๆ ขณะประมวลผลข้อมูลจำนวนมาก ...

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 昔 ã‹ã‚‰ ã‚ã‚‹ å ´æ‰€'

ฉันจะแก้ไขปัญหานี้ได้อย่างไร ฉันสามารถหลีกเลี่ยงสตริงได้อย่างไรเพื่อไม่ให้ข้อผิดพลาดนี้เกิดขึ้นหรือฉันต้องเปลี่ยนการเข้ารหัสตารางของฉันหรือไม่และถ้าเป็นเช่นนั้นฉันควรเปลี่ยนเป็นอะไร


ข้อผิดพลาดนี้เป็นแบบฉีดได้หรือไม่?
hamza irizaj

คำตอบ:


288
SET collation_connection = 'utf8_general_ci';

จากนั้นสำหรับฐานข้อมูลของคุณ

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 แอบแอบอยู่ในนั้นในบางครั้งโดยไม่มีเหตุผลที่สมเหตุสมผล


3
@ เบ็น: ขอบคุณสำหรับโซลูชันที่คัดลอกวางได้โดยตรง ช่วยฉันประหยัดเวลาได้มาก
Pistos

15
@ เบ็น: เริ่มแรกพัฒนาโดย บริษัท สวีเดน ... นั่นคือเหตุผลเบื้องหลังการตั้งค่าเริ่มต้น latin1_swedish_ci ที่น่ารำคาญ .. :(
Vajk Hermecz

1
ฉันไม่มีสิทธิ์ทำคำสั่งแรก แต่มันใช้งานได้แค่ทำตาราง
Rob Sedgwick

รักคุณขนาดนี้! : P
prateekkathal

ดูเหมือนว่าจะใช้ได้กับหลาย ๆ คน แต่น่าเสียดายที่ฉันยังคงมีปัญหานี้แม้ว่าจะลองใช้อุปกรณ์ทั้งหมดในชุดข้อความนี้แล้วก็ตาม การเปรียบเทียบค่าเริ่มต้นฐานข้อมูลของฉันปฏิเสธที่จะเปลี่ยนจาก 'ucs2_bin' อย่างดื้อรั้นดังนั้นแม้จะลองเปลี่ยนตารางทั้งหมดและการเปรียบเทียบการเชื่อมต่อเป็น 'usc2_bin' แต่ฉันยังคงได้รับข้อผิดพลาด "SQL Error (1267): การผสมของการเปรียบเทียบที่ไม่ถูกต้อง (utf8_general_ci, IMPLICIT) และ (ucs2_bin, IMPLICIT) สำหรับการดำเนินการ '=' "
bikeman868

15

คุณควรตั้งค่าทั้งการเข้ารหัสตารางและการเข้ารหัสการเชื่อมต่อเป็นUTF-8:

ALTER TABLE keywords CHARACTER SET UTF8; -- run once

และ

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

จำเป็นทั้งสองอย่างนี้หรือฉันสามารถทำอย่างใดอย่างหนึ่งได้หรือไม่?
Click Upvote

เปลี่ยนฐานข้อมูล myDbDEFAULT CHARACTER SET utf8 COLLATE utf8_bin จะได้ผลหรือไม่? เสร็จแล้วมันจะส่งผลกระทบต่อตารางทั้งหมดของฉันไม่ใช่แค่โต๊ะเดียว
Click Upvote

1
แก้ไขฐานข้อมูลจะไม่เปลี่ยนการตั้งค่าตารางปัจจุบันของคุณเฉพาะการตั้งค่าที่สร้างขึ้นใหม่ แม้ว่าจะไม่เจ็บที่จะเปลี่ยนกฎเริ่มต้นสำหรับฐานข้อมูลด้วย
Quassnoi

SET NAMES และ SET CHARACTER SET จะเปลี่ยนการเข้ารหัสการเชื่อมต่อของคุณ คุณต้องออกคำสั่งเหล่านี้ทุกครั้งที่เชื่อมต่อ ไลบรารีไคลเอนต์ของคุณอาจสนับสนุนวิธีการที่หรูหรากว่าในการทำ (php :: mysqli ทำ, php :: mysql ไม่ได้)
Quassnoi

ดูเหมือนว่าจะได้ผลในตอนนี้ฉันจะยอมรับหลังจากการทดสอบเพิ่มเติม การสืบค้นที่สองจำเป็นต้องเรียกใช้ครั้งเดียวหรือเมื่อเริ่มต้นของแต่ละสคริปต์?
Click Upvote

13
CONVERT(column1 USING utf8)

แก้ปัญหาของฉัน โดยที่ column1 คือคอลัมน์ที่ให้ข้อผิดพลาดนี้แก่ฉัน


สำหรับฉันสิ่งนี้ได้ผล: CONVERT ("column1" USING LATIN1)
shasi kanth

4

ใช้คำสั่งต่อไปนี้สำหรับข้อผิดพลาด

ระวังข้อมูลของคุณสำรองหากข้อมูลมีอยู่ในตาราง

 แก้ไขตาราง your_table_name แปลงเป็นชุดอักขระ utf8 รวบรวม utf8_general_ci;

2

โดยทั่วไปวิธีที่ดีที่สุดคือเปลี่ยนการเรียงตาราง อย่างไรก็ตามฉันมีแอปพลิเคชันเก่าและไม่สามารถประเมินผลลัพธ์ได้ว่ามีผลข้างเคียงหรือไม่ ดังนั้นฉันจึงพยายามแปลงสตริงเป็นรูปแบบอื่นที่แก้ปัญหาการเรียงลำดับได้ สิ่งที่ฉันพบว่าได้ผลคือทำการเปรียบเทียบสตริงโดยการแปลงสตริงเป็นการแทนค่าฐานสิบหกของอักขระของมัน ในฐานข้อมูลสิ่งนี้ทำได้ด้วยHEX(column).For PHP คุณสามารถใช้ฟังก์ชันนี้:

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);
}

เมื่อทำการสืบค้นฐานข้อมูลสตริง UTF8 ดั้งเดิมของคุณจะต้องถูกแปลงเป็นสตริง iso ก่อน (เช่นใช้utf8_decode()ใน PHP) ก่อนที่จะใช้ใน DB เนื่องจากประเภทการจัดเรียงฐานข้อมูลจึงไม่สามารถมีอักขระ UTF8 อยู่ภายในได้ดังนั้นการเปรียบเทียบจึงควรทำงานได้แม้ว่าสิ่งนี้จะเปลี่ยนสตริงดั้งเดิม (การแปลงอักขระ UTF8 ที่ไม่มีอยู่ในผลลัพธ์ชุดอักขระ ISO ใน a? หรือสิ่งเหล่านี้จะถูกลบออกทั้งหมด) ตรวจสอบให้แน่ใจว่าเมื่อคุณเขียนข้อมูลลงในฐานข้อมูลแสดงว่าคุณใช้การแปลง UTF8 เป็น ISO เดียวกัน


2

ฉันได้โต๊ะของเดิมที่สร้างขึ้นด้วยcharset = latin1 หลังจากการแปลงตารางเป็นutf8บางคอลัมน์ไม่ได้รับการแปลง แต่ก็ไม่ชัดเจนนัก คุณสามารถลองเรียกใช้SHOW CREATE TABLE my_table;และดูว่าคอลัมน์ใดไม่ได้ถูกแปลงหรือเพียงแค่แก้ไขชุดอักขระที่ไม่ถูกต้องในคอลัมน์ที่มีปัญหาด้วยแบบสอบถามด้านล่าง (เปลี่ยนความยาว varchar และ CHARSET และ COLLATE ตามความต้องการของคุณ):

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

2

เปลี่ยนชุดอักขระของตารางเป็น utf8

แก้ไขตาราง your_table_name แปลงเป็นชุดอักขระ utf8


0

หลังจากทำการแก้ไขตามรายการในคำตอบด้านบนแล้วให้เปลี่ยนการตั้งค่าเริ่มต้นของเซิร์ฟเวอร์ของคุณ

ใน " /etc/my.cnf.d/server.cnf " ของคุณหรือที่ใดก็ตามให้เพิ่มค่าเริ่มต้นในส่วน[mysqld]เพื่อให้มีลักษณะดังนี้:

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

ที่มา: https://dev.mysql.com/doc/refman/5.7/en/charset-applications.html


0

ฉันพบว่าการใช้cast()เป็นทางออกที่ดีที่สุดสำหรับฉัน:

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

นอกจากนี้ยังมีconvert()ฟังก์ชั่น ดูรายละเอียดเพิ่มเติมได้ที่นี่

แหล่งข้อมูลอื่นที่นี่


0

บัญชีผู้ใช้ของฉันไม่มีสิทธิ์ในการแก้ไขฐานข้อมูลและตารางตามที่แนะนำในโซลูชันนี้

ถ้าเช่นฉันคุณไม่สนใจเกี่ยวกับการเรียงอักขระ (คุณใช้ตัวดำเนินการ '=') คุณสามารถใช้การแก้ไขย้อนกลับได้ เรียกใช้ก่อน SELECT ของคุณ:

SET collation_connection = 'latin1_swedish_ci';
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.