【问题标题】:Conversion From String To Type 'Date' Is Not Valid从字符串到类型“日期”的转换无效
【发布时间】:2016-02-13 07:11:06
【问题描述】:

我有 2 个日期时间选择器,允许用户选择开始日期和结束日期。因此,在选择日期后,用户必须单击一个按钮来运行 sql 查询。因此,输出会根据所选日期进行过滤。

但是当我如下声明日期时出现错误(下面的代码放在按钮点击事件下):

Dim startdate As DateTime = Format(DateTimePicker1.Value, "dd/MM/yyyy")
Dim enddate As DateTime = Format(Microsoft.VisualBasic.DateAdd(DateInterval.Day, 1, DateTimePicker2.Value), "dd/MM/yyyy")

query = "Select * from records where recorddate between '" & startdate & "' and '" & enddate & "'"

错误在这里:

Dim startdate As DateTime = Format(DateTimePicker1.Value, "dd/MM/yyyy")

错误是:

Conversion from string "13/02/2016" to type 'Date' is not valid.

我记录的样本日期是这样的:

12/2/2016 7:28:26 PM

我不知道我在这里错过了什么。请帮忙。谢谢

【问题讨论】:

  • DateTimePicker1.Value 已经是一个日期,不需要转换。

标签: .net vb.net date datetime


【解决方案1】:

您的代码中有几个问题。

Dim startdate As DateTime = Format(DateTimePicker1.Value, "dd/MM/yyyy")

如果您将鼠标悬停在Format 上,Intellisense 会告诉您它返回一个字符串。由于您无法将字符串结果分配给声明为DateTime 的变量,因此您会收到错误消息。如果你打开Option Strict,编译器会告诉你这些。

其次,查询还将日期转换为字符串:

"...between '" & startdate & "' and '" & enddate & "'"

记号不是通用的 SQL 分隔符,它们是一种指定文本/字符串数据的方式。 SQL 参数更安全,可以防止意外的数据类型更改以及SQL injection attacks。它们还使代码更易于阅读。如果您的数据库中有名称列,请尝试插入一个名称,如 Tim O'BrienD'Angelo BarksdaleBetty's Cupcake Factory。查询将崩溃。 SQL 参数可以防止这种情况发生。

我不知道是哪个数据库,所以我猜是 Access。这无关紧要,因为 DB Providers 的工作方式都差不多:

' Dim startdate As DateTime = DateTimePicker1.Value
Dim enddate As DateTime = DateTimePicker2.Value.AddDays(1)

Dim SQL = "Select * from records where recorddate between @p1 AND @p2"

Using dbCon As New OleDbConnection(connstr)
    Using cmd As New OleDbCommand(SQL, dbCon)
        dbCon.Open()
        cmd.Parameters.Add("@p1", OleDbType.DBDate).Value = startdate
        cmd.Parameters.Add("@p2", OleDbType.DBDate).Value = DateTimePicker1.Value

        dt = New DataTable
        dt.Load(cmd.ExecuteReader)
    End Using
End Using

注意 这假设数据库中的列类型是日期而不是字符串。 BETWEEN 子句不太可能将日期用作字符串。如果您希望它们充当日期,请将它们另存为 Date。您不需要“需要转换为 String 才能在 SQL 中使用它”。永远。

  • 不需要对 Date 变量进行处理。 NET 提供者知道如何将DateTime 类型传递给数据库。
  • 实际上没有必要将DateTimePicker1.Value 分配给新变量,因为.Value DateTime 类型。
  • Using 块声明并创建 DB 对象,然后关闭并处置它们以释放资源
  • 在定义参数时,代码告诉它期待一个日期 (OleDbType.DBDate),然后 Value set 是一个实际的日期类型。

对于 Access/OleDB,以与它们在 SQL 中出现的顺序完全相同的顺序设置参数值非常重要。 OleDB 允许命名参数,但按它们在 SQL 中出现的顺序分配值。

为了强调这一点,MSDN(和其他)鼓励使用? 代替其他形式("@p1""@firstname""@DateOfBirth")。尤其是在多列查询中,我喜欢"@p1",因为数字有助于索引 SQL 中的相关列,并有助于确保它们是有序的(视觉上)。

最后,您的 BETWEEN 子句是否如您所愿工作将取决于包括该 DataType 参数在内的几件事。 DateTimePicker 中的日期将包括时间。为了不排除某些行,因为时间部分早于您从DateTimePicker 获得的任何内容,您需要使用正确的行。

【讨论】:

    【解决方案2】:

    DateTimePicker.Value 是 DateTime 类型,需要将其转换为 String 才能在 SQL 中使用:

    Dim startdate as String = DateTimePicker1.Value.ToString("dd/MM/yyyy")
    

    但是,您的数据库服务器可能未针对该格式进行配置。最好改为use the default format

    Dim startdate As String = DateTimePicker1.Value.ToString()
    Dim enddate As String = Microsoft.VisualBasic.DateAdd(DateInterval.Day, 1, DateTimePicker2.Value).ToString()
    query = "Select * from records where recorddate between '" & startdate & "' and '" & enddate & "'"
    

    【讨论】:

      猜你喜欢
      • 2015-03-01
      • 1970-01-01
      • 2014-05-03
      • 2011-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-30
      • 2015-02-09
      相关资源
      最近更新 更多