system login using query select 1 - vb.net

I am trying to code the login page, here is my code:
'login form code
Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
Dim username As String = txtUsername.Text.Trim
Dim pwd As String = txtPassword.Text.Trim
Dim insertQry As String = "select 1 from UserInfo where username = '" & username & "' and userpassword = '" & pwd & "'"
Dim res As Boolean = executeReader(insertQry)
End Sub
database module
Imports System.Data.SqlClient
Module DBconn
Public conn_ As New SqlConnection("")
Public Function executeReader(ByVal query As String)
Try
Dim cmd As New SqlCommand(query, conn_)
conn_.Open()
Dim r2 As SqlDataReader = cmd.ExecuteReader()
Return True
Catch ex As Exception
Return False
End Try
End Function
End Module
My question is how to do validation of username and password check with select 1 query?

Take a look at this example, it does the following:
It returns the count of the primary key value in the SQL query (documentation)
It uses parameters to pass the values to the WHERE clause (documentation)
It uses ExecuteScalar to return a single value from the command (documentation)
Private Function ValidateLogin(ByVal username As String, ByVal password As String) As Boolean
Dim count As Integer = 0
'Declare the connection object
Using con As SqlConnection = New SqlConnection
'Wrap code in Try/Catch
Try
'Set the connection string
con.ConnectionString = "" 'TODO: set this value
'Create a new instance of the command object
Using cmd As SqlCommand = New SqlCommand("SELECT Count(UserInfoId) FROM UserInfo WHERE username=#username AND userpassword=#password", con)
'Parameterize the query
With cmd.Parameters
.Add("#username", SqlDbType.VarChar).Value = username
.Add("#password", SqlDbType.VarChar).Value = password
End With
'Open the connection
con.Open()
'Use ExecuteScalar to return a single value
count = Convert.ToInt32(cmd.ExecuteScalar())
'Close the connection
con.Close()
End Using
Catch ex As Exception
'Display the error
Console.WriteLine(ex.Message)
Finally
'Check if the connection object was initialized
If con IsNot Nothing Then
If con.State = ConnectionState.Open Then
'Close the connection if it was left open(exception thrown)
con.Close()
End If
End If
End Try
End Using
'Return row count is greater than 0
Return count > 0
End Function

Related

My Login form show OLE DB Query not working

I need to do login form in vb using role based MS Access. mdb file
but i got error Invalid Query Kindly solutions please.
Public Class login_module
'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\gasdb1.mdb
Dim loginerror As String
Dim ab As Integer
Public Function logins()
Dim DBConn As New ADODB.Connection
Dim user As New ADODB.Recordset
Dim Usernam As String
Dim UserDB As String
Dim passDB As String
Dim roleDB As String
Dim userfound As Boolean
Try
DBConn.Open("Provider = Microsoft.Jet.OLEDB.4.0;Data Source ='" & "E:\crime\crime.mdb'")
user.Open("user", DBConn, ADODB.CursorTypeEnum.adOpenStatic, ADODB.LockTypeEnum.adLockOptimistic)
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical)
Me.Hide()
End Try
userfound = False
logins = False
Usernam = "username ='" & TextBox1.Text & "'"
Do
Try
user.Find(Usernam)
Catch ex As Exception
MsgBox(ex.Message)
End Try
Debug.Print(user.ToString)
So Kindly Solve also i got error operation is not allowed when the object is closed. adodb.recordset.
Public Class login_module
Private ConStr As String = "Provider = Microsoft.Jet.OLEDB.4.0;Data Source =E:\crime\crime.mdb"
Private Function Logins(Name As String, PWord As String) As String
Dim RetVal As Object = Nothing
Dim Role As String
Dim sql = "Select Role From Users Where UserName = #Name And Password = #Password;"
Using cmd As New OleDbCommand(sql, New OleDbConnection(ConStr))
cmd.Parameters.Add("#Name", OleDbType.VarWChar).Value = Name
cmd.Parameters.Add("#Password", OleDbType.VarWChar).Value = PWord
cmd.Connection.Open()
RetVal = cmd.ExecuteScalar
End Using
If RetVal Is Nothing Then
Role = "Not Found"
Else
Role = RetVal.ToString
End If
Return Role
End Function
Private Sub btnLogIn_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
Dim Role As String = ""
Try
Role = Logins(txtUserName.Text, txtPassword.Text)
Catch ex As Exception
MessageBox.Show(ex.Message)
Exit Sub
End Try
Select Case Role
Case "Admin"
'Do something
Case "Supervisor"
'Do something
Case "Clerk"
'Do Something
Case Else
MessageBox.Show("No defined Role was returned.")
End Select
End Sub
End Class

