2009-07-28 19 views
31

मेरे पास एक MySQL तालिका है जहां एक कॉलम में सभी डेटा UPPERCASE में दर्ज किया गया था, लेकिन मुझे Daring Fireball Title Case script के समान "छोटे शब्दों" की पहचान के साथ शीर्षक केस में कनवर्ट करने की आवश्यकता है।क्या MySQL डेटा को शीर्षक केस में परिवर्तित करने का कोई आसान तरीका है?

मुझे स्ट्रिंग्स को लोअरकेस में बदलने के लिए this excellent solution मिला, लेकिन शीर्षक केस फ़ंक्शन को MySQL के मेरे संस्करण से बाहर रखा गया प्रतीत होता है। क्या ऐसा करने का कोई शानदार तरीका है?

+0

में करता है के लिए आप जॉन मेरा उत्तर काम करता है? – hobodave

उत्तर

1

वू! मैं बिल्कुल एसक्यूएल के साथ काम नहीं कर रहा हूँ; यहां दी गई विधि है जो मेरे लिए काम करती है:

  1. तालिका को .sql प्रारूप में टेक्स्ट फ़ाइल के रूप में निर्यात करें।
  2. Textmate में फ़ाइल खोलें (जो कि मेरे पास पहले से ही आसान था)।
  3. UPPERCASE डेटा के साथ पंक्तियों का चयन करें।
  4. "टेक्स्ट" मेनू से "कनवर्ट करें" चुनें, और "शीर्षक के लिए" चुनें।
  5. ढूँढें और उसके हर बदल देते हैं: सही लोअरकेस मूल्यों के साथ

    INSERT INTO `Table` (`Col1`, `Col2`, `Etc`, ...) VALUES 
    

  6. तालिका को वापस डेटाबेस में आयात करें।
  7. लोअरकेस होने वाले कॉलम के लिए लोअरकेस मान रीसेट करने के लिए UPDATE table SET colname=LOWER(colname); का उपयोग करें।

कारण मैं का उपयोग कर Textmate पहले था कि मैं समझ नहीं सकता कैसे अन्य डेटा को बर्बाद कर के बिना शीर्षक केस में एक एकल स्तंभ परिवर्तित करने के लिए, लेकिन यह विधि काम करने लगता है की कोशिश नहीं की। आपके मार्गदर्शन और समर्थन के लिए धन्यवाद!

0

ऐसे फ़ंक्शन को देखने का निश्चित मामला documentation में है।

दुर्भाग्यवश, आपके पास लोअर() और UPPER() फ़ंक्शन हैं, लेकिन कोई शीर्षक केस नहीं है। आपकी सबसे अच्छी शर्त आपके स्वयं के फ़ंक्शन को घोषित करना होगा जो रिक्त स्थान पर विभाजित होती है, आपके छोटे शब्दों को अनदेखा करती है, और प्रत्येक शेष शब्द के पहले अक्षर पर एक UPPER करता है।

0

उत्तर इस बात पर निर्भर करेगा कि कॉलम में किस प्रकार का डेटा है, यानी यह लोग नाम, स्थान के नाम, पुस्तक शीर्षक इत्यादि हैं। यदि आप SQL समाधान की तलाश में हैं, तो मैं इसे कई अपडेट में करूँगा उदाहरण के लिए:

  1. प्रारंभिक स्ट्रिंग है:
  2. टोपियां प्रारंभिक बदल "एक Mockingbird मारने के लिए": "मारने के लिए एक Mockingbird"
  3. को लोअर केस अगर वे शुरू नहीं करते हैं करने के लिए छोटे शब्द कन्वर्ट स्ट्रिंग: " एक मॉकिंगबर्ड को मारें"
+1

आप चरण 4 भूल गए हैं। और 5 .: 4. ??? 5. लाभ। चुटकुले चुटकुले; यह एक समझदार एल्गोरिदम है, लेकिन अंतर्निहित MySQL फ़ंक्शंस चरण 2 को पूरा कर सकता है? – rooskie

