هل هناك طريقة بسيطة لتحويل بيانات MySQL إلى حالة العنوان؟

StackOverflow https://stackoverflow.com/questions/1191605

  •  19-09-2019
  •  | 
  •  

سؤال

لدي جدول MySQL حيث تم إدخال جميع البيانات الموجودة في عمود واحد في أحرف كبيرة، لكنني بحاجة إلى تحويل إلى حالة العنوان، مع التعرف على "الكلمات الصغيرة" أقرب إلى جريء كرة نارية العنوان سيناريو.

وجدت هذا الحل الممتاز لتحويل السلاسل إلى أحرف صغيرة، ولكن يبدو أن وظيفة حالة العنوان قد تم استبعادها من الإصدار الخاص بي من MySQL. هل هناك طريقة أنيقة للقيام بذلك؟

هل كانت مفيدة؟

المحلول 7

وو! أنا لست مفيدا مع SQL على الإطلاق؛ إليك الطريقة التي عملت بالنسبة لي:

  1. تصدير الجدول كملف نصي بتنسيق .sql.
  2. افتح الملف TextMate. (الذي كان لدي بالفعل مفيد).
  3. حدد الصفوف ذات البيانات الكبيرة.
  4. اختر "تحويل" من قائمة "النص"، وحدد "to titlecase".
  5. ابحث واستبدل كل مثيل:

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

    مع القيم الصغيرة الصحيحة.

  6. استيراد الجدول مرة أخرى إلى قاعدة البيانات.
  7. يستخدم UPDATE table SET colname=LOWER(colname); لإعادة ضبط القيم الصغيرة للأعمدة التي يجب أن تكون صغيرة.

السبب في أنني لم أحاول استخدام STORMATE من قبل كان أنه لم أستطع معرفة كيفية تحويل عمود واحد إلى حالة العنوان دون تدمير البيانات الأخرى، ولكن يبدو أن هذه الطريقة تعمل. شكرا لتوجيهاتك ودعمكم!

نصائح أخرى

يحرر

Eureka! حرفيا وظيفة SQL الأولى. لا يوجد ضمان عرض. نسخ احتياطي بياناتك قبل الاستخدام. :)

أولا، حدد الوظيفة التالية:

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 ' ()[]{},.-_!@;:?/'; 
  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.

أم شيء مثل هذا قد يعمل

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

إذا كنت بحاجة إلى رمي المختصرات المخصصة وأنماط رسملة مخصصة أخرى في المزيج لقد قمت بإجابة HoboDave المعممة:

DELIMITER |
CREATE FUNCTION replaceword( str VARCHAR(128), word VARCHAR(128) )
RETURNS VARCHAR(128)
DETERMINISTIC
BEGIN
  DECLARE loc INT;
  DECLARE punct CHAR(27) DEFAULT ' ()[]{},.-_!@;:?/''"#$%^&*<>'; 
  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 ' ()[]{},.-_!@;:?/''"#$%^&*<>'; 

  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 ;

أساسا يتكون من وظيفة استبدال كلمة غير حساسة لحالة الأحرف ووظيفة لاستفادة الحرف الأول من كل كلمة وأداء بعض التحويلات للحصول على كلمات محددة.

نأمل أن مفيدة لشخص ما.

حلا بلدي لحالة بسيطة مناسبة:

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

اعتدت شيئا كهذا

UPDATE `tablename` 
SET `fieldname` =  CONCAT(UCASE(SUBSTRING(`fieldname`,1,1)),'', LCASE(SUBSTRING(`fieldname`,2,LENGTH(`fieldname`)))) 

ملاحظة: سيحول ذلك فقط الحرف الأول إلى أحرف كبيرة. وبقية القيمة إلى أحرف صغيرة.

يمكنك القيام بذلك مع ConcAT () والفرشاة () والطول () ولكن يمكنني فقط أن أرى أنها تعمل من أجل كلمة واحدة. هل هناك سبب محدد لماذا لا يمكنك القيام بذلك في رمز التطبيق الخاص بك، بدلا من MySQL؟

هذا واحد يعمل بالنسبة لي.

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

هذا يعمل بالنسبة لي في بلدي SQL 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 ;

الحالة النهائية للبحث عن هذه الوظيفة موجودة في توثيق.

لسوء الحظ، لديك وظائف أقل () وعلوي ()، ولكن لا توجد حالة عنوان. أفضل رهان سيكون هو إعلان وظيفتك الخاصة بالانشقاقات على المسافات، وتجاهل كلماتك الصغيرة، وتجاهل العلوي الموجود في الطابع الأول لكل كلمة المتبقية.

الجواب سوف يعتمد على نوع البيانات في العمود، أي أسماء الناس، وأسماء وضع، وألقاب الكتب، وما إلى ذلك. إذا كنت تبحث عن محلول SQL، فسأفعل ذلك في تحديثات متعددة، على سبيل المثال:

  1. السلسلة الأولية هي: "لقتل mockingbird"
  2. تحويل إلى قبعات أولية: "لقتل MockingBird"
  3. تحويل الكلمات الصغيرة إلى الحالة الصغيرة إذا لم تبدأ السلسلة: "لقتل MockingBird"
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top