【问题标题】:The conversion of a nvarchar data type to a smalldatetime data type resulted in an out-of-range value将 nvarchar 数据类型转换为 smalldatetime 数据类型导致值超出范围
【发布时间】:2019-11-28 10:08:12
【问题描述】:

我有一个如下所示的 SQL 查询:

select LAST_UPDATED from Employees WHERE (CAST(LAST_UPDATED AS smalldatetime)) > (CAST('@updateTime' AS smalldatetime))

command.Parameters.AddWithValue("updateTime", updatedTime);

我解决了这里提出的几个相关问题以及this page,但没有一个可以解决我的问题。

我还尝试了 ISO-8601 格式 用于日期 (YYYYMMDD),这在此处似乎也不起作用。

SQL server 中 LAST_UPDATED 列的数据类型为 DATE。

问题是这样在开发机器和SQL管理工作室中运行良好,但在测试服务器中抛出以下错误:

将 nvarchar 数据类型转换为 smalldatetime 数据类型导致值超出范围

SQL 管理工作室查询:

select LAST_UPDATED from Employees WHERE (CAST(LAST_UPDATED AS smalldatetime)) > (CAST('2014-08-10 ' AS smalldatetime))

如果有人能对此有所了解,那将非常有帮助。

【问题讨论】:

  • 您是否将变量名写成文字而不是实际变量?
  • 您正在尝试将字符串 '@updateTime' 转换为 smalldatetime - 而不是 @updateTime 变量的值。
  • 我建议使用Parameters.Add 代替AddWithValue 并在C# 代码中定义输入参数的数据类型。
  • 您能否包括如何在 C# 中为变量 updatedTime 赋值?可能是某些日期相关的操作系统设置格式化了导致 SQL Server 在转换时失败的日期。
  • @EzLo : 多亏了你,updatedTime 的分配方式出了问题!

标签: c# sql sql-server


【解决方案1】:

啊!问题终于解决了。我是这样分配string updatedTime的:

string updatedTime = strUpdateTime.Substring(0, 11);
string strUpdateTime = GetLastUpdate()

所以我的代码是这样的:

string strUpdateTime = GetLastUpdate()
string updatedTime = strUpdateTime.Substring(0, 11);

select LAST_UPDATED from Employees WHERE (CAST(LAST_UPDATED AS smalldatetime)) > (CAST('@updateTime' AS smalldatetime))

command.Parameters.AddWithValue("updateTime", updatedTime);

在寻找帖子的答案时,我遇到了Mike Clark's answer,并注意到我也使用了 Substring()。所以我没有通过updatedTime,而是通过了strUpdateTime

command.Parameters.AddWithValue("updateTime", strUpdateTime);

如果需要更改 DateTime 的格式,可以在 several ways 中完成。

感谢所有为这篇文章做出贡献的人。

【讨论】:

  • 很高兴您找到了答案。下次,请尝试包含所有相关代码,这样我们就可以避免乒乓问答,因为这次错误超出了您在帖子中包含的代码。
  • @EzLo 当然可以。
【解决方案2】:

看看这些例子:

DECLARE @updateTime VARCHAR(20) = '2020-01-01'

SELECT CAST('@updateTime' AS smalldatetime)

消息 295,级别 16,状态 3,行 3 转换时转换失败 字符串转小日期时间数据类型。

现在,如果我们删除单引号,我们实际上将访问变量的内容,而不是硬编码的字符串'@updateTime'

DECLARE @updateTime VARCHAR(20) = '2020-01-01'

SELECT CAST(@updateTime AS smalldatetime)

结果:

2020-01-01 00:00:00

单引号用于分隔文字值。您可以使用变量名称(以 @ 开头)访问变量的内容,无需任何引号。


如果问题实际上是LAST_UPDATED 内容,则将您强制的CAST 替换为TRY_PARSE,如果LAST_UPDATED 内容不可转换,则不会失败。

select LAST_UPDATED from Employees 
WHERE TRY_PARSE(LAST_UPDATED AS smalldatetime) > TRY_PARSE(@updateTime AS smalldatetime)

【讨论】:

  • 试过你的建议仍然得到同样的错误,我错过了什么愚蠢的东西!
  • 如果 Last_Updated 已经是一个日期,那么问题出在 C# 变量的值上。
【解决方案3】:

就像我在 cmets 中所说的,不要传递 nvarchar,传递一个日期参数,然后就不需要强制转换了。所以在你的 c# 中改为:

command.Parameters.Add("updateTime",SqldbType.DateTime).Value = updatedTime

那么你的 SQL 可以这么简单:

SELECT LAST_UPDATED
FROM Employees
WHERE LAST_UPDATED > @updateTime;

当然,假设LAST_UPDATED(small)datetime;但是,为什么如果它被比较为一个日期?

【讨论】:

  • 您的建议似乎更有意义,但是当我尝试相同时,我得到了错误,因为 String 未被识别为有效的 DateTime 我觉得这是由于 @987654326 @ 变量是 String 数据类型,所以我做了 DateTime time = Convert.ToDateTime(updatedTime); command.Parameters.Add("updatetime",SqlDbType.DateTime).Value = time; time 的值是 2014-08-10 00:00:00 现在我收到错误,因为 String 未被识别为有效的 DateTime 我觉得我错过了一些非常非常愚蠢的事情!
  • updatedTime 需要是应用程序中的日期和时间数据类型。为什么不是,@m_beta?
  • 那是现有的代码,我们不要进入那部分。但在这里你可以看到我确实将updatedTime 转换为DateTime 数据类型。
猜你喜欢
  • 2011-01-19
  • 1970-01-01
  • 2016-10-22
  • 1970-01-01
  • 1970-01-01
  • 2017-03-31
  • 1970-01-01
  • 2012-04-16
  • 2014-04-19
相关资源
最近更新 更多