+0

कोई नहीं, ओपी को कुछ एसक्यूएल लिखना होगा। जिन बिंदुओं को मैं बनाने की कोशिश कर रहा था वे थे 1) "शीर्षक केस" डेटा के अर्थ को जानने के बिना अस्पष्ट है; और 2) यह कई चरणों में सबसे अच्छा किया जाता है। मैं बिंदु 1 के उत्तर को जानने के बिना एसक्यूएल लिखने में समय बिताने वाला नहीं हूं।होबोडेव का जवाब मुझे सही लगता है लेकिन कॉलम वांछित परिणाम नहीं देगा यदि कॉलम "फ्लैनेरी ओ'कोनर" जैसे नामों से भरा हुआ है। –

+1

@jamie: आपको आयरिश के लिए विशेष अपवाद करना होगा। :-) – hobodave

1

आप इसे concat(), substring(), और लंबाई() के साथ कर सकते हैं लेकिन मैं इसे केवल एक शब्द के लिए काम कर सकता हूं। क्या कोई विशिष्ट कारण है कि आप mysql के बजाय अपने एप्लिकेशन के कोड में ऐसा क्यों नहीं कर सकते हैं?

55

संपादित

यूरेका! सचमुच मेरा पहला एसक्यूएल फ़ंक्शन। कोई वारंटी की पेशकश नहीं की। उपयोग करने से पहले अपने डेटा का बैकअप लें। :)

पहले, निम्न समारोह को परिभाषित:

DROP FUNCTION IF EXISTS lowerword; 
SET GLOBAL log_bin_trust_function_creators=TRUE; 
DELIMITER | 
CREATE FUNCTION lowerword(str VARCHAR(128), word VARCHAR(5)) 
RETURNS VARCHAR(128) 
DETERMINISTIC 
BEGIN 
    DECLARE i INT DEFAULT 1; 
    DECLARE loc INT; 

    SET loc = LOCATE(CONCAT(word,' '), str, 2); 
    IF loc > 1 THEN 
    WHILE i <= LENGTH (str) AND loc <> 0 DO 
     SET str = INSERT(str,loc,LENGTH(word),LCASE(word)); 
     SET i = loc+LENGTH(word); 
     SET loc = LOCATE(CONCAT(word,' '), str, i); 
    END WHILE; 
    END IF; 
    RETURN str; 
END; 
| 
DELIMITER ; 

यह str में शब्द की सभी घटनाओं को कम कर देगी।

तो इस संशोधित उचित समारोह को परिभाषित:

DROP FUNCTION IF EXISTS tcase; 
SET GLOBAL log_bin_trust_function_creators=TRUE; 
DELIMITER | 
CREATE FUNCTION tcase(str VARCHAR(128)) 
RETURNS VARCHAR(128) 
DETERMINISTIC 
BEGIN 
    DECLARE c CHAR(1); 
    DECLARE s VARCHAR(128); 
    DECLARE i INT DEFAULT 1; 
    DECLARE bool INT DEFAULT 1; 
    DECLARE punct CHAR(17) DEFAULT '()[]{},[email protected];:?/'; 
    SET s = LCASE(str); 
    WHILE i <= LENGTH(str) DO 
    BEGIN 
     SET c = SUBSTRING(s, i, 1); 
     IF LOCATE(c, punct) > 0 THEN 
     SET bool = 1; 
     ELSEIF bool=1 THEN 
     BEGIN 
      IF c >= 'a' AND c <= 'z' THEN 
      BEGIN 
       SET s = CONCAT(LEFT(s,i-1),UCASE(c),SUBSTRING(s,i+1)); 
       SET bool = 0; 
      END; 
      ELSEIF c >= '0' AND c <= '9' THEN 
      SET bool = 0; 
      END IF; 
     END; 
     END IF; 
     SET i = i+1; 
    END; 
    END WHILE; 

    SET s = lowerword(s, 'A'); 
    SET s = lowerword(s, 'An'); 
    SET s = lowerword(s, 'And'); 
    SET s = lowerword(s, 'As'); 
    SET s = lowerword(s, 'At'); 
    SET s = lowerword(s, 'But'); 
    SET s = lowerword(s, 'By'); 
    SET s = lowerword(s, 'For'); 
    SET s = lowerword(s, 'If'); 
    SET s = lowerword(s, 'In'); 
    SET s = lowerword(s, 'Of'); 
    SET s = lowerword(s, 'On'); 
    SET s = lowerword(s, 'Or'); 
    SET s = lowerword(s, 'The'); 
    SET s = lowerword(s, 'To'); 
    SET s = lowerword(s, 'Via'); 

    RETURN s; 
