LIKE 연산자는 MSSQL Server에서 대소 문자를 구분합니까?


99

에서 에서 LIKE 연산자에 대한 설명서 , 아무것도 그것의 대소 문자 구분에 대해 이야기하지 않습니다. 맞나요? 활성화 / 비활성화하는 방법은 무엇입니까?

varchar(n)중요한 경우 Microsoft SQL Server 2005 설치에서 열을 쿼리하고 있습니다.


14
열 (또는 데이터베이스)의 데이터 정렬에 따라 다릅니다. 이 경우 민감한 경우 LIKE가 아니라면 다음, 대소 문자를 구분 LIKE하지 않습니다
Lamak

SQL-Server 데이터 정렬에 대한 설명서를 확인하십시오. msdn.microsoft.com/en-us/library/ms144250%28v=sql.105%29.aspx
GarethD

당신의 목표는 무엇입니까? 대소 문자를 구분 하시겠습니까, 아니면 대소 문자를 구분하지 않겠습니까?
Aaron Bertrand

1
대소 문자 구분은 기본적으로 데이터베이스에있는 열의 데이터 정렬로 설정됩니다. 대부분 반올림됩니다. 어느 방향으로 가고 싶습니까?
Tony Hopkinson 2013

답변:


101

대소 문자를 구분하는 연산자가 아니라 열 자체입니다.

SQL Server 설치가 수행되면 인스턴스에 대한 기본 데이터 정렬이 선택됩니다. 달리 명시 적으로 언급하지 않는 한 (아래 collate 절 확인) 새 데이터베이스가 생성되면 인스턴스에서 데이터 정렬을 상속하고 새 열이 생성 될 때 자신이 속한 데이터베이스에서 데이터 정렬을 상속합니다.

같은 데이터 정렬 sql_latin1_general_cp1_ci_as은 열의 내용을 처리하는 방법을 나타냅니다. CI는 대소 문자를 구분하지 않고 AS는 악센트 구분을 의미합니다.

전체 데이터 정렬 목록은 https://msdn.microsoft.com/en-us/library/ms144250(v=sql.105).aspx 에서 확인할 수 있습니다.

(a) 인스턴스 데이터 정렬을 확인하려면

select serverproperty('collation')

(b) 데이터베이스 데이터 정렬을 확인하려면

select databasepropertyex('databasename', 'collation') sqlcollation

(c) 다른 데이터 정렬을 사용하여 데이터베이스를 만들려면

create database exampledatabase
collate sql_latin1_general_cp1_cs_as 

(d) 다른 데이터 정렬을 사용하여 열을 만들려면

create table exampletable (
    examplecolumn varchar(10) collate sql_latin1_general_cp1_ci_as null
)

(e) 열 데이터 정렬을 수정하려면

alter table exampletable
alter column examplecolumn varchar(10) collate sql_latin1_general_cp1_ci_as null

인스턴스 및 데이터베이스 데이터 정렬을 변경할 수 있지만 이전에 만든 개체에는 영향을주지 않습니다.

문자열 비교를 위해 즉시 열 데이터 정렬을 변경할 수도 있지만 비용이 많이 들기 때문에 프로덕션 환경에서는 권장하지 않습니다.

select
  column1 collate sql_latin1_general_cp1_ci_as as column1
from table1

5
같은 문자 범위 [A-Z]는 항상 대소 문자를 구분하지 않는 것 같습니다 . [ABCDEFGHIJKLMNOPQRSŠTUVWXYZŽÅÄÖ]그러나 대조를 따르는 것 같습니다.
jumxozizi

1
: 또한,이 같은 뭔가 특정 컬럼의 경우 감도를 조회 할 수 있습니다select COLLATION_NAME, iif(cast(COLLATIONPROPERTY(COLLATION_NAME, 'ComparisonStyle') as int) & 1 = 0, 'case sensitive', 'case insensitive') from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'exampletable' and COLUMN_NAME = 'examplecolumn'
Jeppe의 Stig 닐슨

@jumxozizi 답변에 귀하의 제안을 추가했습니다.
John Zabroski

@JeppeStigNielsen 답변에 귀하의 제안을 추가했습니다.
John Zabroski

18

데이터 정렬에 대한이 모든 이야기는 다소 복잡해 보입니다. 다음과 같은 것을 사용하지 않는 이유는 무엇입니까?

IF UPPER(@@VERSION) NOT LIKE '%AZURE%'

그런 다음 검사는 데이터 정렬에 관계없이 대소 문자를 구분하지 않습니다.


10
이것은 srgable이 아니기 때문입니다. 이 예에서는 변수와 선행 와일드 카드를 사용합니다. 그러나 대소 문자를 구분하지 않는 데이터 정렬로 인덱싱 된 열에 대해 인덱스를 like 'a%'사용할 upper수 있지만 버전은 사용할 수 없습니다.
Martin Smith

3
문제는 like연산자가 대소 문자를 구분 하는지 여부였습니다 .
jumxozizi

데이터 정렬을 알아야합니다. 그렇지 않으면이 작업이 무의미해질 수 있습니다. 예를 들어 쿼리중인 열이를 사용 Latin1_General_CI_AS하는 경우 수행 UPPER(@@VALUE) NOT LIKE '%SOMETHING%'하거나 @@COLUMN NOT LIKE '%SOMETHING%'관련이없는 경우 결과는 동일합니다.
rsenna

