使用datetime作为存储过程中的参数更新表时出错
将char数据类型转换为DateTime数据类型会导致DateTime值超出范围。 该语句已终止。
ALTER PROCEDURE [dbo].[attendance_updatebyemployee_id] @Employee_id int, @AtDate datetime, @FNLogged bit, @ANLogged bit, @LogTime varchar(10), @LogOuttime varchar(10) AS BEGIN SET NOCOUNT ON; update Mst_Attendance set FNLogged=@FNLogged, ANLogged=@ANLogged,LogTime=@LogTime,LogOuttime=@LogOuttime where EmployeeId=@Employee_id and Atdate= @AtDate END
在C#代码我给它
cmd.Parameters.AddWithValue("@AtDate",Dtime.ToString("dd/MMM/yyyy"));
使用SQl profiler时,传递的数据是
exec [dbo].[attendance_updatebyemployee_id] @Employee_id=2,@AtDate='Feb 19 2011 12:00:00:000AM',@FNLogged=1,@ANLogged=0,@LogTime='11:45 AM',@LogOuttime=' '
在存储过程中@AtDate的值为2011-02-19 00:00:00.000.
它正在打破更新命令。
在表格内,日期保存为2/19/2011 12:00:00 AM
我该如何解决这个日期问题。
如果您有该工具,请使用SQL事件探查器实际查看传递给数据库的确切 SQL字符串。 这将帮助您找到错误。
从您的代码中,您的C#代码中似乎有一个DateTime
变量 – 所以只需按原样使用 – 完全不需要转换为字符串!
如果你有:
ALTER PROCEDURE [dbo].[attendance_updatebyemployee_id] @Employee_id int, @AtDate datetime, .....
然后你可以这样存储这样:
cmd.Parameters.AddWithValue("@AtDate", Dtime);
假设Dtime
是C#中的DateTime
类型。
不要不必要地转换和投射东西! 这只会引入潜在的破损和转换错误! 只需按原样使用DateTime
– 它将被发送到SQL Server并在T-SQL中使用并识别为DATETIME
。
如果你确实需要将日期值转换为字符串以将其传递给SQL Server,我总是建议使用ISO-8601标准格式: YYYYMMDD
或yyyy-MM-ddThh:mm:ss
被识别并且无论如何都可以使用任何区域,语言或区域设置。
所以,如果你绝对必须,那么使用:
Dtime.ToString("yyyyMMdd")
要么
Dtime.ToString("yyyyMMddTHH:mm:ss")
没有别的(所有其他格式都依赖于语言和设置,可能在一种情况下有效,在另一种情况下有效; ISO-8601 始终有效)
更新
格式化字符串应为
ToString("MM\\/dd\\/yyyy hh:mm:ss tt")
这将在数据库中提供输出
02/19/2011 12:00:00 AM
您可以使用DateTime.TryParse()将字符串转换为DateTime对象。
但是,您需要确保字符串实际上是日期时间表示。
示例(来自MSDN)
string[] dateStrings = {"05/01/2009 14:57:32.8", "2009-05-01 14:57:32.8", "2009-05-01T14:57:32.8375298-04:00", "5/01/2008 14:57:32.80 -07:00", "1 May 2008 2:57:32.8 PM", "16-05-2009 1:00:32 PM", "Fri, 15 May 2009 20:10:57 GMT" }; DateTime dateValue; Console.WriteLine("Attempting to parse strings using {0} culture.", CultureInfo.CurrentCulture.Name); foreach (string dateString in dateStrings) { if (DateTime.TryParse(dateString, out dateValue)) Console.WriteLine(" Converted '{0}' to {1} ({2}).", dateString, dateValue, dateValue.Kind); else Console.WriteLine(" Unable to parse '{0}'.", dateString); } // The example displays the following output: // Attempting to parse strings using en-US culture. // Converted '05/01/2009 14:57:32.8' to 5/1/2009 2:57:32 PM (Unspecified). // Converted '2009-05-01 14:57:32.8' to 5/1/2009 2:57:32 PM (Unspecified). // Converted '2009-05-01T14:57:32.8375298-04:00' to 5/1/2009 11:57:32 AM (Local). // Converted '5/01/2008 14:57:32.80 -07:00' to 5/1/2008 2:57:32 PM (Local). // Converted '1 May 2008 2:57:32.8 PM' to 5/1/2008 2:57:32 PM (Unspecified). // Unable to parse '16-05-2009 1:00:32 PM'. // Converted 'Fri, 15 May 2009 20:10:57 GMT' to 5/15/2009 1:10:57 PM (Local).
如果您知道要尝试解析的日期的格式是什么,则可以使用DateTime.TryParseExact()并在第二个参数中指定格式:
DateTime.TryParseExact(dateString, "M/dd/yyyy hh:mm", enUS, DateTimeStyles.None, out dateValue)
它只是在3个地方匹配数据类型的问题:
- C#传递给存储过程的类型
- 您的商店程序所期望的类型
- 您输入的字段在数据库中
目前,
- 你C#传递一个字符串值
Dtime.ToString("dd/MMM/yyyy")
- 您的存储过程需要一个日期时间 (
@AtDate datetime
) - 数据库中的
Atdate
字段似乎是datetime (Atdate=@AtDate
)
因此,要使它们全部匹配,您只需调整C#代码,从字符串到Dtime,如下所示:
cmd.Parameters.AddWithValue("@AtDate",Dtime);
我希望数据库中的Atdate字段实际上是DATETIME,而不是VARCHAR。 如果它是VARCHAR,那么你应该保持你的C#代码,并更改存储过程中的@AtDate参数匹配它:
@AtDate VARCHAR(10)
但是,如果可能的话,最好的是让它们成为真正的DATETIME。 如果可以,请避免使用字符串(varchar)作为日期