Delete From Table error

i'm trying to create a delete button to delete a record ....
here's my code:
Dim SqlQuery As String = "DELETE FROM MyTable WHERE InvoiceNumber = " & id & ";"
'id is public shared as integer , which is ListView1.SelectedItems(0).Text
Dim SqlCommand As New OleDb.OleDbCommand
With SqlCommand
.CommandText = SqlQuery
.Connection = conn
.ExecuteNonQuery()
End With
I get an exception in .ExecuteNonQuery(), the error is
"ExecuteNonQuery() requires the command to have a transaction" ,
"Validate transaction" , "ExecuteReaderInternal"
assume that the database is connected, got info and delete button is button3 .
Also i will show you my whole form code:
Public Class Report
Public id As Integer
Public conn As New OleDb.OleDbConnection
Public connstring As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Ramy\Documents\Beach.accdb"
Private Property RivieraDataSet As Object
Private Sub Report_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
conn.Close()
End Sub
Private Sub Report_Load(sender As Object, e As EventArgs) Handles MyBase.Load
If conn.State = ConnectionState.Closed Then
Try
conn.ConnectionString = connstring
conn.Open()
MsgBox("DataBase opened successfully!", MsgBoxStyle.Exclamation)
loadlistview()
Catch ex As Exception
MsgBox(ex.ToString, MsgBoxStyle.Critical)
End Try
Else
MsgBox("DataBase Error!!", MsgBoxStyle.Critical)
End If
Dim reading As OleDb.OleDbDataReader
Dim cmd As New OleDb.OleDbCommand
Dim trans As OleDb.OleDbTransaction
trans = conn.BeginTransaction
cmd.CommandText = "SELECT * FROM MyTable"
cmd.Connection = conn
cmd.Transaction = trans
reading = cmd.ExecuteReader
Dim i
Do While reading.Read
i = Val(reading.Item("Total")) + i
Loop
TextBox7.Text = i
TextBox7.Text = Convert.ToDecimal(TextBox7.Text).ToString("N2") & " L.E"
End Sub
Sub loadlistview()
ListView1.FullRowSelect = True
ListView1.MultiSelect = False
ListView1.View = View.Details
ListView1.Columns.Clear()
ListView1.Items.Clear()
ListView1.Columns.Add("No", 30, HorizontalAlignment.Left)
ListView1.Columns.Add("InvoiceDate", 125, HorizontalAlignment.Left)
ListView1.Columns.Add("PersonsNumber", 70, HorizontalAlignment.Left)
ListView1.Columns.Add("PersonPrice", 80, HorizontalAlignment.Left)
ListView1.Columns.Add("CashierName", 100, HorizontalAlignment.Left)
ListView1.Columns.Add("Total", 100, HorizontalAlignment.Left)
Dim SqlQuery As String = "SELECT * FROM MyTable"
Dim SqlCommand As New OleDb.OleDbCommand
Dim SqlAdapter As New OleDb.OleDbDataAdapter
Dim table As New DataTable
With SqlCommand
.CommandText = SqlQuery
.Connection = conn
End With
With SqlAdapter
.SelectCommand = SqlCommand
.Fill(table)
End With
For i = 0 To table.Rows.Count - 1
With ListView1
.Items.Add(table.Rows(i)("InvoiceNumber"))
With .Items(.Items.Count - 1).SubItems
.Add(table.Rows(i)("InvoiceDate"))
.Add(table.Rows(i)("PersonsNumber"))
.Add(table.Rows(i)("PersonPrice"))
.Add(table.Rows(i)("CashierName"))
.Add(table.Rows(i)("Total"))
End With
End With
Next
End Sub
Private Sub ListView1_MouseClick(sender As Object, e As MouseEventArgs) Handles ListView1.MouseClick
Dim SqlQuery As String = "SELECT * FROM MyTable"
Dim SqlCommand As New OleDb.OleDbCommand
Dim SqlAdapter As New OleDb.OleDbDataAdapter
Dim table As New DataTable
With SqlCommand
.CommandText = SqlQuery
.Connection = conn
End With
With SqlAdapter
.SelectCommand = SqlCommand
End With
If ListView1.SelectedItems.Count > 0 Then
id = ListView1.SelectedItems(0).Text
TextBox1.Text = id
TextBox6.Text = ListView1.SelectedItems(0).SubItems(1).Text
TextBox3.Text = ListView1.SelectedItems(0).SubItems(2).Text
TextBox4.Text = ListView1.SelectedItems(0).SubItems(3).Text
TextBox2.Text = ListView1.SelectedItems(0).SubItems(4).Text
TextBox5.Text = ListView1.SelectedItems(0).SubItems(5).Text
End If
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim SqlQuery As String = "DELETE FROM MyTable WHERE InvoiceNumber = " & id & ";"
'id is public shared as integer , which is ListView1.SelectedItems(0).Text
Dim SqlCommand As New OleDb.OleDbCommand
With SqlCommand
.CommandText = SqlQuery
.Connection = conn
.ExecuteNonQuery()
End With
End Sub
End Class
I was searching for a mistake in my delete btn code for hours , but i can see everything is good..... but .ExecuteNonQuery() is so annoying .
In your Form_Load you open a transaction for your GLOBAL connection.
This means that every command executed using that connection should be informed of this transaction (and you do it in the Form_Load event setting the Command.Transaction property).
But in other parts of your program, executing a command with that connection and not setting the Transaction property will raise the mentioned error.
Looking at your code above I would suggest to remove altogether the Transaction because, as is, you don't need it.
Simply remove these lines in Form_Load
Dim trans As OleDb.OleDbTransaction
trans = conn.BeginTransaction
...
cmd.Transaction = trans
Instead, if for motives not apparent from the code above, you insist in keeping the Transaction then you should create the command from the connection so the transaction is passed to the command.
Dim SqlQuery As String = "DELETE FROM MyTable WHERE InvoiceNumber = " & id & ";"
Dim SqlCommand = conn.CreateCommand()
With SqlCommand
....
End With
By the way, I really suggest you to remove that global connection variable. It is only a source of problems (check if open, transactions etc...) Just make a function that creates it for you and use it in a Using Statement whenever you need it
Public Function GetConnection() As OleDb.OleDbConnection
Dim conn = New OleDb.OleDbConnection(connstring)
conn.Open()
return conn
End Function
And use it with Using Statement that close and dispose the enclosed object also in case of exceptions
Using conn = GetConnection()
Using command = conn.CreateCommand()
With command
command.CommandText = "DELETE FROM MyTable WHERE InvoiceNumber = " & id & ";"
command.ExecuteNonQuery()
End With
End Using
End Using
Pay also attention at possible sql injection scenarios. In your situation (reading an integer from a ListView) there are few problems, but a parameterized query is always better