END; 
| 
DELIMITER ; 

प्रयोग

सत्यापित करें यह उम्मीद के रूप में काम करता है:

SELECT tcase(title) FROM table; 

यह प्रयोग करें:

UPDATE table SET title = tcase(title); 

स्रोत: http://www.artfulsoftware.com/infotree/queries.php?&bw=1070#122

+0

इसके लिए धन्यवाद। मेरा दिन बचाया –

+0

बहुत बढ़िया काम - मुझे कुछ ऐसी चीज चाहिए जो उपयोगकर्ता परिभाषित शब्दकोष को संभालेगी, इसलिए मैंने जो सामान्य किया है उसे सामान्यीकृत किया है। – CurtainDog

+0

इसका उपयोग करते समय मुझे यह त्रुटि मिली: # 1305 - फ़ंक्शन तालिका_नाम.LENGTH मौजूद नहीं है। क्या मैं कुछ भूल रहा हूँ? –

8

आप मिश्रण मैं hobodave के जवाब सामान्यीकृत किया है में कस्टम acronyms और अन्य कस्टम पूंजीकरण पैटर्न फेंक की जरूरत है:

DELIMITER | 
CREATE FUNCTION replaceword(str VARCHAR(128), word VARCHAR(128)) 
RETURNS VARCHAR(128) 
DETERMINISTIC 
BEGIN 
    DECLARE loc INT; 
    DECLARE punct CHAR(27) DEFAULT '()[]{},[email protected];:?/''"#$%^&*<>'; 
    DECLARE lowerWord VARCHAR(128); 
    DECLARE lowerStr VARCHAR(128); 

    IF LENGTH(word) = 0 THEN 
    RETURN str; 
    END IF; 
    SET lowerWord = LOWER(word); 
    SET lowerStr = LOWER(str); 
    SET loc = LOCATE(lowerWord, lowerStr, 1); 
    WHILE loc > 0 DO 
    IF loc = 1 OR LOCATE(SUBSTRING(str, loc-1, 1), punct) > 0 THEN 
     IF loc+LENGTH(word) > LENGTH(str) OR LOCATE(SUBSTRING(str, loc+LENGTH(word), 1), punct) > 0 THEN 
     SET str = INSERT(str,loc,LENGTH(word),word); 
     END IF; 
    END IF; 
    SET loc = LOCATE(lowerWord, lowerStr, loc+LENGTH(word)); 
    END WHILE; 
    RETURN str; 
END; 
| 
DELIMITER ; 

