MySQL에서 대소문자를 구분하지 않는 REPLACE?
MySQL은 기본 정렬에서 거의 모든 문자열 비교를 실행합니다...을 제외하고REPLACE
지휘권대/소문자를 구분하지 않는 데이터 정렬이 있으므로 대/소문자를 구분하지 않고REPLACE
강제로 할 수 있는 방법이 있습니까?REPLACE
항상 대/소문자를 구분하는 비교를 수행하는 것이 아니라 현재의 대조를 사용하는 것입니까?MySQL(현재 5.1 실행 중)을 업그레이드하여 추가 기능을 사용할 수 있습니다...
mysql> charset utf8 collation utf8_unicode_ci;
Charset changed
mysql> select 'abc' like '%B%';
+------------------+
| 'abc' like '%B%' |
+------------------+
| 1 |
+------------------+
mysql> select replace('aAbBcC', 'a', 'f');
+-----------------------------+
| replace('aAbBcC', 'a', 'f') |
+-----------------------------+
| fAbBcC | <--- *NOT* 'ffbBcC'
+-----------------------------+
한다면replace(lower())
작동하지 않습니다. 다른 기능을 만들어야 합니다.
내 2센트.
많은 사람들이 MySQL에서 MariaDB로 이주했기 때문에, 그 사람들은 다음과 같은 새로운 기능을 사용할 수 있을 것입니다.REGEXP_REPLACE
일반적으로 대체하는 것처럼 사용하지만 패턴은 정규식입니다.
다음은 작동 예입니다.
UPDATE `myTable`
SET `myField` = REGEXP_REPLACE(`myField`, '(?i)my insensitive string', 'new string')
WHERE `myField` REGEXP '(?i)my insensitive string'
옵션(?i)
이후의 모든 일치 항목은 대소문자를 구분하지 않습니다(나처럼 패턴의 시작 부분에 놓이면 모든 일치 항목이 구분하지 않습니다).
자세한 내용은 여기를 참조하십시오. https://mariadb.com/kb/en/mariadb/pcre/
편집: MySQL 8.0부터 이제 사용할 수 있습니다.regexp_replace
기능도 마찬가지입니다. 설명서 참조: https://dev.mysql.com/doc/refman/8.0/en/regexp.html
fvox에서 말하는 것에 대한 대체 기능.
DELIMITER |
CREATE FUNCTION case_insensitive_replace ( REPLACE_WHERE text, REPLACE_THIS text, REPLACE_WITH text )
RETURNS text
DETERMINISTIC
BEGIN
DECLARE last_occurency int DEFAULT '1';
IF LCASE(REPLACE_THIS) = LCASE(REPLACE_WITH) OR LENGTH(REPLACE_THIS) < 1 THEN
RETURN REPLACE_WHERE;
END IF;
WHILE Locate( LCASE(REPLACE_THIS), LCASE(REPLACE_WHERE), last_occurency ) > 0 DO
BEGIN
SET last_occurency = Locate(LCASE(REPLACE_THIS), LCASE(REPLACE_WHERE));
SET REPLACE_WHERE = Insert( REPLACE_WHERE, last_occurency, LENGTH(REPLACE_THIS), REPLACE_WITH);
SET last_occurency = last_occurency + LENGTH(REPLACE_WITH);
END;
END WHILE;
RETURN REPLACE_WHERE;
END;
|
DELIMITER ;
소규모 테스트:
SET @str = BINARY 'New York';
SELECT case_insensitive_replace(@str, 'y', 'K');
답변:New Kork
Luist의 답변을 수정하면 바늘을 케이스가 다른 버전의 바늘로 교체할 수 있습니다(두 줄이 변경됨).
DELIMITER |
CREATE FUNCTION case_insensitive_replace ( REPLACE_WHERE text, REPLACE_THIS text, REPLACE_WITH text )
RETURNS text
DETERMINISTIC
BEGIN
DECLARE last_occurency int DEFAULT '1';
IF LENGTH(REPLACE_THIS) < 1 THEN
RETURN REPLACE_WHERE;
END IF;
WHILE Locate( LCASE(REPLACE_THIS), LCASE(REPLACE_WHERE), last_occurency ) > 0 DO
BEGIN
SET last_occurency = Locate(LCASE(REPLACE_THIS), LCASE(REPLACE_WHERE), last_occurency);
SET REPLACE_WHERE = Insert( REPLACE_WHERE, last_occurency, LENGTH(REPLACE_THIS), REPLACE_WITH);
SET last_occurency = last_occurency + LENGTH(REPLACE_WITH);
END;
END WHILE;
RETURN REPLACE_WHERE;
END;
|
DELIMITER ;
저는 대/소문자 구분 대체를 통해 대/소문자 구분 없이 검색을 수행하는 http://pento.net/2009/02/15/case-insensitive-replace-for-mysql/ (infvox's answer)과 함께 갔습니다. 검색 문자열의 다른 곳에서 영향을 받지 않는 문자가 무엇인지에 대한 대/소문자를 변경하지 않습니다.
N.B. 같은 페이지에서 CHAR(255)를 VARCHAR(255)로 변경해야 한다는 의견을 추가로 제시했습니다. 이것은 저에게도 필요한 것으로 보입니다.
이전 답변 및 pento.net 링크에서 다음과 같은 주장을 펼칩니다.LOCATE()
소문자입니다.
LOCATE는 기본적으로 대소문자를 구분하지 않으므로 리소스 낭비입니다.
mysql> select locate('el', 'HELLo');
+-----------------------+
| locate('el', 'HELLo') |
+-----------------------+
| 2 |
+-----------------------+
대체할 수 있습니다.
WHILE Locate( LCASE(REPLACE_THIS), LCASE(REPLACE_WHERE), last_occurency ) > 0 DO
와 함께
WHILE Locate(REPLACE_THIS, REPLACE_WHERE, last_occurency ) > 0 DO
기타.
'특수' 문자의 경우 예상치 못한 동작이 발생합니다.
SELECT case_insensitive_replace('A', 'Ã', 'a')
기브즈
a
예상치 못한 일이...우리는 A가 아닌 ã만 교체하기를 원하기 때문에.
더 이상한 것은:
SELECT LOCATE('Ã', 'A');
기브즈
0
정확한 결과는...저장된 절차의 매개변수를 인코딩하는 것과 관련이 있는 것 같습니다
저는 원래의 검색 문자열이나 검색 문자열의 경우를 걱정하지 않고 교체해야 할 때 만든 검색 및 교체 기능을 사용하는 것을 좋아합니다.수신 문자열을 변경하지 않고 빈/null 검색 문자열이나 null 대체 문자열을 전달하면 이 루틴이 빠르게 실행됩니다.검색이 계속 반복될 경우를 대비해 안전 카운트 다운도 추가했습니다.이렇게 하면 우리는 영원히 고리에 갇히지 않습니다.너무 낮다고 생각되면 시작 번호를 변경합니다.
delimiter //
DROP FUNCTION IF EXISTS `replace_nocase`//
CREATE FUNCTION `replace_nocase`(raw text, find_str varchar(1000), replace_str varchar(1000)) RETURNS text
CHARACTER SET utf8
DETERMINISTIC
BEGIN
declare ret text;
declare len int;
declare hit int;
declare safe int;
if find_str is null or find_str='' or replace_str is null then
return raw;
end if;
set safe=10000;
set ret=raw;
set len=length(find_str);
set hit=LOCATE(find_str,ret);
while hit>0 and safe>0 do
set ret=concat(substring(ret,1,hit-1),replace_str,substring(ret,hit+len));
set hit=LOCATE(find_str,ret,hit+1);
set safe=safe-1;
end while;
return ret;
END//
이 질문은 조금 오래된 것이지만 저는 같은 문제에 부딪혔고 주어진 답들은 제가 그것을 완전히 풀 수 있도록 허락하지 않았습니다.
저는 그 결과가 원래 문자열의 케이스를 유지하기를 원했습니다.
그래서 나는 약간의 수정을 했습니다.replace_ci
에 의해제안된 :fvox는 다음과 .
DELIMITER $$
DROP FUNCTION IF EXISTS `replace_ci`$$
CREATE FUNCTION `replace_ci` (str TEXT, needle CHAR(255), str_rep CHAR(255))
RETURNS TEXT
DETERMINISTIC
BEGIN
DECLARE return_str TEXT DEFAULT '';
DECLARE lower_str TEXT;
DECLARE lower_needle TEXT;
DECLARE tmp_needle TEXT;
DECLARE str_origin_char CHAR(1);
DECLARE str_rep_char CHAR(1);
DECLARE final_str_rep TEXT DEFAULT '';
DECLARE pos INT DEFAULT 1;
DECLARE old_pos INT DEFAULT 1;
DECLARE needle_pos INT DEFAULT 1;
IF needle = '' THEN
RETURN str;
END IF;
SELECT LOWER(str) INTO lower_str;
SELECT LOWER(needle) INTO lower_needle;
SELECT LOCATE(lower_needle, lower_str, pos) INTO pos;
WHILE pos > 0 DO
SELECT substr(str, pos, char_length(needle)) INTO tmp_needle;
SELECT '' INTO final_str_rep;
SELECT 1 INTO needle_pos;
WHILE needle_pos <= char_length(tmp_needle) DO
SELECT substr(tmp_needle, needle_pos, 1) INTO str_origin_char;
SELECT SUBSTR(str_rep, needle_pos, 1) INTO str_rep_char;
SELECT CONCAT(final_str_rep, IF(BINARY str_origin_char = LOWER(str_origin_char), LOWER(str_rep_char), IF(BINARY str_origin_char = UPPER(str_origin_char), UPPER(str_rep_char), str_rep_char))) INTO final_str_rep;
SELECT (needle_pos + 1) INTO needle_pos;
END WHILE;
SELECT CONCAT(return_str, SUBSTR(str, old_pos, pos - old_pos), final_str_rep) INTO return_str;
SELECT pos + CHAR_LENGTH(needle) INTO pos;
SELECT pos INTO old_pos;
SELECT LOCATE(lower_needle, lower_str, pos) INTO pos;
END WHILE;
SELECT CONCAT(return_str, SUBSTR(str, old_pos, CHAR_LENGTH(str))) INTO return_str;
RETURN return_str;
END$$
DELIMITER ;
사용 예:
SELECT replace_ci( 'MySQL', 'm', 'e' ) as replaced;
반환 예정: | 대체됨 | | --- | EySQL |
언급URL : https://stackoverflow.com/questions/5656056/case-insensitive-replace-in-mysql
'programing' 카테고리의 다른 글
asp.net 에서 "Access-Control-Allow-Origin" 헤더를 구현하는 방법 (0) | 2023.09.03 |
---|---|
Android Studio - 인터넷이 연결되지 않은 Android Emulator WiFi (0) | 2023.08.29 |
봄 트랜잭션 필수 대 REQUESTERS_NEW : 롤백 트랜잭션 (0) | 2023.08.29 |
"2" 인수를 사용하여 "DownloadFile"을 호출하는 중 예외 발생: "WebClient 요청 중에 예외가 발생했습니다." (0) | 2023.08.29 |
배열의 모든 구성원을 영숫자로 전환하는 가장 빠른 방법은 무엇입니까? (0) | 2023.08.29 |