从字符串转换为类型'日期'无效

时间:2016-02-13 07:11:06

标签: .net vb.net date datetime

我有2个datetimepicker,允许用户选择开始日期和结束日期。因此,在选择日期后,用户必须单击一个按钮才能运行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

我不知道我错过了什么。请帮忙。感谢

2 个答案:

答案 0 :(得分:1)

您的代码中存在多个问题。

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

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

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

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

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

我不知道哪个数据库,所以我猜到了Access。这并不重要,因为数据库提供商的工作方式大致相同:

' 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"中使用它。如初。

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

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

为了强调这一点,MSDN(和其他人)鼓励使用?代替其他表单("@p1""@firstname""@DateOfBirth")。特别是在包含多列的查询中,我喜欢"@p1",因为数字有助于索引SQL中的相关列,并有助于确保它们按顺序(可视)。

最后,您的BETWEEN子句是否按预期工作将取决于几个因素,包括DataType参数。 DateTimePicker的日期将包含时间。为了不排除某些行,因为时间部分早于从DateTimePicker获得的任何部分,您将需要使用正确的行。

答案 1 :(得分:0)

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 & "'"