programing

선행 또는 후행 공백을 포함하는 MySQL 선택 필드

telebox 2023. 9. 19. 20:59
반응형

선행 또는 후행 공백을 포함하는 MySQL 선택 필드

MySQL을 사용할 수 있습니다.TRIM()선행 또는 후행 공백이 포함된 필드를 다음과 같이 정리하는 방법UPDATE다음과 같습니다.

UPDATE Foo SET field = TRIM(field);

이 작업이 실행되기 전에 영향을 미칠 필드를 실제로 보고 싶습니다.시도했지만 0개의 결과를 반환합니다.

SELECT * FROM Foo WHERE field != TRIM(field);

이것은 효과가 있을 것 같지만 효과가 없습니다.

해결책이 있는 사람?그리고 왜 안 되는지 궁금하군요...

다음유형 아래에 문서화된 대로:

MySQL 콜렉션은 모두 유형입니다.PADSPACE. 이것은 모든 것이CHAR그리고.VARCHARMySQL의 값은 후행 공백에 관계없이 비교됩니다.

조작자의 정의에서 설명서는 다음과 같이 설명합니다.

특히 후행 공간은 유의하며, 이는 연산자와 수행된 비교의 경우에는 해당되지 않습니다.

이 답변에 언급된 바와 같이:

이 동작은 SQL-92 및 SQL:2008에 지정되어 있습니다.비교를 위해 짧은 줄은 긴 줄의 길이에 맞춰 추가됩니다.

초안(8.2 <비교 술어>)에서:

X 문자의 길이가 Y 문자의 길이와 동일하지 않으면 비교를 위해 더 짧은 문자열이 효과적으로 대체되고, 하나 이상의 패드 문자의 오른쪽에 연결되어 더 긴 문자열의 길이로 확장된 자신의 복사본이 CS를 기반으로 패드 문자가 선택됩니다.만약 CS가 NO PAD 특성을 가지고 있다면, 패드 문자는 CS 아래의 어떤 문자열보다 더 적게 수집되는 X와 Y의 문자 집합의 어떤 문자와도 다른 구현 의존적인 문자입니다.그렇지 않으면 패드 문자는 <공간>입니다.

하나의 해결책:

SELECT * FROM Foo WHERE CHAR_LENGTH(field) != CHAR_LENGTH(TRIM(field))
SELECT *
FROM 
    `foo`
WHERE 
   (name LIKE ' %')
OR 
   (name LIKE '% ')

RegEx의 예는 다음과 같습니다.

SELECT *
FROM 
    `foo`
WHERE 
   (name REGEXP '(^[[:space:]]|[[:space:]]$)')

또 다른 해결책은 사용할 수 있습니다.IN문자열의 마지막 문자와 첫 번째 문자를 공백 문자 목록과 비교...

(SUBSTRING(@s,  1, 1) IN (' ', '\t', '\n', '\r') OR SUBSTRING(@s, -1, 1) IN (' ', '\t', '\n', '\r'))

...어디에@s는 임의의 입력 문자열입니다.필요에 따라 비교 목록에 공백 문자를 추가합니다.

다음은 식이 다양한 문자열 입력에서 어떻게 동작하는지 보여주는 간단한 테스트입니다.

SET @s_normal = 'x';
SET @s_ws_leading = '\tx';
SET @s_ws_trailing = 'x ';
SET @s_ws_both = '\rx ';

SELECT
    NOT(SUBSTRING(@s_normal,      1, 1) IN (' ', '\t', '\n', '\r') OR SUBSTRING(@s_normal,     -1, 1) IN (' ', '\t', '\n', '\r')) test_normal      #=> 1 (PASS)
  ,    (SUBSTRING(@s_ws_leading,  1, 1) IN (' ', '\t', '\n', '\r') OR SUBSTRING(@s_ws_leading, -1, 1) IN (' ', '\t', '\n', '\r')) test_ws_leading  #=> 1 (PASS)
  ,    (SUBSTRING(@s_ws_trailing, 1, 1) IN (' ', '\t', '\n', '\r') OR SUBSTRING(@s_ws_trailing,-1, 1) IN (' ', '\t', '\n', '\r')) test_ws_trailing #=> 1 (PASS)
  ,    (SUBSTRING(@s_ws_both,     1, 1) IN (' ', '\t', '\n', '\r') OR SUBSTRING(@s_ws_both,    -1, 1) IN (' ', '\t', '\n', '\r')) test_ws_both     #=> 1 (PASS)
;

이 작업을 많이 수행할 경우 이에 대한 기능을 만들 수도 있습니다.

DROP FUNCTION IF EXISTS has_leading_or_trailing_whitespace;

CREATE FUNCTION has_leading_or_trailing_whitespace(s VARCHAR(2000))
  RETURNS BOOLEAN
  DETERMINISTIC
RETURN (SUBSTRING(s, 1, 1) IN (' ', '\t', '\n', '\r') OR SUBSTRING(s, -1, 1) IN (' ', '\t', '\n', '\r'))
;

# test
SELECT
    NOT(has_leading_or_trailing_whitespace(@s_normal     )) #=> 1 (PASS)
  ,     has_leading_or_trailing_whitespace(@s_ws_leading )  #=> 1 (PASS)
  ,     has_leading_or_trailing_whitespace(@s_ws_trailing)  #=> 1 (PASS)
  ,     has_leading_or_trailing_whitespace(@s_ws_both    )  #=> 1 (PASS)
;

언급URL : https://stackoverflow.com/questions/16724574/mysql-select-fields-containing-leading-or-trailing-whitespace

반응형