DELIMITER | 
CREATE FUNCTION tcase(str VARCHAR(128)) 
RETURNS VARCHAR(128) 
DETERMINISTIC 
BEGIN 
    DECLARE c CHAR(1); 
    DECLARE s VARCHAR(128); 
    DECLARE i INT DEFAULT 1; 
    DECLARE bool INT DEFAULT 1; 
    DECLARE punct CHAR(27) DEFAULT '()[]{},[email protected];:?/''"#$%^&*<>'; 

    SET s = LCASE(str); 
    WHILE i <= LENGTH(str) DO 
    BEGIN 
     SET c = SUBSTRING(s, i, 1); 
     IF LOCATE(c, punct) > 0 THEN 
     SET bool = 1; 
     ELSEIF bool=1 THEN 
     BEGIN 
      IF c >= 'a' AND c <= 'z' THEN 
      BEGIN 
       SET s = CONCAT(LEFT(s,i-1),UCASE(c),SUBSTRING(s,i+1)); 
       SET bool = 0; 
      END; 
      ELSEIF c >= '0' AND c <= '9' THEN 
      SET bool = 0; 
      END IF; 
     END; 
     END IF; 
     SET i = i+1; 
    END; 
    END WHILE; 

    SET s = replaceword(s, 'a'); 
    SET s = replaceword(s, 'an'); 
    SET s = replaceword(s, 'and'); 
    SET s = replaceword(s, 'as'); 
    SET s = replaceword(s, 'at'); 
    SET s = replaceword(s, 'but'); 
    SET s = replaceword(s, 'by'); 
    SET s = replaceword(s, 'for'); 
    SET s = replaceword(s, 'if'); 
    SET s = replaceword(s, 'in'); 
    SET s = replaceword(s, 'n'); 
    SET s = replaceword(s, 'of'); 
    SET s = replaceword(s, 'on'); 
    SET s = replaceword(s, 'or'); 
    SET s = replaceword(s, 'the'); 
    SET s = replaceword(s, 'to'); 
    SET s = replaceword(s, 'via'); 

    SET s = replaceword(s, 'RSS'); 
    SET s = replaceword(s, 'URL'); 
    SET s = replaceword(s, 'PHP'); 
    SET s = replaceword(s, 'SQL'); 
    SET s = replaceword(s, 'OPML'); 
    SET s = replaceword(s, 'DHTML'); 
    SET s = replaceword(s, 'CSV'); 
    SET s = replaceword(s, 'iCal'); 
    SET s = replaceword(s, 'XML'); 
    SET s = replaceword(s, 'PDF'); 

    SET c = SUBSTRING(s, 1, 1); 
    IF c >= 'a' AND c <= 'z' THEN 
     SET s = CONCAT(UCASE(c),SUBSTRING(s,2)); 
    END IF; 

    RETURN s; 
END; 
| 
DELIMITER ; 

मूलतः यह समारोह की जगह एक केस-संवेदी शब्द के होते हैं और एक समारोह फायदा उठाने में प्रत्येक शब्द का पहला अक्षर और विशिष्ट शब्दों के लिए कुछ परिवर्तन करता है।

उम्मीद है कि यह किसी के लिए सहायक होगा। इस तरह

8

उम्म कुछ काम कर सकते हैं

UPDATE table_name SET `col_name`= CONCAT(UPPER(SUBSTRING(`col_name`, 1, 1)) , LOWER(SUBSTRING(`col_name` FROM 2))); 
+1

इस समाधान के साथ समस्या केवल फ़ील्ड मान का पहला अक्षर अपरकेस होगा। अन्य शब्द लोअरकेस बने रहेंगे। –

+0

आप इसे कैसे बदल सकते हैं ताकि यह अन्य शब्दों को उचित रूप से तैयार कर सके? – NuWin

1

मेरे लिए यह एक काम करता है।

