System.Data.OleDb.OleDbException: 'Parameter @Status has no default value.' 在 VB
System.Data.OleDb.OleDbException: 'Parameter @Status has no default value.' in VB
抱歉,如果我的 post 没有遵循编码论坛的常见 practice/rules,因为这是我的第二个问题。
我有一个按钮,单击该按钮后,它会根据组合框中选定的值在 MS Access 数据库中搜索项目,并将这些项目添加到数据网格中。它为每个值创建一个参数,并将相关的组合框项添加到该参数。
CreateSQLStr() 函数根据具有选定值的组合框形成 SQL 命令文本(即,如果组合框没有选定值,则它会不要在 table 中为该字段指定条件,但如果指定,它将添加 AND (TableField = @Parameter) 到 SQL 命令文本中。
我已经尝试将“ACTIVE”更改为预定义的字符串并出现相同的错误,但我想不出其他任何东西。
我的错误是`System.Data.OleDb.OleDbException: 'Parameter @Status has no default value.'
详情:
System.Data.OleDb.OleDbException
HResult=0x80040E10
Message=Parameter @Status has no default value.
Source=System.Data
StackTrace:
at System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr)
at System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams, Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.OleDb.OleDbCommand.ExecuteReader()
at WindowsApplication1.frmEmployee.vehiclesearch_Click(Object sender, EventArgs e) in C:\Users\aawad\OneDrive\Documents\QHP\QHP\QHP\frmEmployee.vb:line 79
at System.EventHandler.Invoke(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
at WindowsApplication1.My.MyApplication.Main(String[] Args) in :line 81
This exception was originally thrown at this call stack:
[External Code]
WindowsApplication1.frmEmployee.vehiclesearch_Click(Object, System.EventArgs) in frmEmployee.vb
[External Code]
`
Private Sub vehiclesearch_Click(sender As Object, e As EventArgs) Handles VehicleSearch.Click
If DbConnect() Then 'This fucntions returns boolean for whether or not database is connecyed
Dim SQLcmd As New OleDbCommand
With SQLcmd
.Connection = cn
.CommandText = CreateSQLStr() 'Creates command text based on selected combo box items, see below
.Parameters.AddWithValue("@Make", MakeCBox.SelectedItem)
.Parameters.AddWithValue("@Model", ModelCBox.SelectedItem)
.Parameters.AddWithValue("@ClassV", ClassCBox.SelectedItem)
.Parameters.AddWithValue("@VSeats", SeatsCBox.SelectedItem)
.Parameters.AddWithValue("@GrBox", GrboxCBox.SelectedItem)
.Parameters.AddWithValue("@Branch", BranchCBox.SelectedItem)
.Parameters.AddWithValue("@Status", "ACTIVE")
Dim rs As OleDbDataReader = .ExecuteReader 'Error occurs at this point
While rs.Read 'Adding data to data grid
Dim make, model, year, fuel, vclass, body As String
make = rs("VMake")
model = rs("VModel")
year = rs("VRegYear")
fuel = rs("VFuel")
vclass = rs("VClass")
body = rs("VBody")
VehDGrid.Rows.Add(make, model, year, fuel, vclass, body)
End While
rs.Close()
cn.Close()
End With
Else 'Error message when no vehicle found
MessageBox.Show("Could not find any vehicles with the selected details. ", "Find vehicle", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
End Sub
Function CreateSQLStr() As String
Dim SQLStr As String
SQLStr = "Select * FROM Vehicles WHERE (VStatus = @Status)"
If MakeCBox.SelectedItem IsNot Nothing Then
SQLStr = SQLStr + " AND (VMake = @Make)"
End If
If ModelCBox.SelectedItem IsNot Nothing Then
SQLStr = SQLStr & " AND (VModel = @Model)"
End If
If ClassCBox.SelectedItem IsNot Nothing Then
SQLStr = SQLStr & " AND (VClass = @ClassV)"
End If
If SeatsCBox.SelectedItem IsNot Nothing Then
SQLStr = SQLStr & " AND (VSeats = @Seats)"
End If
If GrboxCBox.SelectedItem IsNot Nothing Then
SQLStr = SQLStr & " AND (VGearbox = @GrBox)"
End If
If BranchCBox.SelectedItem IsNot Nothing Then
SQLStr = SQLStr & " AND (BranchID = @Branch)"
End If
Return SQLStr
End Function
编辑:回复评论
Dim rs As OleDbDataReader = SQLcmd.ExecuteReader
While rs.Read
VehDGrid.Rows.Add(rs("VehicleID"), rs("VMake"), rs("VModel"), rs("VRegYear"),
rs("VFuel"), rs("VClass"), rs("VBody"), rs("VSeats"),
rs("VGearbox"), rs("VReg"), rs("PPDay"), rs("VColour"))
End While
对于 MS Access,参数的顺序比名称更重要。使用参数时,我在 SQL 命令中使用 ?
占位符。我还指定了数据类型,因此请考虑使用 OleDbParameter Constructor (String, OleDbType) 构造函数。在我的示例中,我使用了 VarChar
,您可能希望对其进行相应更改。
我也会考虑实施 Using:
Managed resources are disposed of by the .NET Framework garbage collector (GC) without any extra coding on your part. You do not need a Using block for managed resources. However, you can still use a Using block to force the disposal of a managed resource instead of waiting for the garbage collector.
最后,如果您想根据所选值有条件地更新 WHERE
,您应该对参数执行相同的操作,以确保在不需要时也不会添加它们:
If MakeCBox.SelectedItem IsNot Nothing Then
SQLcmd.Parameters.AddWithValue("@Make", MakeCBox.SelectedItem)
End If
这应该有助于确保您的 SQL 命令符合您的要求。
礼貌地考虑花时间命名您的变量、方法和其他任何更具描述性的东西,例如 CreateSQLStr
变成 GetSelectVehicleCommandString
.
我还尝试抽象出方法背后的重复代码,以便您可以调用它并传入参数。它使维护更容易一些,如果您愿意,您可以为这些方法编写单元测试,以确保它们完全按照您的预期进行。这些只是我的想法。我已经举了一个例子来帮助你。希望这一切对您有用:
Private Sub vehiclesearch_Click(sender As Object, e As EventArgs) Handles VehicleSearch.Click
Dim selectVehicleCommandString = "SELECT * FROM Vehicles WHERE (VStatus = @Status)"
Using connection As New OleDbConnection(connectionString),
command As New OleDbCommand(selectVehicleCommandString, connection)
command.Parameters.Add(CreateParameter("@Status", OleDbType.VarChar, "ACTIVE"))
If MakeCBox.SelectedItem IsNot Nothing Then
selectVehicleCommandString = AppendToWhereClause(selectVehicleCommandString, "VMake")
command.Parameters.Add(CreateParameter("@Make", OleDbType.VarChar,MakeCBox.SelectedItem))
End If
If ModelCBox.SelectedItem IsNot Nothing Then
selectVehicleCommandString = AppendToWhereClause(selectVehicleCommandString, "VModel")
command.Parameters.Add(CreateParameter("@Model", OleDbType.VarChar,ModelCBox.SelectedItem))
End If
If ClassCBox.SelectedItem IsNot Nothing Then
selectVehicleCommandString = AppendToWhereClause(selectVehicleCommandString, "VClass")
command.Parameters.Add(CreateParameter("@ClassV", OleDbType.VarChar,ClassCBox.SelectedItem))
End If
If SeatsCBox.SelectedItem IsNot Nothing Then
selectVehicleCommandString = AppendToWhereClause(selectVehicleCommandString, "VSeats")
command.Parameters.Add(CreateParameter("@VSeats", OleDbType.VarChar,SeatsCBox.SelectedItem))
End If
If GrboxCBox.SelectedItem IsNot Nothing Then
selectVehicleCommandString = AppendToWhereClause(selectVehicleCommandString, "VGearbox")
command.Parameters.Add(CreateParameter("@GrBox", OleDbType.VarChar,GrboxCBox.SelectedItem))
End If
If BranchCBox.SelectedItem IsNot Nothing Then
selectVehicleCommandString = AppendToWhereClause(selectVehicleCommandString, "BranchID")
command.Parameters.Add(CreateParameter("@Branch", OleDbType.VarChar,BranchCBox.SelectedItem))
End If
command.CommandText = selectVehicleCommandString
connection.Open()
Dim results As New DataTable
results.Load(command.ExecuteReader())
VehDGrid.DataSource = results
End Using
End Sub
Private Function AppendToWhereClause(commandString As String, columnName As String) As String
Return commandString + $" AND ({columnName} = ?)"
End Function
Private Function CreateParameter(parameterName As String, dataType As OleDbType, value As String)
Dim parameter As New OleDbParameter(parameterName, dataType) With {
.Value = value
}
Return parameter
End Function
Please note that this code is completely untested as I haven't got the capabilities of running this against an MS Access database. if I've missed something, let me know and I'll look to correct accordingly
我在这里的尝试是尝试给你一些关于如何处理代码的想法:
- 有机会就“使用”
- 如果有条件地附加到
WHERE
子句,如果值存在,则对参数本身执行相同的操作
- 为您的变量名、方法、表单对象提供更具描述性的名称
- 移除不必要的变量并简化代码,例如,在向
VehDGrid
添加行时
您不需要循环来归档数据网格。
而且无论连接是打开还是关闭,我都不会弄乱。所有编写的代码都将关闭连接,因此代码基于该假设。
虽然 oleDB 的“@”名称参数无关紧要(对于 Access 数据引擎),但是,您不妨使用它们,因为该代码将来可用于 sql 服务器等.
我也不会单独添加 where 子句,然后单独添加参数。始终同时添加它们。
那样的话,您可以更改代码的顺序,甚至可以剪切 + 粘贴更多的部分,它总是有效的。由于 Access 对参数的顺序很敏感,因此这个建议更有价值(在代码中添加 sql 和参数作为一个组 - 而不是在两个单独的地方。那样的话,你真的不能搞砸了顺序,因为您在代码中配对了这个过程。
如前所述,您不需要循环即可将行添加到数据网格 - 它是一种数据感知代码,因此您只需向其发送数据 table.
例如:
Using conn As New OleDbConnection(My.Settings.AccessDB)
conn.Open()
Using cmdSQL As New OleDbCommand("", conn)
pAdd(cmdSQL, "VMake", MakeCBox)
pAdd(cmdSQL, "Vmodel", ModelCBox)
pAdd(cmdSQL, "VClass", ClassCBox)
pAdd(cmdSQL, "VSeats", SeatsCBox)
pAdd(cmdSQL, "VGearBox", GrboxCBox)
pAdd(cmdSQL, "BranchID", BranchCBox)
cmdSQL.CommandText &= " AND (VStatus = @VStatus)"
cmdSQL.Parameters.AddWithValue("@VStatus", "ACTIVE")
cmdSQL.CommandText = "SELECT * FROM Vehicles WHERE " & cmdSQL.CommandText
Console.WriteLine(cmdSQL.CommandText)
Dim rstData As New DataTable
rstData.Load(cmdSQL.ExecuteReader)
If rstData.Rows.Count = 0 Then
MsgBox("no data")
Else
VehDGrid.DataSource = rstData
End If
End Using
End Using
End Sub
Sub pAdd(cmd As OleDbCommand, sColumn As String, c As ComboBox)
If c.SelectedItem IsNot Nothing AndAlso c.Text <> "" Then
Dim sP As String = "@" & sColumn
If cmd.CommandText <> "" Then cmd.CommandText &= " AND "
cmd.CommandText &= "(" & sColumn & " = " & sP & ")"
cmd.Parameters.AddWithValue(sP, c.Text)
End If
End Sub
编辑:关于 My.Settings.AccessDB
的问题
好吧,是桌面版还是网络版?我刚用过这个:
项目->项目属性,然后是:
因此,在上面,您可以单击“...”按钮,这将启动连接生成器。一旦你在上面保存,就可以使用 My.Settings."my setting name here".
中的设置
所以,对于公司名称、头衔或其他什么?您可以构建和创建自己的设置。完成后,这些方便的设置就可以在代码中使用了。
抱歉,如果我的 post 没有遵循编码论坛的常见 practice/rules,因为这是我的第二个问题。
我有一个按钮,单击该按钮后,它会根据组合框中选定的值在 MS Access 数据库中搜索项目,并将这些项目添加到数据网格中。它为每个值创建一个参数,并将相关的组合框项添加到该参数。
CreateSQLStr() 函数根据具有选定值的组合框形成 SQL 命令文本(即,如果组合框没有选定值,则它会不要在 table 中为该字段指定条件,但如果指定,它将添加 AND (TableField = @Parameter) 到 SQL 命令文本中。
我已经尝试将“ACTIVE”更改为预定义的字符串并出现相同的错误,但我想不出其他任何东西。
我的错误是`System.Data.OleDb.OleDbException: 'Parameter @Status has no default value.'
详情:
System.Data.OleDb.OleDbException
HResult=0x80040E10
Message=Parameter @Status has no default value.
Source=System.Data
StackTrace:
at System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr)
at System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams, Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.OleDb.OleDbCommand.ExecuteReader()
at WindowsApplication1.frmEmployee.vehiclesearch_Click(Object sender, EventArgs e) in C:\Users\aawad\OneDrive\Documents\QHP\QHP\QHP\frmEmployee.vb:line 79
at System.EventHandler.Invoke(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
at WindowsApplication1.My.MyApplication.Main(String[] Args) in :line 81
This exception was originally thrown at this call stack:
[External Code]
WindowsApplication1.frmEmployee.vehiclesearch_Click(Object, System.EventArgs) in frmEmployee.vb
[External Code]
`
Private Sub vehiclesearch_Click(sender As Object, e As EventArgs) Handles VehicleSearch.Click
If DbConnect() Then 'This fucntions returns boolean for whether or not database is connecyed
Dim SQLcmd As New OleDbCommand
With SQLcmd
.Connection = cn
.CommandText = CreateSQLStr() 'Creates command text based on selected combo box items, see below
.Parameters.AddWithValue("@Make", MakeCBox.SelectedItem)
.Parameters.AddWithValue("@Model", ModelCBox.SelectedItem)
.Parameters.AddWithValue("@ClassV", ClassCBox.SelectedItem)
.Parameters.AddWithValue("@VSeats", SeatsCBox.SelectedItem)
.Parameters.AddWithValue("@GrBox", GrboxCBox.SelectedItem)
.Parameters.AddWithValue("@Branch", BranchCBox.SelectedItem)
.Parameters.AddWithValue("@Status", "ACTIVE")
Dim rs As OleDbDataReader = .ExecuteReader 'Error occurs at this point
While rs.Read 'Adding data to data grid
Dim make, model, year, fuel, vclass, body As String
make = rs("VMake")
model = rs("VModel")
year = rs("VRegYear")
fuel = rs("VFuel")
vclass = rs("VClass")
body = rs("VBody")
VehDGrid.Rows.Add(make, model, year, fuel, vclass, body)
End While
rs.Close()
cn.Close()
End With
Else 'Error message when no vehicle found
MessageBox.Show("Could not find any vehicles with the selected details. ", "Find vehicle", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
End Sub
Function CreateSQLStr() As String
Dim SQLStr As String
SQLStr = "Select * FROM Vehicles WHERE (VStatus = @Status)"
If MakeCBox.SelectedItem IsNot Nothing Then
SQLStr = SQLStr + " AND (VMake = @Make)"
End If
If ModelCBox.SelectedItem IsNot Nothing Then
SQLStr = SQLStr & " AND (VModel = @Model)"
End If
If ClassCBox.SelectedItem IsNot Nothing Then
SQLStr = SQLStr & " AND (VClass = @ClassV)"
End If
If SeatsCBox.SelectedItem IsNot Nothing Then
SQLStr = SQLStr & " AND (VSeats = @Seats)"
End If
If GrboxCBox.SelectedItem IsNot Nothing Then
SQLStr = SQLStr & " AND (VGearbox = @GrBox)"
End If
If BranchCBox.SelectedItem IsNot Nothing Then
SQLStr = SQLStr & " AND (BranchID = @Branch)"
End If
Return SQLStr
End Function
编辑:回复评论
Dim rs As OleDbDataReader = SQLcmd.ExecuteReader
While rs.Read
VehDGrid.Rows.Add(rs("VehicleID"), rs("VMake"), rs("VModel"), rs("VRegYear"),
rs("VFuel"), rs("VClass"), rs("VBody"), rs("VSeats"),
rs("VGearbox"), rs("VReg"), rs("PPDay"), rs("VColour"))
End While
对于 MS Access,参数的顺序比名称更重要。使用参数时,我在 SQL 命令中使用 ?
占位符。我还指定了数据类型,因此请考虑使用 OleDbParameter Constructor (String, OleDbType) 构造函数。在我的示例中,我使用了 VarChar
,您可能希望对其进行相应更改。
我也会考虑实施 Using:
Managed resources are disposed of by the .NET Framework garbage collector (GC) without any extra coding on your part. You do not need a Using block for managed resources. However, you can still use a Using block to force the disposal of a managed resource instead of waiting for the garbage collector.
最后,如果您想根据所选值有条件地更新 WHERE
,您应该对参数执行相同的操作,以确保在不需要时也不会添加它们:
If MakeCBox.SelectedItem IsNot Nothing Then
SQLcmd.Parameters.AddWithValue("@Make", MakeCBox.SelectedItem)
End If
这应该有助于确保您的 SQL 命令符合您的要求。
礼貌地考虑花时间命名您的变量、方法和其他任何更具描述性的东西,例如 CreateSQLStr
变成 GetSelectVehicleCommandString
.
我还尝试抽象出方法背后的重复代码,以便您可以调用它并传入参数。它使维护更容易一些,如果您愿意,您可以为这些方法编写单元测试,以确保它们完全按照您的预期进行。这些只是我的想法。我已经举了一个例子来帮助你。希望这一切对您有用:
Private Sub vehiclesearch_Click(sender As Object, e As EventArgs) Handles VehicleSearch.Click
Dim selectVehicleCommandString = "SELECT * FROM Vehicles WHERE (VStatus = @Status)"
Using connection As New OleDbConnection(connectionString),
command As New OleDbCommand(selectVehicleCommandString, connection)
command.Parameters.Add(CreateParameter("@Status", OleDbType.VarChar, "ACTIVE"))
If MakeCBox.SelectedItem IsNot Nothing Then
selectVehicleCommandString = AppendToWhereClause(selectVehicleCommandString, "VMake")
command.Parameters.Add(CreateParameter("@Make", OleDbType.VarChar,MakeCBox.SelectedItem))
End If
If ModelCBox.SelectedItem IsNot Nothing Then
selectVehicleCommandString = AppendToWhereClause(selectVehicleCommandString, "VModel")
command.Parameters.Add(CreateParameter("@Model", OleDbType.VarChar,ModelCBox.SelectedItem))
End If
If ClassCBox.SelectedItem IsNot Nothing Then
selectVehicleCommandString = AppendToWhereClause(selectVehicleCommandString, "VClass")
command.Parameters.Add(CreateParameter("@ClassV", OleDbType.VarChar,ClassCBox.SelectedItem))
End If
If SeatsCBox.SelectedItem IsNot Nothing Then
selectVehicleCommandString = AppendToWhereClause(selectVehicleCommandString, "VSeats")
command.Parameters.Add(CreateParameter("@VSeats", OleDbType.VarChar,SeatsCBox.SelectedItem))
End If
If GrboxCBox.SelectedItem IsNot Nothing Then
selectVehicleCommandString = AppendToWhereClause(selectVehicleCommandString, "VGearbox")
command.Parameters.Add(CreateParameter("@GrBox", OleDbType.VarChar,GrboxCBox.SelectedItem))
End If
If BranchCBox.SelectedItem IsNot Nothing Then
selectVehicleCommandString = AppendToWhereClause(selectVehicleCommandString, "BranchID")
command.Parameters.Add(CreateParameter("@Branch", OleDbType.VarChar,BranchCBox.SelectedItem))
End If
command.CommandText = selectVehicleCommandString
connection.Open()
Dim results As New DataTable
results.Load(command.ExecuteReader())
VehDGrid.DataSource = results
End Using
End Sub
Private Function AppendToWhereClause(commandString As String, columnName As String) As String
Return commandString + $" AND ({columnName} = ?)"
End Function
Private Function CreateParameter(parameterName As String, dataType As OleDbType, value As String)
Dim parameter As New OleDbParameter(parameterName, dataType) With {
.Value = value
}
Return parameter
End Function
Please note that this code is completely untested as I haven't got the capabilities of running this against an MS Access database. if I've missed something, let me know and I'll look to correct accordingly
我在这里的尝试是尝试给你一些关于如何处理代码的想法:
- 有机会就“使用”
- 如果有条件地附加到
WHERE
子句,如果值存在,则对参数本身执行相同的操作 - 为您的变量名、方法、表单对象提供更具描述性的名称
- 移除不必要的变量并简化代码,例如,在向
VehDGrid
添加行时
您不需要循环来归档数据网格。
而且无论连接是打开还是关闭,我都不会弄乱。所有编写的代码都将关闭连接,因此代码基于该假设。
虽然 oleDB 的“@”名称参数无关紧要(对于 Access 数据引擎),但是,您不妨使用它们,因为该代码将来可用于 sql 服务器等.
我也不会单独添加 where 子句,然后单独添加参数。始终同时添加它们。
那样的话,您可以更改代码的顺序,甚至可以剪切 + 粘贴更多的部分,它总是有效的。由于 Access 对参数的顺序很敏感,因此这个建议更有价值(在代码中添加 sql 和参数作为一个组 - 而不是在两个单独的地方。那样的话,你真的不能搞砸了顺序,因为您在代码中配对了这个过程。
如前所述,您不需要循环即可将行添加到数据网格 - 它是一种数据感知代码,因此您只需向其发送数据 table.
例如:
Using conn As New OleDbConnection(My.Settings.AccessDB)
conn.Open()
Using cmdSQL As New OleDbCommand("", conn)
pAdd(cmdSQL, "VMake", MakeCBox)
pAdd(cmdSQL, "Vmodel", ModelCBox)
pAdd(cmdSQL, "VClass", ClassCBox)
pAdd(cmdSQL, "VSeats", SeatsCBox)
pAdd(cmdSQL, "VGearBox", GrboxCBox)
pAdd(cmdSQL, "BranchID", BranchCBox)
cmdSQL.CommandText &= " AND (VStatus = @VStatus)"
cmdSQL.Parameters.AddWithValue("@VStatus", "ACTIVE")
cmdSQL.CommandText = "SELECT * FROM Vehicles WHERE " & cmdSQL.CommandText
Console.WriteLine(cmdSQL.CommandText)
Dim rstData As New DataTable
rstData.Load(cmdSQL.ExecuteReader)
If rstData.Rows.Count = 0 Then
MsgBox("no data")
Else
VehDGrid.DataSource = rstData
End If
End Using
End Using
End Sub
Sub pAdd(cmd As OleDbCommand, sColumn As String, c As ComboBox)
If c.SelectedItem IsNot Nothing AndAlso c.Text <> "" Then
Dim sP As String = "@" & sColumn
If cmd.CommandText <> "" Then cmd.CommandText &= " AND "
cmd.CommandText &= "(" & sColumn & " = " & sP & ")"
cmd.Parameters.AddWithValue(sP, c.Text)
End If
End Sub
编辑:关于 My.Settings.AccessDB
的问题好吧,是桌面版还是网络版?我刚用过这个:
项目->项目属性,然后是:
因此,在上面,您可以单击“...”按钮,这将启动连接生成器。一旦你在上面保存,就可以使用 My.Settings."my setting name here".
中的设置所以,对于公司名称、头衔或其他什么?您可以构建和创建自己的设置。完成后,这些方便的设置就可以在代码中使用了。