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行。
我会检查选项是否在不同的服务器上配置不同,特别是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以后!