UPDATE `suburbs` 
SET title2 = CONCAT_WS(' ', 
CONCAT(UPPER(LEFT(SUBSTRING_INDEX(title, ' ',1),1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',1),2))), 
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',2),LENGTH(SUBSTRING_INDEX(title, ' ',1)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',2),3 + LENGTH(SUBSTRING_INDEX(title, ' ',1))))), 
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',3),LENGTH(SUBSTRING_INDEX(title, ' ',2)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',3),3 + LENGTH(SUBSTRING_INDEX(title, ' ',2))))), 
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',4),LENGTH(SUBSTRING_INDEX(title, ' ',3)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',4),3 + LENGTH(SUBSTRING_INDEX(title, ' ',3))))), 
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',5),LENGTH(SUBSTRING_INDEX(title, ' ',4)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',5),3 + LENGTH(SUBSTRING_INDEX(title, ' ',4))))), 
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',6),LENGTH(SUBSTRING_INDEX(title, ' ',5)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',6),3 + LENGTH(SUBSTRING_INDEX(title, ' ',5))))), 
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',7),LENGTH(SUBSTRING_INDEX(title, ' ',6)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',7),3 + LENGTH(SUBSTRING_INDEX(title, ' ',6))))), 
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',8),LENGTH(SUBSTRING_INDEX(title, ' ',7)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',8),3 + LENGTH(SUBSTRING_INDEX(title, ' ',7))))), 
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',9),LENGTH(SUBSTRING_INDEX(title, ' ',8)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',9),3 + LENGTH(SUBSTRING_INDEX(title, ' ',8))))), 
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',10),LENGTH(SUBSTRING_INDEX(title, ' ',9)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',10),3 + LENGTH(SUBSTRING_INDEX(title, ' ',9))))), 
CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',11),LENGTH(SUBSTRING_INDEX(title, ' ',10)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',11),3 + LENGTH(SUBSTRING_INDEX(title, ' ',10)))))) 
WHERE 1 
3

सरल उचित मामले के लिए मेरे समाधान:

CREATE FUNCTION `proper_case`(str varchar(128)) RETURNS varchar(128) 
BEGIN 
DECLARE n, pos INT DEFAULT 1; 
DECLARE sub, proper VARCHAR(128) DEFAULT ''; 

if length(trim(str)) > 0 then 
    WHILE pos > 0 DO 
     set pos = locate(' ',trim(str),n); 
     if pos = 0 then 
      set sub = lower(trim(substr(trim(str),n))); 
     else 
      set sub = lower(trim(substr(trim(str),n,pos-n))); 
     end if; 

     set proper = concat_ws(' ', proper, concat(upper(left(sub,1)),substr(sub,2))); 
     set n = pos + 1; 
    END WHILE; 
end if; 

RETURN trim(proper); 
END 

के रूप में यह प्रयोग करें:

SELECT proper_case("JOHN DOE"); 

आउटपुट:

John Doe 
+0

एक और समान कार्य - https://stackoverflow.com/a/33561905/4050261 –

2

मैं इस

की तरह कुछ के लिए इस्तेमाल किया
UPDATE `tablename` 
SET `fieldname` = CONCAT(UCASE(SUBSTRING(`fieldname`,1,1)),'', LCASE(SUBSTRING(`fieldname`,2,LENGTH(`fieldname`)))) 

नोट: यह केवल पहले वर्ण को अपरकेस में परिवर्तित करेगा। और लोअरकेस के लिए शेष मूल्य।

+0

मैं क्वेरी को कैसे संपादित कर सकता हूं ताकि यह उचित केस बना सके? – NuWin

1

यह मेरे लिए काम कर रहा है मेरे एसक्यूएल 5,0

 DELIMITER | 
     CREATE FUNCTION CamelCase(str VARCHAR(8000)) 
     RETURNS VARCHAR(8000) 
      BEGIN 
      DECLARE result VARCHAR(8000); 
      SET str = CONCAT(' ',str,' '); 
      SET result = ''; 
      WHILE LENGTH(str) > 1 DO 
       SET str = SUBSTR(str,INSTR(str,' ')+1,LENGTH(str)); 
       SET result = CONCAT(result,UPPER(LEFT(str,1)), LOWER(SUBSTR(str,2,INSTR(str,' ') - 1))) ; 
       SET str = SUBSTR(str,INSTR(str,' '),LENGTH(str)); 
      END WHILE; 
     RETURN result; 
     END 
    | 
    DELIMITER ; 
संबंधित मुद्दे

 संबंधित मुद्दे