您的代码中有几个问题。
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'Brien、D'Angelo Barksdale 或 Betty'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 获得的任何内容,您需要使用正确的行。