13

테이블을 정의 할 때 데이터 정렬 순서 를 정의 할 수있는 옵션이 있습니다. 대소 문자를 구분하는 순서를 정의하면 LIKE연산자는 대소 문자를 구분하는 방식으로 작동합니다. 대소 문자를 구분하지 않는 조합 순서를 정의하면 LIKE연산자는 대소 문자도 무시합니다.

CREATE TABLE Test (
    CI_Str VARCHAR(15) COLLATE Latin1_General_CI_AS -- Case-insensitive
,   CS_Str VARCHAR(15) COLLATE Latin1_General_CS_AS -- Case-sensitive
);

다음은 sqlfiddle에 대한 빠른 데모 입니다 LIKE..


12

열 / 데이터베이스 / 서버의 데이터 정렬을 변경하지 않고 대 / 소문자 구분 검색을 수행하려면 항상 COLLATE절을 사용할 수 있습니다.

USE tempdb;
GO
CREATE TABLE dbo.foo(bar VARCHAR(32) COLLATE Latin1_General_CS_AS);
GO
INSERT dbo.foo VALUES('John'),('john');
GO
SELECT bar FROM dbo.foo 
  WHERE bar LIKE 'j%';
-- 1 row

SELECT bar FROM dbo.foo 
  WHERE bar COLLATE Latin1_General_CI_AS LIKE 'j%';
-- 2 rows

GO    
DROP TABLE dbo.foo;

다른 방식으로도 작동합니다. 열 / 데이터베이스 / 서버가 대소 문자를 구분하고 대소 문자를 구분하는 검색을 원하지 않는 경우, 예를 들어

USE tempdb;
GO
CREATE TABLE dbo.foo(bar VARCHAR(32) COLLATE Latin1_General_CI_AS);
GO
INSERT dbo.foo VALUES('John'),('john');
GO
SELECT bar FROM dbo.foo 
  WHERE bar LIKE 'j%';
-- 2 rows

SELECT bar FROM dbo.foo 
  WHERE bar COLLATE Latin1_General_CS_AS LIKE 'j%';
-- 1 row

GO
DROP TABLE dbo.foo;

마지막 쿼리를 사용 WHERE bar COLLATE Latin1_General_CS_AS LIKE '[j-k]%'하면 John이 데이터 정렬 대문자 J가 소문자 j와 소문자 사이에있는 것처럼 반환 됩니다 k. 그것은 aAbBcC...jJkKlLmM...분명하지 않은 것과 같습니다 . Latin1_General_BINLIKE 연산자를 사용하는 범위 검색으로 더 예측 가능해 보입니다 .
wqw

7

like오퍼레이터는 두 문자열 걸린다. 이러한 문자열에는 호환 가능한 데이터 정렬이 있어야하며 여기 에 설명되어 있습니다 .

제 생각에는 상황이 복잡해집니다. 다음 쿼리는 데이터 정렬이 호환되지 않는다는 오류를 반환합니다.

select *
from INFORMATION_SCHEMA.TABLES
where 'abc' COLLATE SQL_Latin1_General_CP1_CI_AS like 'ABC' COLLATE SQL_Latin1_General_CP1_CS_AS

여기 임의의 컴퓨터에서 기본 데이터 정렬은 SQL_Latin1_General_CP1_CI_AS입니다. 다음 쿼리는 성공했지만 행을 반환하지 않습니다.

select *
from INFORMATION_SCHEMA.TABLES
where 'abc' like 'ABC' COLLATE SQL_Latin1_General_CP1_CS_AS

"abc"및 "ABC"값은 대소 문자를 구분하는 세계에서 일치하지 않습니다.

즉, 데이터 정렬이없는 것과 기본 데이터 정렬을 사용하는 것에는 차이가 있습니다. 한쪽에 데이터 정렬이 없으면 다른 쪽의 명시 적 데이터 정렬이 "할당"됩니다.

(명시 적 데이터 정렬이 왼쪽에있을 때 결과는 동일합니다.)


INFORMATION_SCHEMA.TABLES와 같은 시스템 객체가 아닌 테이블에 대해 오류를 재현 할 수 있습니까?
Aaron Bertrand

@AaronBertrand. . . 예, 저는 할수 있습니다. 데이터베이스가 손상 되었습니까?)?
Gordon Linoff

모르겠습니다. 지금 모바일 장치를 사용 중이며 Windows VM을 실행할 수 없습니다. 전체 설명이 기술적으로 정확한지 모르겠습니다.
Aaron Bertrand

4

실행 해보세요.

SELECT SERVERPROPERTY('COLLATION')

그런 다음 데이터 정렬이 대소 문자를 구분하는지 확인하십시오.



0

Microsoft SQL Server Management Studio에서 데이터 정렬을 쉽게 변경할 수 있습니다.

  • 오른쪽 클릭 테이블-> 디자인.
  • 열을 선택하고 열 속성을 아래로 스크롤하여 데이터 정렬합니다.
  • "대소 문자 구분"을 선택하여 정렬 기본 설정을 지정하십시오.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.