【发布时间】:2021-12-16 06:37:00
【问题描述】:
我正在尝试运行 UPDATE 命令,该命令将 DateTime 数据类型存储在 SQL Server 表中,但是每当它到达该行时
command.ExecuteNonQuery();
程序因以下错误而失败:
将 varchar 数据类型转换为 datetime 数据类型导致值超出范围
我已经设法收集到这可能意味着我正在使用的 DateTime 格式,但无论我试图将时间转换成什么形状,它仍然会吐出完全相同的错误。
数据存储格式为en-GB,读取如下:
StartDateTime = DateTime.Parse(items[0], new CultureInfo("en-GB"));
当我尝试在 SQL 中存储时间时,我当前使用的是以下格式:
const string ParamStart = "@NewStartDate";
command.Parameters.Add(ParamStart, System.Data.SqlDbType.DateTime).Value = newStartDate;
存储在 SQL Server 表中的数据以这种格式存储:
yyyy-MM-dd HH:mm:ss.fff
我的 SQL 阅读器从 SQL Server 获取数据没有问题,但是一旦我开始使用参数,它就会报错。
真正令人沮丧的是,在同一个文件的其他地方我有一个SELECT 命令,它使用完全相同的格式将数据包含在查询中:
command.Parameters.Add(ParamStart, System.Data.SqlDbType.DateTime).Value = startDate;
这很好用。
SQL Server 中该列的数据类型是datetime,不能为空。
出现在我的 C# 代码中的查询:
string query = $"UPDATE [{DB_NAME}].[dbo].[{TABLE_BATCH}] SET [{COLUMN_START}] = {ParamStart}, [{COLUMN_MACHINE}] = {ParamMachine}," +
$" [{COLUMN_SERIAL}] = {ParamSerial}, {(newBatch.EndDateTime != null ? $"[{COLUMN_END}] = {ParamEnd}, " : "")}[{COLUMN_COMPLETE}] = {ParamComplete}, [{COLUMN_IN_USE}] = {ParamInUse} {oldBatch.ToWhere()}";
以COLUMN_ 或Param 开头的任何内容都只是一个仅包含字符串的常量。使用它是为了避免拼写错误,并且可以在列名更改时编辑代码。
ToWhere() 方法从预先从数据库中提取的现有项目创建WHERE。 WHERE 使用插值字符串,因此不应在此处进行参数转换,但无论如何我都会发布 return 子句的格式:
$"WHERE [StartDateTime] = '{StartDateTime}' AND [MachineID] = '{MachineID}' AND [BatchNumber] = '{BatchNumber}'" +
$" AND [SAPOrderNumber] {sapString} AND [PartNumber] = '{PartNumber}' AND [LastSerialNumber] = {LastSerialNumber}" +
$" AND [EndDateTime] {endDateString} AND [Complete] {completeString} AND [BatchInUse] {inUseString}";
我需要对格式进行哪些更改才能使 SQL Server 识别日期?
【问题讨论】:
-
日期是二进制值,如 int 和 double,它们没有格式。不要将日期存储为字符串。使用正确的类型 -
date、datetime2或datetimeoffset。如果您将日期存储为字符串,那么您将遇到严重的错误,并且很可能是无法挽救的垃圾数据。根本无法确定07/04/2021是 4 月 7 日还是 7 月 4 日 -
在 C# 中使用
DateTime,而不是字符串。 -
我将它存储为日期时间。
-
如果你这样做,
varchar来自哪里?查询有什么作用?发布实际重现问题的代码。不知何故,在某处,您将日期作为文本处理 -
参数不是问题,无论您尝试执行什么查询。当
DATETIME和VARCHAR值组合在一起时,SQL Server 将始终倾向于将VARCHAR转换为DATETIME以进行比较,而不是相反。因此,如果 anyVARCHAR值未使用服务器的语言设置隐式转换为DATETIME,则会出现此错误。解决方案是修复查询,使其使用显式转换(或一劳永逸地修复数据,这样就不会发生类型的混合和匹配)。
标签: c# sql-server sqlclient