هل هناك طريقة بسيطة لتحويل بيانات MySQL إلى حالة العنوان؟
-
19-09-2019 - |
سؤال
لدي جدول MySQL حيث تم إدخال جميع البيانات الموجودة في عمود واحد في أحرف كبيرة، لكنني بحاجة إلى تحويل إلى حالة العنوان، مع التعرف على "الكلمات الصغيرة" أقرب إلى جريء كرة نارية العنوان سيناريو.
وجدت هذا الحل الممتاز لتحويل السلاسل إلى أحرف صغيرة، ولكن يبدو أن وظيفة حالة العنوان قد تم استبعادها من الإصدار الخاص بي من MySQL. هل هناك طريقة أنيقة للقيام بذلك؟
المحلول 7
وو! أنا لست مفيدا مع SQL على الإطلاق؛ إليك الطريقة التي عملت بالنسبة لي:
- تصدير الجدول كملف نصي بتنسيق .sql.
- افتح الملف TextMate. (الذي كان لدي بالفعل مفيد).
- حدد الصفوف ذات البيانات الكبيرة.
- اختر "تحويل" من قائمة "النص"، وحدد "to titlecase".
ابحث واستبدل كل مثيل:
INSERT INTO `Table` (`Col1`, `Col2`, `Etc`, ...) VALUES
مع القيم الصغيرة الصحيحة.
- استيراد الجدول مرة أخرى إلى قاعدة البيانات.
- يستخدم
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، فسأفعل ذلك في تحديثات متعددة، على سبيل المثال:
- السلسلة الأولية هي: "لقتل mockingbird"
- تحويل إلى قبعات أولية: "لقتل MockingBird"
- تحويل الكلمات الصغيرة إلى الحالة الصغيرة إذا لم تبدأ السلسلة: "لقتل MockingBird"