【问题标题】:Problems with sending DateTime to SQL Table将 DateTime 发送到 SQL 表的问题
【发布时间】:2016-02-17 17:14:33
【问题描述】:

我正在用 C# 编写 WinForms 代码,基本上有以下内容:

DateTime localDate = DateTime.UtcNow;
SqlConnection Conn = new SqlConnection("....[connection info]....");
Conn.Open();
SqlCommand sqlcomm = new SqlCommand("INSERT INTO dbo.Call VALUES(...., @Time,...);", Conn);

sqlcomm.Parameters.Add("@Time", SqlDbType.DateTime);
sqlcomm.Parameters["@Time"].Value = localDate;

Int32 o = sqlcomm.ExecuteNonQuery();

这会引发“When converting a string to DateTime, parse the string to take the date before putting each variable into the DateTime object.”的错误,据我所知,它认为localDate 变量是一个字符串,但如果我写入控制台localDate.GetType(),它会显示System.DateTime

数据库中“@Time”的列设置为 DateTime,所以这不是问题。有什么想法吗?

【问题讨论】:

  • 异常到底是在哪里抛出的?

标签: c# winforms datetime


【解决方案1】:

你快到了。对于 Sql Server 来说,考虑这些因素

select cast(getdate() as time)

问题是.net中没有时间这种类型,所以需要适应

SqlCommand sqlcomm = new SqlCommand(
    "INSERT INTO dbo.Call VALUES(...., cast(@Time as time),...);", Conn);

sqlcomm.Parameters.AddWithValue("@Time", localDate);

这就是您所需要的。虽然,我认为,您甚至可能不需要添加强制转换,因为数据库引擎本身会尝试强制转换。我认为,问题在于您明确表示您的类型SqlDbType.DateTime。但是如果你使用AddWithValue,提供商会为你做事。

既然@Frédéric 提到了TimeSpan,你也可以试试这个

sqlcomm.Parameters.AddWithValue("@Time", localDate.TimeOfDay);
' and no cast(@Time as time)

【讨论】:

  • 没有时间输入.net?检查TimeSpan
  • @Frédéric TimeSpan 与 Sql Server Time 不直接匹配,因为timespan 可以为负数,而time 不能。
  • 查看我在第一条评论中添加的链接。 TimeSpan 是 sql time 的官方匹配,来自 msdn
  • @Frédéric 好的。但是您也应该在其中重新注释 小于零或大于或等于 24 小时的时间值将引发 ArgumentException。。你是对的。 timespan 映射到 Time。但它不是直接等价的,因为它的范围比time 大得多。所以,如果时间跨度在 0 到 24 之间 - 它会起作用
  • 仅供参考,您可以通过执行 localDate.TimeOfDay 来简化您的 TimeSpan 版本,这与 New TimeSpan(0, localDate.Hour, localDate.Minute, localDate.Second, localDate.Millisecond) 的作用相同(我删除了我的旧 cmets,你在哪里对)
【解决方案2】:

UTC格式不是你在parameters.add中指定的sql日期时间格式

过去我将 utc 时间格式化为 yyyy-MM-dd。

【讨论】:

  • 日期时间 localDate = Convert.ToDateTime(DateTime.UtcNow);字符串 testMe = localDate.Date.ToString("yyyy-MM-dd HH:mm:ss"); SqlConnection Conn = new SqlConnection("....[连接信息]...."); Conn.Open(); SqlCommand sqlcomm = new SqlCommand("INSERT INTO dbo.Call VALUES(...., @Time,...);", Conn); sqlcomm.Parameters.Add("@Time", SqlDbType.DateTime); sqlcomm.Parameters["@Time"].Value = localDate; Int32 o = sqlcomm.ExecuteNonQuery();
【解决方案3】:

鉴于此表架构:

create table dbo.call_history
(
  id          int      not null identity(1,1) primary key clustered ,
  my_date     date         null ,
  my_time     time         null ,
  my_datetime datetime     null ,
)

这段代码运行良好:

using ( SqlConnection conn = new SqlConnection( connectString ) )
using ( SqlCommand cmd = conn.CreateCommand() )
{

  cmd.CommandType = CommandType.Text;
  cmd.CommandText = @"
    insert dbo.call_history ( my_date , my_time , my_datetime )
    values                  ( @pDate  , @pDate  , @pDate      )

    select scope_identity()
  ";

  cmd.Parameters.AddWithValue( "@pDate" , DateTime.UtcNow );

  conn.Open();

  // double downcast required herebecause scope_identity()
  // returns numeric(38,0) which gets mapped to decimal
  int id = (int)(decimal) cmd.ExecuteScalar() ;

  conn.Close();

}

【讨论】:

  • 顺便说一句 select scope_identity() 是旧风格。 output inserted + ExecuteReader 更强大
猜你喜欢
  • 1970-01-01
  • 2021-01-02
  • 2021-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-30
  • 1970-01-01
  • 2011-04-19
相关资源
最近更新 更多