本文可協助您解決當語句包含 IN 針對 Unicode 資料行定義的 或 OR 子句,並包含 collate 以將 Unicode 資料行類型轉換成另一個二進制定序時所發生的問題。
原始產品版本:SQL Server
原始 KB 編號: 3053639
徵兆
您在 SQL Server 資料庫中有一個資料表,其中下列條件成立:
- 數據表包含 Unicode 資料行。 例如,數據表有一個數據行
nchar(5)。 - Unicode 資料行的定序為
Latin1_General_BIN。 - 相同的 Unicode 資料行是索引的一部分。 不過,針對此數據表執行的 T-SQL 語句可能會傳回不正確的結果。 當下列條件成立時,就會發生此問題:
- T-SQL 語句包含
IN針對相同 Unicode 資料行定義的 orOR子句。 - T-SQL 語句包含
collate將 Unicode 資料行類型轉換成另一個二進制定序。
- T-SQL 語句包含
範例查詢:
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
因應措施
若要解決此問題,請確定 Unicode 數據行 [徵兆] 區段中的範例查詢中的 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 ')。 - 不是 Index 的一部分,或是使用資料表提示強制進行
FORCESCAN數據表掃描。 - 和 之類的
RTRIMLTRIM函式可用來強制表掃描。
其他相關資訊
若要重現此問題,請執行下列腳本:
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 Web
- SQL Server 2012 商業智慧
- SQL Server 2012 開發人員
- 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