ऑपरेशन के लिए कोलाज (utf8_unicode_ci, IMPLICIT) और (utf8_general_ci, IMPLICIT) का अवैध मिश्रण '='


160

MySql पर त्रुटि संदेश:

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

मैं कई अन्य पदों से गुजरा हूं और इस समस्या को हल करने में सक्षम नहीं था। प्रभावित हिस्सा कुछ इस तरह है:

CREATE TABLE users (
    userID INT UNSIGNED NOT NULL AUTO_INCREMENT,
    firstName VARCHAR(24) NOT NULL,
    lastName VARCHAR(24) NOT NULL,
    username VARCHAR(24) NOT NULL,
    password VARCHAR(40) NOT NULL,
    PRIMARY KEY (userid)
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE products (
    productID INT UNSIGNED NOT NULL AUTO_INCREMENT,
    title VARCHAR(104) NOT NULL,
    picturePath VARCHAR(104) NULL,
    pictureThumb VARCHAR(104) NULL,
    creationDate DATE NOT NULL,
    closeDate DATE NULL,
    deleteDate DATE NULL,
    varPath VARCHAR(104) NULL,
    isPublic TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
    PRIMARY KEY (productID)
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE productUsers (
    productID INT UNSIGNED NOT NULL,
    userID INT UNSIGNED NOT NULL,
    permission VARCHAR(16) NOT NULL,
    PRIMARY KEY (productID,userID),
    FOREIGN KEY (productID) REFERENCES products (productID) ON DELETE RESTRICT ON UPDATE NO ACTION,
    FOREIGN KEY (userID) REFERENCES users (userID) ON DELETE RESTRICT ON UPDATE NO ACTION
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci;

संग्रहीत प्रक्रिया मैं उपयोग कर रहा हूँ यह है:

CREATE PROCEDURE updateProductUsers (IN rUsername VARCHAR(24),IN rProductID INT UNSIGNED,IN rPerm VARCHAR(16))
BEGIN
    UPDATE productUsers
        INNER JOIN users
        ON productUsers.userID = users.userID
        SET productUsers.permission = rPerm
        WHERE users.username = rUsername
        AND productUsers.productID = rProductID;
END

मैं php के साथ परीक्षण कर रहा था, लेकिन SQLyog के साथ वही त्रुटि दी गई है। मैंने पूरे डीबी को फिर से बनाने के लिए परीक्षण किया है, लेकिन कोई अच्छा नहीं है।

किसी भी प्रकार के मदद की बहुत सराहना की जाएगी।

जवाबों:


220

संग्रहीत कार्यविधि मापदंडों के लिए डिफ़ॉल्ट टकराव है utf8_general_ciऔर आप टकरावों को नहीं मिला सकते हैं, इसलिए आपके पास चार विकल्प हैं:

विकल्प 1 : COLLATEअपने इनपुट चर में जोड़ें :

SET @rUsername = aname COLLATE utf8_unicode_ci; -- COLLATE added
CALL updateProductUsers(@rUsername, @rProductID, @rPerm);

विकल्प 2 : ऐड COLLATEकरने के लिए WHEREखंड:

CREATE PROCEDURE updateProductUsers(
    IN rUsername VARCHAR(24),
    IN rProductID INT UNSIGNED,
    IN rPerm VARCHAR(16))
BEGIN
    UPDATE productUsers
        INNER JOIN users
        ON productUsers.userID = users.userID
        SET productUsers.permission = rPerm
        WHERE users.username = rUsername COLLATE utf8_unicode_ci -- COLLATE added
        AND productUsers.productID = rProductID;
END

विकल्प 3 : इसे INपैरामीटर परिभाषा में जोड़ें :

CREATE PROCEDURE updateProductUsers(
    IN rUsername VARCHAR(24) COLLATE utf8_unicode_ci, -- COLLATE added
    IN rProductID INT UNSIGNED,
    IN rPerm VARCHAR(16))
BEGIN
    UPDATE productUsers
        INNER JOIN users
        ON productUsers.userID = users.userID
        SET productUsers.permission = rPerm
        WHERE users.username = rUsername
        AND productUsers.productID = rProductID;
END

विकल्प 4 : क्षेत्र को ही बदल दें:

ALTER TABLE users CHARACTER SET utf8 COLLATE utf8_general_ci;

जब तक आपको यूनिकोड क्रम में डेटा को सॉर्ट करने की आवश्यकता नहीं होती, तब तक मैं utf8_general_ciकोलाज का उपयोग करने के लिए आपके सभी तालिकाओं को बदलने का सुझाव दूंगा, क्योंकि इसमें कोई कोड परिवर्तन की आवश्यकता नहीं है, और यह थोड़ा ऊपर की ओर गति करेगा।

अद्यतन : utf8mb4 / utf8mb4_unicode_ci अब पसंदीदा वर्ण सेट / कोलाज विधि है। utf8_general_ci के खिलाफ सलाह दी जाती है, क्योंकि प्रदर्शन में सुधार नगण्य है। Https://stackoverflow.com/a/766996/1432614 देखें


1
COLLATE utf8_unicode_ciस्ट्रिंग स्थिरांक में जोड़ना भी संभव है SET @EMAIL = 'abc@def.com' COLLATE utf8_unicode_ci;:। यह विशेष रूप से उपयोगी है यदि आप एक स्क्रिप्ट को कंसोल से चला रहे हैं, जहां कंसोल डिफ़ॉल्ट एन्कोडिंग आपके स्ट्रिंग स्थिरांक के टकराव पर लागू होती है।
गाबर्सच

या डेटाबेस को ड्रॉप करें और utf8_general_ci के साथ नया बनाएं; मिलान।
ओलेक्सी कोस्लीट्सिन

2
भविष्य के संदर्भ के लिए, अपने सभी तालिकाओं को utf8_general_ci में तब तक न बदलें जब तक कि आप दो टकरावों के बीच के अंतर को नहीं समझते हैं।
मैनटैक्स

1
@GaborSch स्ट्रिंग वेरिएबल्स में कोलायत जोड़ना मेरे लिए समाधान था, मैंने आपकी टिप्पणी पर गौर करने से पहले इसके बारे में विस्तृत उत्तर लिखा था।
nkatsar

एक ही त्रुटि मिल रही im, सिवाय इसके (utf8mb4_unicode_ci, IMPLICIT)बजाय (utf8_unicode_ci, IMPLICIT)। मैं अजगर का उपयोग करके वेब से डेटा स्क्रैप कर रहा हूं, फिर स्क्रैप किए गए डेटा के साथ एक सीएसवी फ़ाइल बना रहा हूं, जो तब मैं अपने सर्वर पर एक PHP फ़ाइल के साथ प्रक्रिया करता हूं जो डेटा को मेरे डेटाबेस पर अपलोड करता है। मेरे सभी MySQL टेबल / कॉलम को इस रूप में समेटा गया है utf8mb4_unicode_ci। समस्या उत्पन्न हो सकती है क्योंकि मैं डेटा को utf8अजगर / सीएसवी के रूप में बताता हूं ?
ओल्डबॉय

27

मैंने utf8_unicode_ci और utf8_general_ci के बीच टकराव के साथ एक समान "अवैध मिश्रण के टकराव" के जवाब की तलाश में आधा दिन बिताया।

मैंने पाया कि मेरे डेटाबेस में कुछ कॉलम विशेष रूप से utf8_unicode_ci को नहीं मिलाए गए थे । ऐसा लगता है कि mysql ने इन कॉलमों को utf8_general_ci से जोड़ दिया ।

विशेष रूप से, 'SHOW CREATE TABLE table1' क्वेरी को चलाने पर निम्न जैसा कुछ उत्पन्न होता है:

| table1 | CREATE TABLE `table1` (
`id` int(11) NOT NULL,
`col1` varchar(4) CHARACTER SET utf8 NOT NULL,
`col2` int(11) NOT NULL,
PRIMARY KEY (`col1`,`col2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |

ध्यान दें कि लाइन 'col1' वर्चर (4) CHARACTER SET utf8 नहीं NULL में एक कोलाज निर्दिष्ट नहीं है। मैंने तब निम्न क्वेरी चलाई:

ALTER TABLE table1 CHANGE col1 col1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL;

इसने मेरे "अवैध मिश्रणों के टकराव" को हल कर दिया। आशा है कि यह किसी और की मदद कर सकता है।


7
धन्यवाद। ABLE शो क्रिएट टेबल ’समस्या के मूल कारण को समझने और ठीक करने का सबसे आसान तरीका है।
जोरू

2
यह भी ध्यान दें कि COLLATEपूरी तालिका (यानी ALTER TABLE table1 CHARSET utf8 COLLATE utf8_unicode_ci) के लिए निर्दिष्ट करने से समस्या ठीक नहीं होगी , इसे प्रत्येक (समस्याग्रस्त) कॉलम के लिए करना होगा।
स्किप्पी ले ग्रांड गौरौ

6

मुझे एक समान समस्या थी, लेकिन यह मेरे अंदर की प्रक्रिया में हुआ, जब मेरी क्वेरी परम को चर का उपयोग करके सेट किया गया था SET @value='foo'

यह क्या कारण था बेमेल collation_connectionऔर डेटाबेस टकराव। collation_connectionमैच बदल गया collation_databaseऔर समस्या दूर हो गई। मुझे लगता है कि यह परम / मूल्य के बाद COLLATE को जोड़ने की तुलना में अधिक सुरुचिपूर्ण दृष्टिकोण है।

योग करने के लिए: सभी टकरावों का मिलान होना चाहिए। उपयोग करें SHOW VARIABLESऔर सुनिश्चित करें collation_connectionऔर collation_databaseमिलान करें (उपयोग करके तालिका टकराव की जांच करें SHOW TABLE STATUS [table_name])।


1
एक ही मुद्दा मेरे साथ हुआ, मैंने कोलाज को सीधे चर घोषणा में सेट करके collation_YYY चर को बदलने से परहेज किया। SET @my_var = 'string1,string2' COLLATE utf8_unicode_ci;
nkatsar

5

@Bpile उत्तर के समान, मेरा मामला my.cnf प्रविष्टि सेटिंग था collation-server = utf8_general_ci। जब मुझे एहसास हुआ कि (और ऊपर सब कुछ आज़माने के बाद), मैंने अपने डेटाबेस को utf8_unicode_ci के बजाय utf8_general_ci पर स्विच कर दिया और वह यह था:

ALTER DATABASE `db` CHARACTER SET utf8 COLLATE utf8_general_ci;

1
यह अजीब है कि विन्यास बहुत चारों ओर फैले हुए हैं। सभी कोलेशन डिफॉल्ट्स को एक ही जगह पर सेट किया जाना चाहिए।
मैनटैक्स

0

मेरे अपने मामले में मेरे पास निम्न त्रुटि है

ऑपरेशन के लिए कोलाज (utf8_general_ci, IMPLICIT) और (utf8_unicode_ci, IMPLICIT) का अवैध मिश्रण '='

$ यह-> db-> चुनें ("matric_no के रूप में users.username, CONCAT (users.surname, '', users.first_name, '', users.last_name) के रूप में fullname") -> शामिल ('उपयोगकर्ता', 'उपयोगकर्ता) .username = class_students.matric_no ',' left ') -> कहाँ (' 'class_students.session_id', $ session) -> जहाँ ('' class_students.level_id ', $ level) -> कहाँ (' 'class_students.dept_id'), $ dept_d );

Google खोज के हफ्तों के बाद मैंने देखा कि मैं जिन दो क्षेत्रों की तुलना कर रहा हूं उनमें अलग-अलग कोलाजेशन नाम शामिल हैं। पहला एक अर्थात उपयोगकर्ता नाम utf8_general_ci का है, जबकि दूसरा एक utf8_unicode_ci का है, इसलिए मैं दूसरी तालिका की संरचना में वापस चला गया और दूसरे फ़ील्ड (matric_no) को बदलकर utf8 -general_ci कर दिया और यह एक आकर्षण की तरह काम किया।


0

एक ही समस्या ( 1 , 2 , 3 , 4 ) के बारे में एक बड़ी संख्या में प्रश्न खोजने के बावजूद , मुझे कभी ऐसा उत्तर नहीं मिला जिसने प्रदर्शन को ध्यान में रखा हो।

यद्यपि कई कार्य समाधान पहले ही दिए जा चुके हैं, मैं एक प्रदर्शन पर विचार करना चाहूंगा।

EDIT: इस विकल्प को इंगित करने के लिए मैनटैक्स को धन्यवाद कि प्रदर्शन 1 को समस्याओं का सामना न करना पड़े।

विकल्प 1 और 2 का उपयोग करें , COLLATE कास्ट दृष्टिकोण उर्फ , संभावित अड़चन पैदा कर सकता है, क्योंकि स्तंभ पर परिभाषित किसी भी सूचकांक का उपयोग पूर्ण स्कैन के कारण नहीं किया जाएगा ।

भले ही मैंने विकल्प 3 की कोशिश नहीं की , लेकिन मेरा कूबड़ यह है कि यह विकल्प 1 और 2 के समान परिणाम भुगतना होगा ।

अंत में, विकल्प 4 बहुत बड़ी तालिकाओं के लिए सबसे अच्छा विकल्प है जब यह व्यवहार्य है। मेरा मतलब है कि कोई अन्य उपयोग नहीं है जो मूल टकराव पर भरोसा करते हैं।

इस सरलीकृत प्रश्न पर विचार करें:

SELECT 
    *
FROM
    schema1.table1 AS T1
        LEFT JOIN
    schema2.table2 AS T2 ON T2.CUI = T1.CUI
WHERE
    T1.cui IN ('C0271662' , 'C2919021')
;

मेरे मूल उदाहरण में, मेरे कई और जुड़ाव थे। बेशक, टेबल 1 और टेबल 2 के अलग-अलग टकराव हैं। कोलाज ऑपरेटर का उपयोग करने के लिए, यह अनुक्रमित करने के लिए नेतृत्व नहीं किया जाएगा।

नीचे चित्र में sql स्पष्टीकरण देखें।

COLLATE का उपयोग करते समय दृश्य क्वेरी स्पष्टीकरण

दूसरी ओर, विकल्प 4 संभावित सूचकांक का लाभ ले सकता है और तेजी से प्रश्नों का कारण बन सकता है।

नीचे दी गई तस्वीर में, आप लागू विकल्प 4 , उर्फ ​​स्कीमा / टेबल / कॉलम को बदलने के बाद उतने ही क्वेरी देख सकते हैं ।

कोलाज के बाद दृश्य क्वेरी स्पष्टीकरण को बदल दिया गया है, और इसलिए कोलाट कलाकारों के बिना

अंत में, यदि प्रदर्शन महत्वपूर्ण हैं और आप तालिका के टकराव को बदल सकते हैं, तो विकल्प 4 पर जाएं । यदि आपको किसी एकल स्तंभ पर कार्य करना है, तो आप कुछ इस तरह का उपयोग कर सकते हैं:

ALTER TABLE schema1.table1 MODIFY `field` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

आपके योगदान के लिए धन्यवाद रैफेल, लेकिन मेरा मानना ​​है कि विकल्प 1 इंडेक्स का उपयोग करेगा, क्योंकि आप तालिका को नहीं डाल रहे हैं, लेकिन तुलनात्मक मूल्य इससे पहले कि आप इसे एसपी को भी पास कर दें।
मैनटैक्स

यह बात बताने के लिए धन्यवाद। यह मेरी गलती थी। मैंने उसी के अनुसार अपना उत्तर संपादित किया।
राफेल

0

ऐसा तब होता है, जहां स्तंभ को स्पष्ट रूप से भिन्न कोलाजेशन पर सेट किया जाता है या डिफ़ॉल्ट रूप से संक्षिप्त की गई तालिका में भिन्न होती है।

यदि आपके पास कई तालिकाएँ हैं, तो आप इस क्वेरी को चलाने पर कोलाज बदलना चाहते हैं:

select concat('ALTER TABLE ', t.table_name , ' CONVERT TO CHARACTER 
SET utf8 COLLATE utf8_unicode_ci;') from (SELECT table_name FROM 
information_schema.tables where table_schema='SCHRMA') t;

यह प्रति कॉलम सही तालमेल का उपयोग करने के लिए सभी तालिकाओं को परिवर्तित करने के लिए आवश्यक प्रश्नों का उत्पादन करेगा


यह तब भी होता है जब (मेरे मामले में) एसपी के लिए आपका डिफ़ॉल्ट टकराव सारणी के लिए उपयोग किए गए टकराव से अलग होता है।
मैनटैक्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.