使用datetime作为存储过程中的参数更新表时出错

时间:2011-02-19 05:57:51

标签: c# .net sql-server 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

我如何解决这个日期问题。

4 个答案:

答案 0 :(得分:5)

从您的代码中,您的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或{ {1}}无论是否有任何区域,语言或区域设置,都可以识别并运行。

所以,如果你绝对必须,那么使用:

yyyy-MM-ddThh:mm:ss

Dtime.ToString("yyyyMMdd")

,没有别的(所有其他格式都依赖于语言和设置,可能在一种情况下有效,在另一种情况下有效; ISO-8601 总是有效)

答案 1 :(得分:2)

<强>更新

格式化字符串应为

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)

答案 2 :(得分:1)

如果您使用该工具,请使用SQL Profiler实际查看传递给数据库的完全 SQL字符串。这有助于您找到错误。

答案 3 :(得分:0)

只需在3个地方匹配数据类型:

  • C#传递给存储过程的类型
  • 您的商店程序所期望的类型
  • 您填写的字段在数据库中

目前,

  • 您C#正在传递字符串Dtime.ToString("dd/MMM/yyyy")
  • 您的存储过程需要日期时间@AtDate datetime
  • 数据库中的Atdate字段似乎日期时间Atdate=@AtDate

所以,要使它们全部匹配,你只需要调整你的C#代码,从字符串到Dtime,如下所示:

cmd.Parameters.AddWithValue("@AtDate",Dtime);

我希望数据库中的Atdate字段实际上是DATETIME,而不是VARCHAR。如果它是VARCHAR,那么你应保持你的C#代码,并更改存储过程中的@AtDate参数匹配它:

@AtDate VARCHAR(10)

但如果可能的话,最好的方法就是让它们成为真正的DATETIME。如果可以,请避免使用字符串(varchar)作为日期