Zapytanie programu SQL Server, które wpisze kolumnę Unicode do sortowania binarnego, zwraca nieprawidłowe wyniki

Ten artykuł ułatwia rozwiązanie problemu występującego, gdy instrukcja zawiera klauzulę lub OR zdefiniowaną IN dla kolumny Unicode i zawiera collate wpisanie kolumny Unicode do innego sortowania binarnego.

Oryginalna wersja produktu: SQL Server
Oryginalny numer KB: 3053639

Symptomy

Masz tabelę w bazie danych programu SQL Server, w której spełnione są następujące warunki:

  • Tabela zawiera kolumnę Unicode. Na przykład tabela zawiera kolumnę nchar(5) .
  • Sortowanie kolumny Unicode to Latin1_General_BIN.
  • Ta sama kolumna Unicode jest częścią indeksu. Jednak instrukcje języka T-SQL uruchamiane względem tej tabeli mogą zwracać nieprawidłowe wyniki. Ten problem występuje, gdy spełnione są następujące warunki:
    • Instrukcja języka T-SQL zawiera klauzulę or OR zdefiniowaną IN dla tej samej kolumny Unicode.
    • Instrukcja T-SQL zawiera collate wpisanie kolumny Unicode do innego sortowania binarnego.

Przykładowe zapytanie:

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

Rozwiązanie

Aby obejść ten problem, upewnij się, że kolumna Unicode (Col3 w przykładowym zapytaniu w sekcji Objawy ) spełnia jeden z następujących warunków:

  • Jest typu danych char(5) lub nvarchar(5).
  • Jest definiowany przy użyciu tego samego sortowania, dla którego sortowanie Chinese_PROC_BIN jest pożądane (należy pamiętać, że Chinese_PROC_BIN jest to tylko przykład; mają zastosowanie również inne sortowania binarne).
  • Jest sortowaniem innym niż Latin1_General_BIN.
  • Jest sortowany w sortowaniu ciągłej integracji. Na przykład: collate Chinese_PRC_90_CI_AI IN (N'1 ', N'2 ').
  • Jest porównywany ze stałą zgodną z długością kolumny. Na przykład collate Chinese_PRC_BIN IN (N'1 ', N'2 ').
  • Nie jest częścią indeksu lub skanowanie tabeli jest wymuszane przy użyciu FORCESCAN wskazówki tabeli.
  • Funkcje takie jak RTRIM i LTRIM są używane do wymuszania skanowania tabeli.

Więcej informacji

Aby odtworzyć ten problem, uruchom następujący skrypt:

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

Dotyczy

  • SQL Server 2014 Business Intelligence
  • SQL Server 2014 Developer
  • SQL Server 2014 Enterprise
  • SQL Server 2014 Enterprise Core
  • SQL Server 2014 Express
  • SQL Server 2014 Standard
  • SQL Server 2014 Web
  • SQL Server 2012 Business Intelligence
  • SQL Server 2012 Developer
  • SQL Server 2012 Enterprise
  • SQL Server 2012 Express
  • SQL Server 2012 Standard
  • SQL Server 2012 Web
  • 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 Parallel Data Warehouse
  • 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