我正在尝试使用rd.HasRow
方法来验证键入的数据在保存到数据库之前是否重复。
如果重复,则假定弹出错误消息框而不是保存数据。
我该如何执行此操作以及将照片上传到数据库的代码?如果我注释了这部分代码,可以将键入的数据(不重复)保存到数据库中,但是照片不会随照片一起上传。
'i = cmd.ExecuteNonQuery()
'If i >= 1 Then
'MessageBox.Show("Profile successfully registered!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
'Else
'MessageBox.Show("Error. Please try again later.", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
'End If
但是,如果我不这样做,将不会保存用户键入的数据,并且会针对i=cmd.ExecuteNonQuery()
弹出此错误消息:
System.InvalidOperationException:'已经存在与此Command关联的打开的DataReader,必须先关闭它。'
这是整体代码。
Private Sub button2_Click(sender As Object, e As EventArgs) Handles button2.Click
Dim con As New SqlConnection
Dim cmd As New SqlCommand
Dim rollno As String
Dim name As String
Dim gender As String
Dim address As String
Dim phoneno As Integer
Dim datereg As String
Dim faculty As String
Dim course As String
Dim semester As String
Dim i As Integer
Dim j As Integer
rollno = TextBox1.Text
name = TextBox2.Text
gender = ComboBox4.Text
address = TextBox3.Text
phoneno = TextBox4.Text
datereg = dateTimePicker1.Value
faculty = comboBox1.Text
course = comboBox2.Text
semester = comboBox3.Text
con.ConnectionString = "Data Source=LAPTOP-85ALBAVS\SQLEXPRESS;Initial Catalog=Portal;Integrated Security=True"
cmd.Connection = con
con.Open()
'To validate whether duplication of typed in data by user occurs or not, if yes, error msg pop-up. If no, proceed and save the data into database
Dim rd As SqlDataReader
cmd.CommandText = "SELECT * FROM Profile WHERE RollNo= '" & TextBox1.Text & "' and Name='" & TextBox2.Text & "'"
rd = cmd.ExecuteReader()
If rd.HasRows Then
MessageBox.Show("User already registered! Please try again.", "Error", MessageBoxButtons.OK)
Else
cmd.CommandText = "INSERT INTO Profile VALUES ('" & rollno & "' , '" & name & "' , '" & gender & "' , '" & address & "' , '" & phoneno & "' , '" & datereg & "' , '" & faculty & "' , '" & course & "' , '" & semester & "')"
End If
'i = cmd.ExecuteNonQuery()
'If i >= 1 Then
'MessageBox.Show("Profile successfully registered!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
'Else
'MessageBox.Show("Error. Please try again later.", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
'End If
con.Close()
con.Open()
'To save the uploaded photo to table Photo
Dim command As New SqlCommand("Insert into Photo (Img, Pid) Values (@Img, @Pid)", con)
command.Connection = con
Dim ms As New MemoryStream
pictureBox1.Image.Save(ms, pictureBox1.Image.RawFormat)
command.Parameters.Add("@Img", SqlDbType.Image).Value = ms.ToArray()
command.Parameters.Add("@Pid", SqlDbType.VarChar).Value = TextBox1.Text
j = cmd.ExecuteNonQuery()
If j >= 1 Then
MessageBox.Show("Profile successfully registered!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("Error. Please try again later.", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Sub
答案 0 :(得分:1)
代码看起来有些杂乱,至少以我的经验,调试杂乱的代码可能很困难。我们可以采取一些措施来纠正该问题,我现在将尝试与您一起解决。
首先,为控件添加有意义的名称。您可以通过选择控件并更改Name
属性在表单上进行设计。通过代码引用它们时,这将极大地帮助您。在这种情况下,它还将帮助您消除对变量的需求。
考虑实施Using:
有时,您的代码需要不受管的资源,例如文件句柄,COM包装程序或SQL连接。使用代码块可以保证在您的代码完成后,处置一个或多个此类资源。这使它们可供其他代码使用。
这将帮助您管理声明和资源,同时使代码更清晰。
我还考虑将每个命令分成自己的Using
块,以使代码更清晰。
将数据插入数据库时,请考虑使用SQL parameters来避免SQL injection。
最后进入代码,让我们依次查看每个Using
块。
首先,我将在SqlConnection
块中启动Using
,然后为每个命令使用该连接:
Using con As New SqlConnection("Data Source=LAPTOP-85ALBAVS\SQLEXPRESS;Initial Catalog=Portal;Integrated Security=True")
con.Open()
'Add the rest of the code here
End Using
检查记录是否存在:
在这里,考虑声明一个Boolean
变量,我们将使用该变量来确定记录是否存在。
Dim recordExists As Boolean = False
Using cmd As New SqlCommand("SELECT * FROM Profile WHERE RollNo = @RollNo AND Name = @Name", con)
cmd.Parameters.Add("@RollNo", SqlDbType.[Type]).Value = txtRollNo.Text
cmd.Parameters.Add("@Name", SqlDbType.[Type]).Value = txtName.Text
Using reader As SqlDataReader = cmd.ExecuteReader()
recordExists = reader.HasRows
End Using
End Using
显示记录是否存在的提示,如果不存在则插入数据库:
If recordExists Then
MessageBox.Show("User already registered! Please try again.", "Error", MessageBoxButtons.OK)
Else
Using cmd As New SqlCommand("INSERT INTO Profile VALUES (@RollNo, @Name, @Gender, @Address, @PhoneNo, @DateReg, @Faculty, @Course, @Semester)", con)
cmd.Parameters.Add("@RollNo", SqlDbType.[Type]).Value = txtRollNo.Text
cmd.Parameters.Add("@Name", SqlDbType.[Type]).Value = txtName.Text
cmd.Parameters.Add("@Gender", SqlDbType.[Type]).Value = cboGender.Text
cmd.Parameters.Add("@Address", SqlDbType.[Type]).Value = txtAddress.Text
cmd.Parameters.Add("@PhoneNo", SqlDbType.[Type]).Value = txtPhoneNo.Text
cmd.Parameters.Add("@DateReg", SqlDbType.[Type]).Value = dtpDateReg.Value
cmd.Parameters.Add("@Faculty", SqlDbType.[Type]).Value = cboFaculty.Text
cmd.Parameters.Add("@Course", SqlDbType.[Type]).Value = cboCourse.Text
cmd.Parameters.Add("@Semester", SqlDbType.[Type]).Value = cboSemster.Text
If cmd.ExecuteNonQuery() > 0 Then
MessageBox.Show("Profile successfully registered!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("Error. Please try again later.", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Using
End If
插入图像:
Using cmd As New SqlCommand("INSERT INTO Photo (Img, Pid) VALUES (@Img, @Pid)", con)
Using ms As New MemoryStream()
pbxImage.Image.Save(ms, pbxImage.Image.RawFormat)
cmd.Parameters.Add("@Img", SqlDbType.Image).Value = ms.ToArray()
cmd.Parameters.Add("@Pid", SqlDbType.VarChar).Value = txtName.Text
End Using
cmd.ExecuteNonQuery()
End Using
请注意,我不确定您在数据库中的数据类型时使用了
SqlDbType.[Type]
。您将要用为每一列指定的数据类型替换它。
所有代码都看起来像这样:
Using con As New SqlConnection("Data Source=LAPTOP-85ALBAVS\SQLEXPRESS;Initial Catalog=Portal;Integrated Security=True")
con.Open()
Dim recordExists As Boolean = False
Using cmd As New SqlCommand("SELECT * FROM Profile WHERE RollNo = @RollNo AND Name = @Name", con)
cmd.Parameters.Add("@RollNo", SqlDbType.VarChar).Value = txtRollNo.Text
cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = txtName.Text
Using reader As SqlDataReader = cmd.ExecuteReader()
recordExists = reader.HasRows
End Using
End Using
If recordExists Then
MessageBox.Show("User already registered! Please try again.", "Error", MessageBoxButtons.OK)
Else
Using cmd As New SqlCommand("INSERT INTO Profile VALUES (@RollNo, @Name, @Gender, @Address, @PhoneNo, @DateReg, @Faculty, @Course, @Semester)", con)
cmd.Parameters.Add("@RollNo", SqlDbType.[Type]).Value = txtRollNo.Text
cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = txtName.Text
cmd.Parameters.Add("@Gender", SqlDbType.VarChar).Value = cboGender.Text
cmd.Parameters.Add("@Address", SqlDbType.VarChar).Value = txtAddress.Text
cmd.Parameters.Add("@PhoneNo", SqlDbType.VarChar).Value = txtPhoneNo.Text
cmd.Parameters.Add("@DateReg", SqlDbType.VarChar).Value = dtpDateReg.Value
cmd.Parameters.Add("@Faculty", SqlDbType.VarChar).Value = cboFaculty.Text
cmd.Parameters.Add("@Course", SqlDbType.VarChar).Value = cboCourse.Text
cmd.Parameters.Add("@Semester", SqlDbType.VarChar).Value = cboSemster.Text
con.Open()
If cmd.ExecuteNonQuery() > 0 Then
MessageBox.Show("Profile successfully registered!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("Error. Please try again later.", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Using
End If
Using cmd As New SqlCommand("INSERT INTO Photo (Img, Pid) VALUES (@Img, @Pid)", con)
Using ms As New MemoryStream()
pbxImage.Image.Save(ms, pbxImage.Image.RawFormat)
cmd.Parameters.Add("@Img", SqlDbType.Image).Value = ms.ToArray()
cmd.Parameters.Add("@Pid", SqlDbType.VarChar).Value = txtName.Text
End Using
con.Open()
cmd.ExecuteNonQuery()
End Using
End Using
该代码未经测试,我没有使用环境,但是它应该可以为您提供一些帮助。
答案 1 :(得分:0)
在线发表评论和解释。
Private Sub OPCode()
Dim i As Integer
Dim j As Integer
Dim rollno = TextBox1.Text
Dim name = TextBox2.Text
Dim gender = ComboBox4.Text
Dim address = TextBox3.Text
Dim phoneno = CInt(TextBox4.Text) 'Unless your phone numbers are very different
'than the phone numbers here, the likelyhood of a user entering just numbers is
'nil. Change this to a string and a VarChar in the database
Dim datereg = dateTimePicker1.Value
Dim faculty = comboBox1.Text
Dim course = ComboBox2.Text
Dim semester = ComboBox3.Text
'The Using block ensures that your connection is closed and disposed
'Pass your connection string to the constructor of the connection
Using con As New SqlConnection("Data Source=LAPTOP-85ALBAVS\SQLEXPRESS;Initial Catalog=Portal;Integrated Security=True")
'Pass the Sql command text and connection to the Constructor of the command.
'NEVER, NEVER, NEVER allow user input to be passed directly to a database. Always use parameters.
Dim cmd As New SqlCommand("SELECT * FROM Profile WHERE RollNo= @RollNo and [Name]= @Name;", con)
cmd.Parameters.Add("@RollNo", SqlDbType.VarChar).Value = rollno
cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = name
con.Open()
Using rd As SqlDataReader = cmd.ExecuteReader()
'To validate whether duplication of typed in data by user occurs or not, if yes, error msg pop-up. If no, proceed and save the data into database
If rd.HasRows Then
MessageBox.Show("User already registered! Please try again.", "Error", MessageBoxButtons.OK)
'You don't want to go any further if the user is registered.
Exit Sub
End If
End Using
'Just use another new command variable to avoid confusion
'I think it is much better practice to list the fields.
Dim cmd2 As New SqlCommand("INSERT INTO Profile VALUES (@RollNo ,@Name,@Gender, @Address, @PhoneNo , @DateReg , @Faculty , @Course , @Semester);", con)
cmd2.Parameters.Add() 'etc.
i = cmd2.ExecuteNonQuery()
If i >= 1 Then
MessageBox.Show("Profile successfully registered!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("Error. Please try again later.", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
Exit Sub
End If
'To save the uploaded photo to table Photo
Dim command3 As New SqlCommand("Insert into Photo (Img, Pid) Values (@Img, @Pid)", con)
command3.Connection = con
Dim ms As New MemoryStream
pictureBox1.Image.Save(ms, pictureBox1.Image.RawFormat)
command3.Parameters.Add("@Img", SqlDbType.Image).Value = ms.ToArray()
command3.Parameters.Add("@Pid", SqlDbType.VarChar).Value = TextBox1.Text
j = command3.ExecuteNonQuery()
End Using
If j >= 1 Then
MessageBox.Show("Profile successfully registered!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("Error. Please try again later.", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Sub