다음을 통해 공유


유니코드 열을 이진 데이터 정렬로 typecast하는 SQL Server 쿼리는 잘못된 결과를 반환합니다.

이 문서에서는 문에 유니코드 열에 대해 정의되고 유니코드 열을 다른 이진 데이터 정렬로 typecast하는 절을 포함하는 IN collate 경우 OR 발생하는 문제를 해결하는 데 도움이 됩니다.

원래 제품 버전: SQL Server
원래 KB 번호: 3053639

증상

SQL Server 데이터베이스에 다음 조건이 충족되는 테이블이 있습니다.

  • 테이블에 유니코드 열이 포함되어 있습니다. 예를 들어 테이블에는 열이 있습니다 nchar(5) .
  • 유니코드 열의 데이터 정렬은 Latin1_General_BIN.
  • 동일한 유니코드 열이 인덱스의 일부입니다. 그러나 이 테이블에 대해 실행되는 T-SQL 문은 잘못된 결과를 반환할 수 있습니다. 이 문제는 다음 조건이 충족될 때 발생합니다.
    • T-SQL 문에는 동일한 유니코드 열에 대해 정의된 또는 OR 절이 포함되어 IN 있습니다.
    • T-SQL 문에는 유니코드 열을 다른 이진 데이터 정렬로 형식화하기 위한 형식화가 포함되어 collate 있습니다.

샘플 쿼리:

CREATE TABLE [dbo].[Table_1]([Col1] [smallint] NOT NULL,
[Col2] [nchar](5),
[Col3] [nchar](5) COLLATE Latin1_General_BIN NOT NULL, -- Col3 , a Unicode Column with "Latin1_General_BIN" collation
CONSTRAINT [PK__Table_1] PRIMARY KEY CLUSTERED -- Primary Key on all the 3 columns
([Col1] ASC,
[Col2] ASC,
[Col3] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SELECT * FROM Table_1 WHERE Col1 = 1 AND Col2 = '1' AND Col3 COLLATE Chinese_PRC_BIN IN (N'1' ,N'2')  -- This statement using "IN" and "collate" might give incorrect results.
GO

SELECT * FROM Table_1 WHERE Col1 = 1 AND Col2 = '1' AND (Col3 COLLATE Chinese_PRC_BIN = N'1' OR Col3 COLLATE Chinese_PRC_BIN = N'2') -- This statement using "OR" and "collate" might give incorrect results.
GO

해결 방법

이 문제를 해결하려면 유니코드 열(증상 섹션의 샘플 쿼리에 있는 Col3)이 다음 조건 중 하나를 충족하는지 확인합니다.

  • 데이터 형식 char(5) 또는 nvarchar(5).
  • 데이터 정렬이 필요한 것과 동일한 데이터 정렬 Chinese_PROC_BIN 을 사용하여 정의됩니다( Chinese_PROC_BIN 예시일 뿐이며 다른 이진 데이터 정렬도 적용됨).
  • 가 아닌 Latin1_General_BIN데이터 정렬입니다.
  • CI 데이터 정렬에서 데이터 정렬됩니다. 예: collate Chinese_PRC_90_CI_AI IN (N'1 ', N'2 ')
  • 열 길이와 일치하는 상수와 비교됩니다. 예들 들어 collate Chinese_PRC_BIN IN (N'1 ', N'2 ')입니다.
  • 인덱스의 일부가 아니거나 테이블 힌트를 사용하여 테이블 검색을 강제로 수행합니다 FORCESCAN .
  • 테이블 검색과 같은 RTRIM 함수 및 LTRIM 테이블 검사를 강제로 적용하는 데 사용됩니다.

자세한 정보

이 문제를 재현하려면 다음 스크립트를 실행합니다.

CREATE DATABASE Test_DB
GO

USE Test_DB
GO

CREATE TABLE [dbo].[Table_1]([Col1] [smallint] NOT NULL,
[Col2] [nchar](5),
[Col3] [nchar](5) COLLATE Latin1_General_BIN NOT NULL, -- Col3 , a Unicode Column with "Latin1_General_BIN" collation

CONSTRAINT [PK__Table_1] PRIMARY KEY CLUSTERED -- Primary Key on all the 3 columns
([Col1] ASC,
[Col2] ASC,
[Col3] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

-- Populate the table with a sample script as below

DECLARE @x AS INT
DECLARE @y AS INT

SET @x=1
SET @y=1

WHILE (@x<=2)
BEGIN
WHILE (@y<=1000)
BEGIN
INSERT INTO Table_1 values (@x,@y,@y)
SET @y=@y+1
END
SET @x=@x +1
END
GO

SELECT * FROM Table_1 WHERE Col1 = 1 AND Col2 = '1' AND Col3 COLLATE Chinese_PRC_BIN = N'1' -- Expected output of one row.
GO

SELECT * FROM Table_1 WHERE Col1 = 1 AND Col2 = '1' AND Col3 COLLATE Chinese_PRC_BIN IN (N'1' ,N'2') -- No rows returned when output for Col3= N'1' is expected.
GO

SELECT * FROM Table_1 WHERE Col1 = 1 AND Col2 = '1' AND (Col3 COLLATE Chinese_PRC_BIN = N'1' OR Col3 COLLATE Chinese_PRC_BIN = N'2') -- No rows returned when output for Col3= N'1' is expected.
GO

적용 대상

  • SQL Server 2014 Business Intelligence
  • SQL Server 2014 개발자
  • SQL Server 2014 Enterprise
  • SQL Server 2014 Enterprise Core
  • SQL Server 2014 Express
  • SQL Server 2014 Standard
  • SQL Server 2014 웹
  • SQL Server 2012 Business Intelligence
  • SQL Server 2012 개발자
  • SQL Server 2012 Enterprise
  • SQL Server 2012 Express
  • SQL Server 2012 Standard
  • SQL Server 2012 웹
  • SQL Server 2012 Enterprise Core
  • SQL Server 2008 R2 Datacenter
  • SQL Server 2008 R2 Developer
  • SQL Server 2008 R2 Enterprise
  • SQL Server 2008 R2 Express
  • SQL Server 2008 R2 병렬 데이터 웨어하우스
  • SQL Server 2008 R2 Standard
  • SQL Server 2008 R2 Web
  • SQL Server 2008 R2 Workgroup
  • SQL Server 2008 Developer
  • SQL Server 2008 Enterprise
  • SQL Server 2008 Express
  • SQL Server 2008 Standard
  • SQL Server 2008 Web
  • SQL Server 2008 Workgroup
  • SQL Server 2005 Developer Edition
  • SQL Server 2005 Enterprise Edition
  • SQL Server 2005 Express Edition
  • SQL Server 2005 Standard Edition
  • SQL Server 2005 Standard X64 Edition
  • SQL Server 2005 Workgroup Edition