Sql 使用空NVARCHAR或空检查的VARCHAR索引上的计数(*)将返回双倍的行

Sql 使用空NVARCHAR或空检查的VARCHAR索引上的计数(*)将返回双倍的行,sql,sql-server,indexing,count,Sql,Sql Server,Indexing,Count,我有一个带有VARCHAR列和索引的表。每当在此表上检查COLUMN=N或COLUMN为NULL时,SELECT COUNT*将返回双倍的行数。使用相同的where子句选择*将返回正确数量的记录 阅读本文之后:并做了一些测试,我相信列的排序和隐式转换不是错误,至少不是直接的错误。该列的排序规则为拉丁文1\u General\u CI\u AS 数据库在SQL Server 2012上,我也在2016年进行了测试 我在下面创建了一个测试脚本来演示这个问题。在这样做时,我相信它可能与数据分页有关,因

我有一个带有VARCHAR列和索引的表。每当在此表上检查COLUMN=N或COLUMN为NULL时,SELECT COUNT*将返回双倍的行数。使用相同的where子句选择*将返回正确数量的记录

阅读本文之后:并做了一些测试,我相信列的排序和隐式转换不是错误,至少不是直接的错误。该列的排序规则为拉丁文1\u General\u CI\u AS

数据库在SQL Server 2012上,我也在2016年进行了测试

我在下面创建了一个测试脚本来演示这个问题。在这样做时,我相信它可能与数据分页有关,因为它需要表中的一些数据才能发生

CREATE TABLE [dbo].TEMP 
(
    ID [varchar](50) COLLATE Latin1_General_CI_AS NOT NULL,
    [DATA] [varchar](200) COLLATE Latin1_General_CI_AS NULL,
    [TESTCOLUMN] [varchar](50) COLLATE Latin1_General_CI_AS NULL,
    CONSTRAINT [PK_TEMP] PRIMARY KEY CLUSTERED ([ID] ASC)
)
GO

CREATE NONCLUSTERED INDEX [I_TEMP_TESTCOLUMN] ON dbo.TEMP (TESTCOLUMN ASC)
GO

DECLARE @ROWS AS INT = 40; 

WITH NUMBERS (NUM) AS 
(
    SELECT 1 AS NUM
    UNION ALL
    SELECT NUM + 1 FROM NUMBERS WHERE NUM < @ROWS
)
INSERT INTO TEMP (ID, DATA)
SELECT NUM, '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901324561234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890' 
FROM NUMBERS

SELECT @ROWS AS EXPECTED, COUNT(*) AS ACTUALROWS
FROM TEMP
GO

SELECT COUNT(*) AS INVALIDINDEXSEARCHCOUNT
FROM TEMP
WHERE (TESTCOLUMN = N'' OR TESTCOLUMN IS NULL)
GO

DROP TABLE TEMP

我可以在某种程度上修改数据库,我无法更改数据,或者更改列,使其不允许为NULL,不幸的是,我无法修改执行搜索的代码,有人能找出一种方法来获得正确的COUNT*返回结果吗?

您最好还是发布,因为这是一个非常具体的数据库问题,而不是编程问题。它看起来像SQL Server引擎错误,我建议您向Microsoft打开票据。正确的计数将与排序规则SQL\u Latin1\u General\u CP1\u CI\u AS一起返回。您可以在[feedback site]feedback.azure.com/forums/908035-sql-server.repeatable上提交错误报告,可在Win 7、sql server 2014 SP3上复制。这是一个令人讨厌的错误,尤其是因为MS是。请发布MS bug ID,以便我们可以协助/投票。感谢大家的反馈。我已经向你提出了一张罚单