2010-08-18 96 views
0

我已经创建了我的桌子复合唯一索引:SQL Server 2008:在唯一索引中忽略排序规则?

CREATE TABLE [dbo].[SearchIndexWord](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [CatalogID] [int] NOT NULL, 
    [Word] [nvarchar](100) NOT NULL, 
CONSTRAINT [PK_SearchIndexWord] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
) 
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) 
ON [PRIMARY] 

CREATE UNIQUE NONCLUSTERED INDEX [IX_SearchIndexWord] ON [dbo].[SearchIndexWord] 
(
    [Word] ASC, 
    [CatalogID] ASC 
) 
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 
ON [PRIMARY] 

整个数据库排序规则设置为SQL_Latin1_General_CP1_CI_AS。当我运行下面的T-SQL,它打印“不等于”:

IF 'm3/h' = 'm³/h' 
    PRINT 'Equals' 
ELSE 
    PRINT 'Does not equal' 

然后,如果我尝试以下插入语句:

INSERT INTO [SearchIndexWord] (Word, CatalogID) VALUES ('m3/h', 1), ('m³/h', 1) 

我收到以下错误信息:

Msg 2601, Level 14, State 1, Line 1 
Cannot insert duplicate key row in object 'dbo.SearchIndexWord' with unique index 'IX_SearchIndexWord'. 

这是为什么?我无法在文档中找到它,但我认为使用配置的排序规则检查了两个键被复制的情况。

我已经检查了表格,列和索引排序方式,它们都等于数据库排序规则。

回答

1

试试这个:

IF CAST('m3/h' AS NVARCHAR(100)) = CAST('m³/h' AS NVARCHAR(100)) 
    PRINT 'Equals' 
ELSE 
    PRINT 'Does not equal' 

对于我来说,这将返回'Equals'这就解释了为什么你得到重复键行错误。

我怀疑代码IF 'm3/h' = 'm³/h'中的值是作为VARCHAR创建的。

+0

你说得对。我通过给列中的不同排序规则(SQL_Latin1_General_BIN)解决了问题。此外,它的工作方式如下:'IF N'm3/h'=N'm³/ h'' – ErikHeemskerk 2010-08-18 06:09:30

+0

CAST()方法的工作原理是将两个字符串转换为unicode。一个更快的/更简单的方法做到这一点是像这样: IF N'm3/H“=N'm³/ H” PRINT‘等于’ ELSE PRINT‘不等于’ 通过将所述N个标记在前面每个字符串,你告诉SQL Server将每个字符串视为unicode - 然后我得到'Equals'。 同样,您也可以使用COLLATE子句: http://www.sqlmag.com/blog/practical-sql-server-45/tsql/Collat​​ion-SQL-Server-139576 – 2011-06-23 03:15:39