sql server -存储过程和c# SqlDataReader返回比预期少的行

本文关键字:返回 SqlDataReader server 存储过程 sql | 更新日期: 2023-09-27 17:51:09

我被要求将一个网站应用程序从一个服务器迁移到另一个服务器。代码是由以前的开发人员编写的。

他用下面的语句创建了一个存储过程:(参数)

            @SurveyPeriodConfigID int = -1,
            @StartDate DATETIME = NULL,
            @EndDate DATETIME = NULL,
            @StartTime DATETIME = [9:00:00],
            @EndTime DATETIME = [19:00:00],
            @Category INT = -1,
            @SubcategoryID INT = -1,
            @ReportType VARCHAR(50) = null,
            @DepartmentID INT = -1,
            @FloorID INT = -1,
            @RoomID INT = -1,
            @IsLazyLoad BIT = 0,
            @Day INT = -1

and [WHERE caluse]:

            SELECT [fields]
            FROM [tables]
            WHERE 
            (DATEPART(dw, rsdm.DateCreated)) != 7 AND (DATEPART(dw, rsdm.DateCreated)) !=1
                    AND rsdm.DateCreated BETWEEN @StartDate AND @EndDate
                    AND (CONVERT(VARCHAR(8),rsdm.DateCreated,108) BETWEEN @StartTime AND @EndTime)
                    AND (@Category = -1 OR rsdm.CategoryCodeID = @Category)
                    AND (@SubcategoryID = -1 OR rsdm.SubcategoryID = @SubcategoryID)
                    AND (@DepartmentID =-1 OR rsdm.DepartmentID = @DepartmentID)
                    AND (@FloorID =-1 OR rsdm.FloorID = @FloorID)
                    AND (@RoomID =-1 OR rsdm.RoomID = @RoomID)
                    AND (@Day =-1  OR  DATEPART(dw, rsdm.DateCreated) = @Day)
c#代码:

            SqlDataReader sqlDataReader = thisCommand.ExecuteReader(CommandBehavior.CloseConnection);

…调用存储过程并返回SqlDataReader。

一切顺利。

现在的问题是…以前旧网站返回8200行,但现在新网站返回6500行!!

我设置代码和网站在我的PC上我的sql数据库的副本…它返回正确的值8200。然后我换了网页。配置指向新的网站SQL服务器…6500行! !

我备份了现场sql数据库,并在我的PC上本地恢复了相同的数据库并进行了测试…8200行! !

旧站点有Sql server 2005,我的PC有开发者Sql 2012,而实时服务器有Sql 2012。

然后我在新的站点sql Server上运行sql分析器,提取脚本并在相同的sql数据库8200条记录上运行脚本!!

我花了1-2天的时间在这个问题上,仍然不知道为什么Sql Server通过sqldatareader返回6500行。

sql server -存储过程和c# SqlDataReader返回比预期少的行

我会检查选项是否在不同的服务器上配置不同,特别是ANSI_NULLS(参见下面的脚本)。请注意,当您在SSMS中运行脚本时,默认选项可能与使用ADO时生效的选项不同。. NET(参见SSMS Tools/Options/Query Execution/SQL Server/ANSI)。这通常解释了SSMS和ADO.NET之间的行为差异。

DECLARE @options INT 
SELECT @options = @@OPTIONS 
PRINT @options
IF ( (1 & @options) = 1 ) PRINT 'DISABLE_DEF_CNST_CHK' 
IF ( (2 & @options) = 2 ) PRINT 'IMPLICIT_TRANSACTIONS' 
IF ( (4 & @options) = 4 ) PRINT 'CURSOR_CLOSE_ON_COMMIT' 
IF ( (8 & @options) = 8 ) PRINT 'ANSI_WARNINGS' 
IF ( (16 & @options) = 16 ) PRINT 'ANSI_PADDING' 
IF ( (32 & @options) = 32 ) PRINT 'ANSI_NULLS' 
IF ( (64 & @options) = 64 ) PRINT 'ARITHABORT' 
IF ( (128 & @options) = 128 ) PRINT 'ARITHIGNORE'
IF ( (256 & @options) = 256 ) PRINT 'QUOTED_IDENTIFIER' 
IF ( (512 & @options) = 512 ) PRINT 'NOCOUNT' 
IF ( (1024 & @options) = 1024 ) PRINT 'ANSI_NULL_DFLT_ON' 
IF ( (2048 & @options) = 2048 ) PRINT 'ANSI_NULL_DFLT_OFF' 
IF ( (4096 & @options) = 4096 ) PRINT 'CONCAT_NULL_YIELDS_NULL' 
IF ( (8192 & @options) = 8192 ) PRINT 'NUMERIC_ROUNDABORT' 
IF ( (16384 & @options) = 16384 ) PRINT 'XACT_ABORT'

当您连接到数据库时,总是有一个与之关联的登录帐户。您是否使用不同的登录为您的应用程序比您使用时连接SQL Server管理工作室?日期格式基于您登录的默认语言。

请执行如下查询:

Select  syslogins.name, syslogins.language, syslanguages.dateformat
From    sys.syslogins
        Inner Join sys.syslanguages
            On syslogins.language = syslanguages.name

检查dateformat列返回的所有登录。如果日期格式不同,那么这可能解释了为什么从应用程序运行与从SSMS运行时得到不同的结果。

如果这确实是导致您出现问题的原因,那么您可以按照本博客中的说明更改登录的默认语言:http://blogs.lessthandot.com/index.php/datamgmt/datadesign/setting-a-standard-dateformat-for-sql-se/

既然你提到SSMS和SqlClient之间的结果不同,我可以想到两个选项

  • 实际上有两个不同模式的不同进程,SSMS选择一个,SqlClient选择另一个(可能基于身份)
  • (更有可能)SET选项不同,导致不同的行为

要检查后者,在两个SSMS中运行select @@OPTIONS并通过SqlClient进行比较。标记列在这里:http://www.mssqltips.com/sqlservertip/1415/determining-set-options-for-a-current-session-in-sql-server/

问题出在(DATEPART(dw, rsdm.DateCreated)) != 7 AND (DATEPART(dw, rsdm.DateCreated)) !=1

SqlClient用户将DATEFIRST设置为1,而我的SSMS设置为7。到其他sql server实例的所有其他相同用户连接都将DATEFIRST设置为7。(也感谢@"G master"对问题的最终确认)。

我所做的只是添加SQL脚本SET DATEFIRST 7;现在,将处理为什么用户设置与1以后!