Checking a PIN number is correct according to it's card number

I'm currently working on an assignment for college that I'm really stuck on. I have to create an application to simulate an ATM machine using Visual Basic 2010. I'm currently stuck trying to check whether the PIN number entered in the text box is correct for the card number selected in the combo box. If the user enters the PIN incorrectly three times, the card is confiscated. I am getting an error message at the moment saying "Object variable or With block variable not set". Below is the code I have written:
Imports System.Data.OleDb
Public Class PinEntry
Public connectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source = C:\Users\ben\Documents\Programming\Year 2\Visual Studio\Assignment2\BankOfGlamorgan\EDP2011-BoG.mdb"
Friend connectionBG As New OleDbConnection
Dim ds As New DataSet
Dim da As New OleDbDataAdapter
Dim commandCardNumber As New OleDbCommand()
Dim dr As OleDbDataReader
Dim pinErrorCount As Integer
Dim ATMCardsBindingSource As New BindingSource
Dim SqlCommandCheckPIN As New OleDbCommand
Dim SqlCommandConfiscate As New OleDbCommand
Private Sub PinEntry_Load(sender As Object, e As EventArgs) Handles MyBase.Load
connectionBG.ConnectionString = connectionString
commandCardNumber.Connection = connectionBG
commandCardNumber.CommandType = CommandType.Text
commandCardNumber.CommandText = "SELECT cardNumber FROM ATMCards"
Try
connectionBG.Open()
da.SelectCommand = commandCardNumber
da.Fill(ds, "ATMCards")
cmbCardNumber.DataSource = ds.Tables("ATMCards")
cmbCardNumber.DisplayMember = "cardNumber"
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
connectionBG.Close()
End Try
End Sub
Private Sub btnEnterPin_Click(sender As Object, e As EventArgs) Handles btnEnterPin.Click
Try
Me.connectionBG.Open()
Dim PIN As String
Dim cardNo As String
PIN = Me.txtPIN.Text
cardNo = Me.ATMCardsBindingSource.Current("cardNumber")
Me.SqlCommandCheckPIN.Parameters("#PIN").Value = PIN
Me.SqlCommandCheckPIN.Parameters("#cardNumber").Value = cardNo
Dim dr As OleDbDataReader = Me.SqlCommandCheckPIN.ExecuteReader()
If dr.HasRows And pinErrorCount <= 2 Then
My.Forms.Menu.ShowDialog()
dr.Close()
pinErrorCount = 0
txtPIN.Text = ""
ElseIf pinErrorCount = 2 Then
dr.Close()
MessageBox.Show("PIN Entered Incorrectly Three Times Card Now Confiscated", "Card Taken", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
cardNo = Me.ATMCardsBindingSource.Current("cardNumber")
Me.SqlCommandConfiscate.Parameters("#cardNumber").Value = cardNo
Me.SqlCommandConfiscate.ExecuteNonQuery()
Else
pinErrorCount = pinErrorCount + 1
MessageBox.Show("Incorrect PIN Please Try Again.", "Incorrect PIN", MessageBoxButtons.OK, MessageBoxIcon.Error)
txtPIN.Text = ""
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
Me.connectionBG.Close()
End Try
End Sub
End Class
Updated code below:
Imports System.Data.OleDb
Public Class PinEntry
Public connectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source = C:\Users\ben\Documents\Programming\Year 2\Visual Studio\Assignment2\BankOfGlamorgan\EDP2011-BoG.mdb"
Friend connectionBG As New OleDbConnection
Dim ds As New DataSet
Dim da As New OleDbDataAdapter
Dim commandCardNumber, commandPinNumber As New OleDbCommand()
Dim dr As OleDbDataReader
Dim pinErrorCount, cardNumber, PIN As Integer
Dim oForm As Menu
Dim userInput As String
Private Sub PinEntry_Load(sender As Object, e As EventArgs) Handles MyBase.Load
connectionBG.ConnectionString = connectionString
commandCardNumber.Connection = connectionBG
commandCardNumber.CommandType = CommandType.Text
commandCardNumber.CommandText = "SELECT cardNumber FROM ATMCards"
commandPinNumber.Connection = connectionBG
commandPinNumber.CommandType = CommandType.Text
commandPinNumber.CommandText = "SELECT PIN FROM ATMCards WHERE cardNumber = ?"
Try
connectionBG.Open()
da.SelectCommand = commandCardNumber
da.Fill(ds, "ATMCards")
cmbCardNumber.DataSource = ds.Tables("ATMCards")
cmbCardNumber.DisplayMember = "cardNumber"
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
connectionBG.Close()
End Try
End Sub
Private Sub btnEnterPin_Click(sender As Object, e As EventArgs) Handles btnEnterPin.Click
cardNumber = Convert.ToInt16(cmbCardNumber.Text)
commandPinNumber.Parameters.Add(New OleDbParameter())
commandPinNumber.Parameters(0).Value = cardNumber
Try
connectionBG.Open()
dr = commandPinNumber.ExecuteReader()
While dr.Read()
PIN = dr.Item("PIN").ToString
End While
dr.Close()
If PIN = userInput Then
MsgBox("Correct PIN")
Else
MsgBox("Incorrect PIN")
End If
Catch ex As Exception
MsgBox(ex.Message)
Finally
connectionBG.Close()
End Try
End Sub
Private Sub txtPIN_TextChanged(sender As Object, e As EventArgs) Handles txtPIN.TextChanged
userInput = txtPIN.Text
End Sub
End Class
OleDBCOmmand objects are typically used in a more disposable way than as module level variables. In order to work, they also need a SQL string and a Connection object associated with them. Ex:
Dim sql As String = "SELECT etc etc etc WHERE something = ?"
Using cmd As New OleDbCommand(Sql, dbCon)
cmd.Parameters.AddWithValue("#p1", myVar)
cmd.Parameters.AddWithValue("#p2", myVar)
Dim rdr As OleDbDataReader = cmd.ExecuteReader
If rdr.HasRows Then
' do something interesting
End If
End Using
Here, both the SQL and DB Connection are associated with the Command Object when it is created. The Using block assures it is properly disposed of when we are done with it.
Also, OleDbCommand objects do not support named parameters. Usually, it just ignores them. The right way for Paramters is shown (ie AddWithValue) where you replace each ? placeholder in the SQL string in order with the actual value. Do be sure the data type matches. If PIN is a number, you must add a number, not Text.
For the SQL, you are testing the PIN entered against a card number, so those are the param values. Depending on how you construct the SQL you can either see if the PIN in the DB matches the one they gave OR just see if you get any rows back.

How to read and move read content via SQL into variables within VB.net and use a connectionstring from a module in forms?

This is my first question, by the way - and I'm not sure exactly how to ask, or say what's wrong. There's 3 things I can't sort so any help would be appreciated.
Module:
This and the first (login) form work as they are but I couldn't get either Form to reference con.connectionstring for them to use without having to re-use the string contained in "" (as they do below) - my attempts ended up with errors including saying that the state couldn't be changed as the connection was already open, but I'd like the same one string to be referenced from the Forms.
Module ConnectionModule
Public con As OleDb.OleDbConnection = New OleDb.OleDbConnection
Public da As OleDb.OleDbDataAdapter
Public ds As DataSet = New DataSet
Public Path As String = Application.StartupPath
Public Sub OpenDb()
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=F:\Computing A2\CG4 Coursework\Greener Cleaning\dbCoursework.accdb"
con.Open()
If con.State = ConnectionState.Closed Then
MsgBox("Connection to db not made.")
End If
End Sub
Public CurrentUser As String = Nothing
End Module
The First Form:
Public Class LoginForm
Private Sub LoginForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
OpenDb()
con.Close()
End Sub
Private Sub btnLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLogin.Click
Dim ID As String = txtID.Text
Dim Pass As String = txtPassword.Text
If IsNumeric(ID) = False Or ID.Length > 4 Or Pass = Nothing Then
MsgBox("Staff ID is a 4-digit number and Password must not be blank.")
Else
Dim con As New System.Data.OleDb.OleDbConnection()
OpenDb()
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=F:\Computing A2\CG4 Coursework\Greener Cleaning\dbCoursework.accdb"
Try
Dim sql As String = "SELECT * FROM tblStaff WHERE [StaffID]='" & ID & "' AND [Pword] = '" & Pass & "'"
Dim sqlCom As New System.Data.OleDb.OleDbCommand(sql)
'Open Database Connection
sqlCom.Connection = con
con.Open()
Dim sqlRead As System.Data.OleDb.OleDbDataReader = sqlCom.ExecuteReader()
If sqlRead.Read() Then 'Correct:
MenuForm.Show()
Me.Hide()
CurrentUser = ID
Else 'Incorrect:
MsgBox("Staff ID or Password incorrect.")
txtPassword.Text = ""
txtID.Text = ""
txtID.Focus()
End If
Catch ex As Exception
MsgBox("Database Connection Error.")
End Try
con.Close()
End If
End Sub
End Class
A form to change the password:
The problem here is that lblUser (A clarification for the user to tell them which password will be changed) only outputs the data already within the program as a variable: CurrentUser (as assigned upon successful login). No error is produced but the full name of the user isn't shown (or possibly read from the database).
I'm also unsure how the UPDATE SQL command should be contained within the second procedure, btnAccept_click, here. What the syntax is, basically. I haven't found a clear example to look at.
Imports System.Data.OleDb
Public Class PasswordForm
Private Sub PasswordForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
con = New System.Data.OleDb.OleDbConnection()
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=F:\Computing A2\CG4 Coursework\Greener Cleaning\dbCoursework.accdb"
Dim Returned(2) As String
CurrentUser = CurrentUser
Dim cmd As OleDbCommand = New OleDbCommand("SELECT [Title], [Forename], [Surname] FROM tblStaff WHERE [StaffID]='" & CurrentUser & "'", con)
Try
con.Open()
Dim reader As OleDbDataReader = cmd.ExecuteReader()
If reader.HasRows Then
reader.Read()
'Makes db contents variables
Returned(0) = reader.Item("[Title]").ToString
Returned(1) = reader.Item("[Forename]").ToString
Returned(2) = reader.Item("[Surname]").ToString
End If
reader.Close()
Catch ex As Exception
Me.Hide()
MsgBox("Database Connection Error.")
Finally
con.Close()
End Try
lblUser.Text = "Current User: " & CurrentUser & Returned(0) & Returned(1) & Returned(2)
''Only outputs CurrentUser
End Sub
Private Sub btnAccept_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAccept.Click
Dim Current As String = txtCurrent.text
Dim NewPass As String = txtNew.Text
'Verification
If txtNew.Text = txtConfirm.Text And NewPass.Length <= 20 Then
Dim cmd As OleDbCommand = New OleDbCommand("UPDATE tblStaff SET [Pword]='" & NewPass & "' WHERE [StaffID]='" & CurrentUser & "'", con)
End If
End Sub
End Class
Thank you, again, for anyone with ideas (especially exact code).
Oh and throughout what's here there are no errors thrown. Just missing content.
you are opening the connection in openDB() and you are trying to open it again in form1, this will throw the error you are getting. So comment all the con related lines in your form. Same comment for your passowrd form also.
'Dim con As New System.Data.OleDb.OleDbConnection()
OpenDb()
'con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=F:\Computing A2\CG4 Coursework\Greener Cleaning\dbCoursework.accdb"
Try
Dim sql As String = "SELECT * FROM tblStaff WHERE [StaffID]='" & ID & "' AND [Pword] = '" & Pass & "'"
Dim sqlCom As New System.Data.OleDb.OleDbCommand(sql)
'Open Database Connection
sqlCom.Connection = con
'con.Open()
...
end try

vb2008 insert and update record using one button

I am trying to make a glossary. I have a form with a listbox, 2 textboxes, and a save button.
The listbox is now populated with words from the database, and when a word is selected, its definition will display in textbox2.
The user can add a record by filling the textbox1 with a new word and textbox2 with its definition,and clicking the save button. If the new word already existed it will not allow to save a new record, also if there's a null value between the 2 textboxes. If it doesn't exist it will be inserted on the table and the new word will be added to the listbox.
The user can also update the record by selecting first a word on the list then edit the word and/or definition and clicking the save button.
I already got the updating part to work but I have problem in inserting a new record. I can't do it properly. The glossary table has only 2 fields: word, definition. Here's my code:
Dim myCmd As New MySqlCommand
Dim myReader As MySqlDataReader
Dim myAdptr As New MySqlDataAdapter
Dim myDataTable As New DataTable
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
Call Connect()
With Me
If Blank() = False Then
If Duplicate() = False Then
STRSQL = "insert into glossary values (#word, #def)"
myCmd.Connection = myConn
myCmd.CommandText = STRSQL
myCmd.Parameters.AddWithValue("word", txtNew.Text)
myCmd.Parameters.AddWithValue("def", txtdefine.Text)
myCmd.ExecuteNonQuery()
myCmd.Dispose()
MsgBox("Record Added")
Dim word As String
word = txtNew.Text
lstword.Items.Add(word)
'myConn.Close()
'Me.FillListbox()
Else
myConn.Open()
STRSQL = "Update glossary set word = #term, definition = #mean where word = #term"
myCmd.Connection = myConn
myCmd.CommandText = STRSQL
myCmd.Parameters.AddWithValue("term", txtNew.Text)
myCmd.Parameters.AddWithValue("mean", txtdefine.Text)
myCmd.ExecuteNonQuery()
myCmd.Dispose()
MsgBox("Record Updated", MsgBoxStyle.Information, "New word added")
End If
End If
End With
End Sub
Public Function Blank() As Boolean
Call Connect()
With Me
If .txtNew.Text = "" Or .txtdefine.Text = "" Then
Blank = True
MsgBox("Cannot save! Term and definition should not contain null value", MsgBoxStyle.Critical, "Unable to save")
Else
Blank = False
End If
End With
End Function
Public Function Duplicate() As Boolean
Call Connect()
With Me
STRSQL = "Select * from glossary where word = '" & txtNew.Text & "'"
myCmd.Connection = myConn
myCmd.CommandText = STRSQL
If myDataTable.Rows.Count <> 0 Then
Duplicate = True
'MsgBox("Word already exist. Please check the word.", MsgBoxStyle.Critical, "Duplicate.")
Else
Duplicate = False
End If
myConn.Close()
End With
End Function
this is my connection module:
Public myConnectionString As String
Public STRSQL As String
Public myConn As New MySqlConnection
Public Sub Connect()
With myConn
Try
If .State = ConnectionState.Open Then
.Close()
End If
myConnectionString = "Database=firstaidcqs;Server=localhost;Uid=root;Password="
.ConnectionString = myConnectionString
.Open()
'MsgBox("Successful Connection")
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical, "Connection Error")
.Close()
End Try
End With
End Sub
Public Sub Disconnect()
With myConn
.Close()
.Dispose()
End With
End Sub
How can I make this work properly?
You are using global variables in all the code above.
myConn and myCmd
in particular, you call Dispose on myCmd but I can't see anywhere the reinitialization of the object with New. Also, forgetting for a moment the myCmd.Dispose problem, you don't reset the myCmd parameters collection. In this way you end up with a wrong Parameter collection for the command executed, Also don't forget to open the connection for the insert part. (and close it for both parts)
You could easily avoid the use of unnecessary global variables
....
If Duplicate() = False Then
STRSQL = "insert into glossary values (#word, #def)"
Using myCmd = new MySqlCommand(STRSQL, myConn)
myConn.Open()
myCmd.Parameters.AddWithValue("word", txtNew.Text)
myCmd.Parameters.AddWithValue("def", txtdefine.Text)
myCmd.ExecuteNonQuery()
End Using
myConn.Close()
.....
Else
STRSQL = "Update glossary set word = #term, definition = #mean where word = #term"
Using myCmd = new MySqlCommand(STRSQL, myConn)
myConn.Open()
myCmd.Parameters.AddWithValue("term", txtNew.Text)
myCmd.Parameters.AddWithValue("mean", txtdefine.Text)
myCmd.ExecuteNonQuery()
End Using
myConn.Close()
.....
A better solution will be changing the Connect() method to return the initialized connection instead of using a global variable. In that way you could enclose also the creation and destruction of the connection in a Using statement
Using myConn as MySqlConnection = Connect()
.......
End Using
For this to work you need to change the code of Connect in this way
Public Function Connect() as MySqlConnection
Dim myConn As MySqlConnection
myConnectionString = "Database=firstaidcqs;Server=localhost;Uid=root;Password="
myConn = New MySqlConnection(myConnectionString)
myConn.Open()
return myConn
End Sub
No need of a Disconnect function because you will always use the Using statement that will close the connection for you, no need to have a global variable to keep the connection because you will reopen the connection every time you need it and close afterward. Don't think that this is not performant because ADO.NET implements connection pooling (It is an MSDN article for SqlServer, but the concept applies also to MySql)
yay!! I got it working now :D (my apology, it took me a long time to finish this..i'm still learning). Here's my final code:
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
Call Connect()
If Blank() = False Then
If Duplicate() = False Then
STRSQL = "insert into glossary values (#word, #def)"
Using myCmd = New MySqlCommand(STRSQL, myConn)
myConn.Open()
myCmd.Parameters.AddWithValue("word", txtNew.Text)
myCmd.Parameters.AddWithValue("def", txtdefine.Text)
myCmd.ExecuteNonQuery()
End Using
myConn.Close()
MsgBox("Record Added")
Dim word As String
word = txtNew.Text
lstword.Items.Add(word)
myConn.Close()
Else
STRSQL = "Update glossary set word = #term, definition = #mean where word = #term"
Using myCmd = New MySqlCommand(STRSQL, myConn)
myConn.Open()
myCmd.Parameters.AddWithValue("term", txtNew.Text)
myCmd.Parameters.AddWithValue("mean", txtdefine.Text)
myCmd.ExecuteNonQuery()
End Using
myConn.Close()
MsgBox("Record Updated", MsgBoxStyle.Information, "New word added")
Dim str As String
str = txtNew.Text
myConn.Close()
End If
End If
End Sub
Public Function Blank() As Boolean
Call Connect()
With Me
If .txtNew.Text = "" Or .txtdefine.Text = "" Then
Blank = True
MsgBox("Cannot save! Term and definition should not contain null value", MsgBoxStyle.Critical, "Unable to save")
Else
Blank = False
End If
End With
End Function
Public Function Duplicate() As Boolean
Dim dset As New DataSet
Call Connect()
With Me
STRSQL = "Select * from glossary where word = '" & txtNew.Text & "'"
myCmd.Connection = myConn
myCmd.CommandText = STRSQL
myAdptr.SelectCommand = myCmd
myAdptr.Fill(dset, "glossary")
myDataTable = dset.Tables("glossary")
If myDataTable.Rows.Count > 0 Then
Duplicate = True
'MsgBox("Word already exist. Please check the word.", MsgBoxStyle.Critical, "Duplicate.")
Else
Duplicate = False
End If
myConn.Close()
End With
End Function
I still used the my first module but I already removed the Disconnect() function. #Steve - thank you very much for the help sir, I'll try using what you suggested to me some time..maybe on my next program. God speed!! :)