SQL Server : delete user - sql

I'm trying to write a query to delete a user registration from my SQL Server database, but when I try to delete a user, I get this error:
System.InvalidOperationException: 'ExecuteReader: Connection property has not been initialized.'
My code:
Public Class DeleteForm
Private Sub btnDelete_Click(sender As Object, e As EventArgs) Handles btnDelete.Click
Dim conn = New SqlConnection("Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=dbProject;Integrated Security=True")
Using cmd = New SqlCommand("SELECT * FROM tblLogin WHERE username = " & txtUsername.Text, conn)
conn.Open()
Dim reader As SqlClient.SqlDataReader = cmd.ExecuteReader
If reader.Read = True Then
If txtUserPass.Text = txtCheckPass.Text Then
Dim deleteOk As Integer = MessageBox.Show("This cant be undone!" & vbCrLf & "Are you sure?", "Warning!", MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
If deleteOk = DialogResult.Yes Then
Dim queryDelete As String = "DELETE FROM tblLogin WHERE username = " & txtUsername.Text & " and password = " & txtPassword.Text
Dim cmdDelete As New SqlClient.SqlCommand(queryDelete, conn)
If conn.State = ConnectionState.Closed Then conn.Open()
reader.Close()
cmdDelete.ExecuteNonQuery()
MsgBox("Cancellazione eseguita correttamente!")
cmdDelete.Dispose()
conn.Close()
ElseIf deleteOk = DialogResult.No Then
End If
Else
MsgBox("The passwords arent matching!")
End If
Else
MsgBox("User not found")
conn.Close()
txtUsername.Clear()
txtUsername.Focus()
txtUserPass.Clear()
txtCheckPass.Clear()
End If
End Using
End Sub
End Class

You need to open connection before you can create a command.
i.e.
Dim conn = New SqlConnection("Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=dbProject;Integrated Security=True")
conn.Open()
Using cmd = New SqlCommand(....
However your current code contains SQL Injection. You should not concatenate strings go get your SQL. You should use parameters. See this answer for better explanation about the application.
Also it is never a good practice to store passwords in plain text. Ever. You should store hash of password only and compare the hashes rather than plain-text. Read this answer for reference. And more background info on why you should hash

Related

How do I make it so everyone has a separate account when they login

I am trying to create a login system for a revision app. However, I was wondering if there was a way where everyone can have separate accounts.
Private Sub Btnlogin_Click(sender As Object, e As EventArgs) Handles Btnlogin.Click
Dim sqlstring As String
sqlstring = "select * FROM login where username = '" & txtusername.Text & "'"
connection.Open()
dataadapter = New OleDb.OleDbDataAdapter(sqlstring, connection)
dt.Clear()
dataadapter.Fill(dt)
connection.Close()
If dt.Rows.Count = 0 Then
MsgBox("no such user")
Exit Sub
End If
If dt.Rows(0)(2) = Txtpassword.Text Then
Flashcard.Show()
Else
Txtpassword.Text = ""
txtusername.Text = ""
MsgBox("Invalid username and password combination")
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Register.Show()
End Sub
That's the code I have if a user already has an account.
Imports System.Data.OleDb
Public Class Register
Dim pro As String
Dim connstring As String
Dim command As String
Dim myconnection As OleDbConnection = New oledbconnection
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
pro = "provider=microsoft.ACE.OLEDB.12.0;Data Source=flashcard login.accdb"
connstring = pro
myconnection.ConnectionString = connstring
myconnection.Open()
command = " insert into login ([username],[password]) values ('" & TextBox1.Text & "','" & TextBox2.Text & "')"
Dim cmd As OleDbCommand = New OleDbCommand(command, myconnection)
cmd.Parameters.Add(New OleDbParameter("username", CType(TextBox1.Text, String)))
cmd.Parameters.Add(New OleDbParameter("password", CType(TextBox1.Text, String)))
MsgBox("You have successfully signed up!")
Form1.Show()
Try
cmd.ExecuteNonQuery()
cmd.Dispose()
myconnection.Close()
TextBox1.Clear()
TextBox2.Clear()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
End Class
That's the code if the user presses the register button (does not have an account).
This code works where the user can succesfully login or register, but the problem is that everyone will have the same windows form. So, I was wondering if there was a way to make each windows form unique to each user?
You can declare and initialize a variable on the same line. The only information you need is if the userName and password exist in the database. Don't pull down data your don't need. You can get this with Count.
Always declare and dispose the connection and command it the method where they are used. Both of these objects need to be disposed so that their unmanaged resources can be released. Using... End Using blocks handle this.
Always use parameters to avoid sql injection. In OleDb the order that the parameters appear in the sql string must match the order that they are added to the parameters collection.
Don't open the connection until directly before the .Execute...
Private ConStr As String = "provider=microsoft.ACE.OLEDB.12.0;Data Source=flashcard login.accdb" '"Your connection string"
Private Sub Btnlogin_Click(sender As Object, e As EventArgs) Handles Btnlogin.Click
Dim rowCount As Integer
Dim sqlstring = "select Count(*) FROM login where [username] = #UserName ANd [password] = #password;"
Using connection As New OleDbConnection(ConStr),
cmd As New OleDbCommand(sqlstring, connection)
cmd.Parameters.Add("#UserName", OleDbType.VarChar).Value = txtusername.Text
connection.Open()
rowCount = CInt(cmd.ExecuteScalar)
End Using
If rowCount = 0 Then
MsgBox("no such user")
Else
Flashcard.Show()
End If
End Sub
Same ideas for the insert. A text box's Text property is always a String so you don't have to convert it.
You are not doing the parameters correctly. You are not using these parameters because the don't appear in the CommandText
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Command = " insert into login ([username],[password]) values (#UserName, #Password);"
Try
Using myconnection As New OleDbConnection(ConStr),
cmd As OleDbCommand = New OleDbCommand(Command, myconnection)
cmd.Parameters.Add("#UserName", OleDbType.VarChar).Value = TextBox1.Text
cmd.Parameters.Add("#Password", OleDbType.VarChar).Value = TextBox2.Text
myconnection.Open()
cmd.ExecuteNonQuery()
End Using
Catch ex As Exception
MsgBox(ex.Message)
Exit Sub
End Try
MsgBox("You have successfully signed up!")
Form1.Show()
TextBox1.Clear()
TextBox2.Clear()
End Sub
Finally, and very important. You should never store passwords as plain text. Look into salting and encrypting.

Confirmation of Old Password

I am having a problem in my condition of changing password. I want to make it simple by confirming the old password and then change the password. Here is my code
Private Sub btnCChangePass_Click(sender As Object, e As EventArgs) Handles btnCChangePass.Click
Dim ConnString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\VB.net\My Projects\InventoryData.accdb"
Dim SqlString As String = "Update Cridentials SET [Password] = #pass"
Dim pass As String = "SELECT [Password] from Cridentials"
Dim conn As New OleDbConnection(ConnString)
conn.Open()
'this part is my problem
If (txtCOldPass.Text <> pass) Then
MsgBox("Wrong Old Password", MsgBoxStyle.Critical, "Password not matched")
ElseIf txtCOldPass.Text = Nothing And txtCNewPass.Text = Nothing And txtCConPass.Text = Nothing Then
MsgBox("Please submit the following information", MsgBoxStyle.Critical, "Incomplete")
ElseIf txtCNewPass.Text <> txtCConPass.Text Then
MsgBox("New Password and Confirm Password in not matached", MsgBoxStyle.Critical, "Incomplete")
Else
Using con As New OleDbConnection(ConnString)
Using cmd As New OleDbCommand(SqlString, con)
cmd.CommandType = CommandType.Text
cmd.Parameters.AddWithValue("#pass", txtCNewPass.Text)
con.Open()
cmd.ExecuteNonQuery()
con.Close()
End Using
End Using
MsgBox("Changing password Success!", MsgBoxStyle.Information, "Successs!")
Me.Close()
Form1.Show()
End If
txtCOldPass.Focus()
txtCOldPass.Clear()
txtCNewPass.Clear()
txtCConPass.Clear()
End Sub

How can I make my MsgBox Appear if the Equip_No is not equal to the value in the Equip_no Textbox?

I am using a visual studio 2010 and Microsoft Sql server 2005.
I want to make the MsgBox("Unable to delete. Equipment Number is not found!", vbInformation, "Error") appear whenever a user enters an incorrect Equip_No.
Any help is appreciated. Thanks!
Private Sub Delete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Delete.Click
If MessageBox.Show("Do you really want to delete this record?", "Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) = DialogResult.No Then
MsgBox("Operation cancelled")
Exit Sub
End If
'If Command.CommandText = "SELECT FROM dbo.inhouse_hardware_marterfile_tbl WHERE Equip_No = #Equip_No" Then
Try
Dim Command As New SqlCommand
Dim con As New SqlConnection("Server=HPC-107;Database=MRPdb;integrated security= ...")
con.Open()
Command.Connection = con
Command.CommandText = " DELETE FROM dbo.inhouse_hardware_marterfile_tbl WHERE Equip_No = '" & Equip_No.Text & "'"
Dim da As New SqlDataAdapter
da.SelectCommand = Command
da.DeleteCommand = Command
Command.ExecuteNonQuery()
msgdeleted()
con.Close()
Catch ex As Exception
End Try
'Else : MsgBox("Unable to delete. Equipment Number is not found!", vbInformation, "Error")
'End If
'Command.Parameters.AddWithValue("#Equip_No", Equip_No.Text)
Grid()
ClearTextBoxes()
End Sub
The ExecuteNonQuery method returns an integer that is the number of rows affected by the command.
In your case, if the number is zero, then you could print your message
Dim result = Command.ExecuteNonQuery()
if result = 0 then
MessageBox.Show("Unable to delete. Equipment Number is not found!")
else
MessageBox.Show("Record deleted")
End if
Said that, please take note that.
An SqlDataAdapter is not required in this context.
You should use a parameterized query and not a string concatenation
Dim Command As New SqlCommand
Dim con As New SqlConnection("Server=HPC-107;Database=MRPdb;integrated security= ...")
con.Open()
Command.Connection = con
Command.CommandText = "DELETE FROM dbo.inhouse_hardware_marterfile_tbl " & _
"WHERE Equip_No = #eqno"
Command.Parameters.AddWithValue("#eqno", Equip_No.Text)
Dim result = Command.ExecuteNonQuery()

How to retrieve data from Access Database, when user are login to the program?

to all my senior. I'm doing an assignment about Music Sales System.
When the system begin will start a form "Login.vb", it allow the user to login with Staff ID and Password. After that, if login successful it will show the name of the staff in a textbox.
Could any senior help me or teach me how to retrieve the name when the staff login to the system?
Furthermore, I also like to retrieve picture from Access Database, hope can get some help from here.
I'm using Jet.Oledb.4.0.
Thank You.
Below is my Login.vb code
Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
Dim Connection As New Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Music_Sales_Database.mdb;")
Dim Command As New Data.OleDb.OleDbCommand("SELECT [Staff_ID] FROM [Staff] WHERE [Staff_IDField] = Staff_ID AND [PasswordField] = Password", Connection)
Dim StaffIDParam As New Data.OleDb.OleDbParameter("Staff_ID", Me.txtStaff_ID.Text)
Dim PasswordParam As New Data.OleDb.OleDbParameter("Password", Me.txtPassword.Text)
Command.Parameters.Add(StaffIDParam)
Command.Parameters.Add(PasswordParam)
Command.Connection.Open()
Dim Reader As Data.OleDb.OleDbDataReader = Command.ExecuteReader()
If txtStaff_ID.Text = "" Then
MessageBox.Show("Staff ID and Password cannot be empty, please try again.", "Login Failed", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
ElseIf txtPassword.Text = "" Then
MessageBox.Show("Staff ID and Password cannot be empty, please try again.", "Login Failed", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
ElseIf Reader.HasRows Then
MessageBox.Show("You are authenticated.", "Login Successful", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
MyPlayer.SoundLocation = path & LogOnSound
MyPlayer.Play()
txtPassword.Text = ""
Me.Hide()
Main_System.Show()
Else
MessageBox.Show("Invalid Staff ID or Password, please try again.", "Login Failed", MessageBoxButtons.OK, MessageBoxIcon.Error)
txtPassword.Text = ""
txtPassword.Focus()
End If
Command.Connection.Close()
End Sub
******BELOW is the program that Im coding, but still coding.......coz Im still new in VB.....hope can get some help
Dim Connection As New OleDb.OleDbConnection
Dim Command As OleDb.OleDbCommand
Dim Reader As OleDb.OleDbDataReader
Dim DBPath As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Music_Sales_Database.mdb;"
Dim Image() As Byte
Private Sub RetrieveStaffInformation()
Connection.ConnectionString = DBPath
Connection.Open()
Command = Connection.CreateCommand
Command.CommandText = "SELECT Staff.* FROM Staff"
Reader = Command.ExecuteReader
Image = CType(Reader(0), Byte())
Dim MS As New System.IO.MemoryStream(Image)
Dim bmImage As New Bitmap(MS)
picStaff.Image = bmImage
picStaff.Refresh()
End Sub
I give you code for sql.change it to access
Dim com As SqlCommand
com = New SqlCommand("select uname,pwd from logg where uname='" & TextBox1.Text & "' and pwd='" & TextBox2.Text & "'", conn)
Dim da As New SqlDataAdapter(com)
Dim ds As New Data.DataSet
da.Fill(ds)
If ds.Tables(0).Rows.Count = 1 Then
MsgBox("Successfully logged in")
Label1.Text = ds.Tables(0).Rows(0)("uname")
End If

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!! :)