我创建了一个执行我的数据的功能
Public Function Excuter(ByVal Query As String)
If cn.State = ConnectionState.Open Then cn.Close()
cn.Open()
Try
cmd.CommandText = (Query)
cmd.ExecuteNonQuery()
cn.Close()
Catch ex As Exception
cn.Close()
MsgBox(ex.ToString())
End Try
End Function
这是我的插入代码
Excuter("INSERT INTO Table_PatientDetail (Patient_ID , Patient_Name , Age,Sex , Phone_Number , Address, Check_In_ID, Check_Out_ID , Service , Transfer , Patient_Result ) VALUES (@Patient_ID , @Patient_Name , @Age, @Sex , @Phone_Number , @Address, @Check_In_ID , @Check_Out_ID , @Service , @Transfer , @Patient_Result)")
cmd.Parameters.AddWithValue("@Patient_ID", .PatientIDPatientInformation.Text)
cmd.Parameters.AddWithValue("@Patient_Name", .PatientNamePatientInformation.Text)
cmd.Parameters.AddWithValue("@Age", .AgePatientInformation.Text)
cmd.Parameters.AddWithValue("@Sex", .ComboBox1.Text)
cmd.Parameters.AddWithValue("@Phone_Number", .PhoneNumPatientInformation.Text)
cmd.Parameters.AddWithValue("@Address", .AddressPatientInformation.Text)
cmd.Parameters.AddWithValue("@Check_In_ID", .CIID.Text)
cmd.Parameters.AddWithValue("@Check_Out_ID", .COID.Text)
cmd.Parameters.AddWithValue("@Service", .Cboservice.SelectedValue)
cmd.Parameters.AddWithValue("@Transfer", .TransferPatientInformation.Text)
cmd.Parameters.AddWithValue("@Patient_Result", .ComboBox3.Text)
当我测试它时,它会显示此错误Must Declare Scalar Variable"@Patient_Name"
;我不明白。
答案 0 :(得分:4)
问题是您的Excuter
函数会在您将参数实际添加到cmd
对象之前获取查询字符串并执行它。一个快速而肮脏的解决方案是在调用Parameters
之前简单地填充Excuter
集合,如下所示:
cmd.Parameters.Clear() 'Remove any parameters left over from the previous call
cmd.Parameters.AddWithValue("@Patient_ID", .PatientIDPatientInformation.Text)
cmd.Parameters.AddWithValue("@Patient_Name", .PatientNamePatientInformation.Text)
cmd.Parameters.AddWithValue("@Age", .AgePatientInformation.Text)
cmd.Parameters.AddWithValue("@Sex", .ComboBox1.Text)
cmd.Parameters.AddWithValue("@Phone_Number", .PhoneNumPatientInformation.Text)
cmd.Parameters.AddWithValue("@Address", .AddressPatientInformation.Text)
cmd.Parameters.AddWithValue("@Check_In_ID", .CIID.Text)
cmd.Parameters.AddWithValue("@Check_Out_ID", .COID.Text)
cmd.Parameters.AddWithValue("@Service", .Cboservice.SelectedValue)
cmd.Parameters.AddWithValue("@Transfer", .TransferPatientInformation.Text)
cmd.Parameters.AddWithValue("@Patient_Result", .ComboBox3.Text)
Excuter("INSERT INTO Table_PatientDetail (Patient_ID , Patient_Name , Age,Sex , Phone_Number , Address, Check_In_ID, Check_Out_ID , Service , Transfer , Patient_Result ) VALUES (@Patient_ID , @Patient_Name , @Age, @Sex , @Phone_Number , @Address, @Check_In_ID , @Check_Out_ID , @Service , @Transfer , @Patient_Result)")
但是,因为此代码在多个调用中重用连接和命令,所以它看起来非常脆弱。例如,您每次调用时都必须记得清除Parameters
集合,否则您最终会遇到非常奇怪的错误。我建议重构您的代码,以便每个数据库调用更加自包含。
答案 1 :(得分:1)
您正在调用执行查询的Executer
,并且在执行查询后添加参数;但是,这太迟了。您必须在cmd.Parameters.AddWith(...)
之前致电cmd.ExecuteNonQuery()
。
向ParamArray
Sub添加Executer
参数,允许您将可变数量的参数传递给查询。由于您无法轻松地同时传递参数名称,只需将参数命名为@0
,@1
,@2
,...
Public Sub Executer(query As String, ParamArray parameters As Object())
Using cn = New SqlConnection(ConnectionString)
Using cmd = New SqlCommand(query, cn)
For i As Integer = 0 To parameters.Length - 1
cmd.Parameters.AddWithValue("@" & i, parameters(i))
Next
cn.Open()
Try
cmd.ExecuteNonQuery()
Catch ex As Exception
Interaction.MsgBox(ex.ToString())
End Try
End Using
End Using
End Sub
请注意Using
语句会自动关闭连接。即使发生异常,它也会这样做。另请注意,我已在本地向该方法声明了连接和命令对象。这样,您就不必在多个电话中跟踪其状态。
现在你可以像这样调用执行者(我稍微缩短了查询):
Const InsertPatientDetailSql As String = _
"INSERT INTO Table_PatientDetail (ID, Name, Age) VALUES (@0, @1, @2)"
Executer(InsertPatientDetailSql, 42, "John Doe", 35)
与您的方法相比,这是Executer
使用的真正简化。