VB.NET DataTable rows - sql-server

I'm trying to make a login form.
I've created a database on my server and created the rows username and password.
I then created a root user with root as password.
but I have a problem with the check if the username and password are correct,
I don't know how to give him the 2 rows.
Dim conn = New SqlConnection("Data Source=SRV-SQL;Initial Catalog=prova;User ID=user;Password=user")
Dim sda = New SqlDataAdapter("select count(*) from tblLogin where username ='" + txtUsername.Text + "' and password='" + txtUserPwd.Text + "'", conn)
Dim dt = New DataTable()
sda.Fill(dt)
If (dt.Rows().ToString() = "1") Then
MsgBox("Logged-in successfully")
Else
MessageBox.Show("The username or the password is wrong!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
Table:

Comments and explanations in-line.
Private Sub VerifyLogin()
'For the Return Value of the command
Dim RetVal As Integer
' A Using...End Using will ensure that you connectionis closed and disposed event
'it there is an error.
Using conn = New SqlConnection("Data Source=SRV-SQL;Initial Catalog=prova;User ID=user;Password=user")
'You don't need a DataAdapter, just a command
'USE PARAMETERS. Yes, I am yelling :-) Even if you are the only user
'it will save you headaches with syntax.
Using cmd = New SqlCommand("select count(*) from tblLogin where username = #UserName and password= #Password;", conn)
cmd.Parameters.Add("#UserName", SqlDbType.VarChar).Value = txtUsername.Text
cmd.Parameters.Add("#Password", SqlDbType.VarChar).Value = txtUserPwd.Text
'You are only returning one row
'ExecuteScalar returns the value in the first column of the
'first row of the the data
conn.Open()
RetVal = CInt(cmd.ExecuteScalar)
End Using
End Using
'No need to convert to a string just compare the Integer
If RetVal = 1 Then
MsgBox("Logged-in successfully")
Else
MessageBox.Show("The username or the password is wrong!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End Sub

Private Function CalculateHash(password As String, salt As String) As String
'TODO:
' Suggest pulling the BCrypt from the NuGet gallery for this:
' https://www.nuget.org/packages/BCrypt-Official/
' Just remember that bcyrpt lib encodes salt as part of the password hash, so the function signatures and db table will be different.
End Function
Public Function CheckCredentials(UserName As String, Password As String) As Boolean
Using conn As New SqlConnection("Data Source=SRV-SQL;Initial Catalog=prova;User ID=user;Password=user"), _
' Need to add a "Salt" column to your table, create a new random salt for each user when you create the user
cmd As New SqlCommand("SELECT Salt, PwdHash FROM tblLogin WHERE username = #Username", conn)
'Parameterized queries or NOTHING. String concatention is NOT OKAY here
cmd.Parameters.Add("#UserName", SqlDbType.NVarChar, 50).Value = UserName
conn.Open()
Using rdr As SqlDataReader = cmd.ExecuteReader()
If Not rdr.Read() Then Return False
Dim Salt As String = rdr("Salt")
Dim PwdHash As String = rdr("PwdHash")
'Compare HASHES, not Passwords
Return PwdHash = CalculateHash(Password, Salt As String)
End Using
End Using
End Function
If CheckCredentials(txtUsername.Text, txtUserPwd.Text) Then
MsgBox("Logged-in successfully")
Else
MessageBox.Show("The username or the password is wrong!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If

Use DataReader instead, use this code and just call CheckLogin in login button or somthing else.
Sub CheckLogin()
Dim conn = New SqlConnection("Data Source=SRV-SQL;Initial Catalog=prova;User ID=user;Password=user")
conn.Open()
Try
Dim query As String = "select count(*) from tblLogin where username = #username and password= #password "
Dim cmd = New SqlCommand(query, conn)
cmd.Parameters.AddWithValue("#username", txtUsername.Text)
cmd.Parameters.AddWithValue("#password", txtUserPwd.Text)
Dim DR As SqlDataReader = cmd.ExecuteReader()
If DR.HasRows Then
MsgBox("Logged-in successfully")
Else
MessageBox.Show("The username or the password is wrong!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
conn.Close()
End Sub

Related

How to resolve : 'There is already an open DataReader associated with this Command which must be closed first.'

I've been trying to insert data into my sql database but this problem always show up
i've tried redoing it again and the same problem occurs and i'm really stumped right now
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim conn As SqlConnection = New SqlConnection("Data Source=DESKTOP-OBQR58O\SQLEXPRESS;Initial Catalog=Accounts;Integrated Security=True")
Dim comm As SqlCommand = New SqlCommand("insert into User(username, password)values('" + TextBox1.Text + "', '" + TextBox3.Text + "')", conn)
Dim data As SqlDataAdapter = New SqlDataAdapter(comm)
Dim user = TextBox1.Text
Dim pass = TextBox2.Text
Dim cpass = TextBox3.Text
Dim reader As SqlDataReader
conn.Open()
Dim cmd As SqlCommand = New SqlCommand("select Username from [User] where Username ='" + TextBox1.Text + "'", conn)
conn.Close()
conn.Open()
reader = cmd.ExecuteReader
If user.Trim() = "" Or pass.Trim() = "" Or cpass.Trim() = "" Then
MessageBox.Show("Empty Fields", "Blank Spaces")
ElseIf Not String.Equals(pass, cpass) Then
MessageBox.Show("Passwords do not match", "ERROR")
conn.Close()
ElseIf reader.HasRows Then
MessageBox.Show("Username already exists!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning)
TextBox1.Clear()
conn.Close()
reader.Close()
Else
MessageBox.Show("Account created succesfully!", "Success")
Dim table As DataTable = New DataTable()
data.Fill(table) ' this is where the problem occurs.
TextBox1.Clear()
TextBox2.Clear()
TextBox3.Clear()
Dim log As New Login
Me.Close()
log.Show()
conn.Close()
End If
conn.Close()
End Sub
I honestly don't know what to do
You open your reader up at the top:
reader = cmd.ExecuteReader
So, it's open. And then, when you run the Fill command, it conflicts with the open reader!
The simplest fix - although, personally, I would restructure the code a bit, to bring the OpenReader nearer to where it is used - would be to add a Close to your reader right before the Fill.
Else
reader.Close() ' what you would add
MessageBox.Show("Account created succesfully!", "Success")
Dim table As DataTable = New DataTable()
data.Fill(table) ' this is where the problem occurs.
VERY IMPORTANT: If you're not familiar with the concept of "SQL Injection Attacks", read up on them, right away. You should NEVER execute SQL that's been built by constructing a string with unvalidated data from the user. You should pass parameters instead.
After all, what if I typed in the user name of "Irrelevant';DROP TABLE Users;--"? You'd wind up with a SQL Statement that contained "SELECT Username from [Users] WHERE [Username] = 'Irrelevant'; DROP TABLE Users; --'"
And, of course, you should validate the input as well, for things like embedded HTML and script! But that's more complicated than just using SQL Parameters.

VB.NET SQL Server: Must declare scalar variable

I am trying to make a query that deletes the user from my database.
But when i confirm to delete the user it gives me an error:
System.Data.SqlClient.SqlException (0x80131904): Must declare the scalar variable "#Username".
Imports System.Data.SqlClient
Public Class DeleteForm
Private Sub btnDelete_Click(sender As Object, e As EventArgs) Handles btnDelete.Click
Dim RetVal As Integer
Dim conn = New SqlConnection("Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=dbProject;Integrated Security=True")
Using cmd = New SqlCommand("select count(*) from tblLogin where username = #Username and password = #Password", conn)
cmd.Parameters.Add("#Username", SqlDbType.VarChar).Value = txtUsername.Text
cmd.Parameters.Add("#Password", SqlDbType.VarChar).Value = txtPassword.Text
conn.Open()
If conn.State = ConnectionState.Open Then
RetVal = CInt(cmd.ExecuteScalar)
If RetVal = 1 Then
If txtPassword.Text And txtCheckPassword.Text <> "" Then
If txtCheckPassword.Text = txtPassword.Text Then
Dim cancConf As Integer = MessageBox.Show("This cant be undone!" & vbCrLf & "Are you sure?", "Warning!", MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
If cancConf = DialogResult.Yes Then
Try
Dim queryDelete As String = "DELETE FROM tblLogin WHERE username = #Username"
Dim cmdDelete As New SqlClient.SqlCommand(queryCancellazione, conn)
cmdCancellazione.ExecuteNonQuery()
MsgBox("Account deleted succesfully!")
cmdCancellazione.Dispose()
conn.Close()
LoginForm.Show()
Me.Close()
Catch ex As Exception
MsgBox(ex.ToString())
End Try
ElseIf cancConf = DialogResult.No Then
End If
Else
MsgBox("The passwords arent matching!", MsgBoxStyle.Exclamation)
End If
ElseIf txtPUtenteCANC.Text <> "" And txtPUtenteCONF.Text = "" Then
MsgBox("Please, confirm the password")
End If
Else
MsgBox("User not found!", MsgBoxStyle.Exclamation)
txtNUtenteCANC.Clear()
txtPUtenteCANC.Clear()
txtPUtenteCONF.Clear()
txtNUtenteCANC.Select()
End If
Else
MessageBox.Show("The connection is not open!" & vbCrLf & "The program will close", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Error)
End
End If
End Using
End Sub
End Class
You have added that parameter to the SELECT COUNT command but not to the DELETE command.
Dim queryCancellazione As String = "DELETE FROM tblLogin WHERE username = #Username"
Dim cmdCancellazione As New SqlClient.SqlCommand(queryCancellazione, conn)
cmdCancellazione.Parameters.Add("#Username", SqlDbType.VarChar).Value = txtUsername.Text

vb.net connect to multiple databases using sqldatareader

If CbDept_login.Text = "DEPT1" Then
Dim con As New SqlConnection("Data Source=XYZ-PC;Database=DATABASE1;Integrated Security =true")
con.Open()
Dim rs As New SqlCommand("SELECT * FROM TABLE1 WHERE Username=#Username COLLATE SQL_Latin1_General_CP1_CS_AS AND Password=#Password COLLATE SQL_Latin1_General_CP1_CS_AS", con)
Dim UsernameParam As New SqlParameter("#Username", Me.txtUsername.Text)
Dim PasswordParam As New SqlParameter("#Password", Me.txtPassword.Text)
rs.Parameters.Add(UsernameParam)
rs.Parameters.Add(PasswordParam)
Dim sqlRead As SqlDataReader = rs.ExecuteReader
If sqlRead.HasRows Then
If sqlRead.Read = True Then
If sqlRead("UserType") = "Admin" Then
MsgBox("Log in as " + txtUsername.Text, MsgBoxStyle.OkOnly Or MsgBoxStyle.DefaultButton2 Or MsgBoxStyle.Information, "Login Sucess")
frm_Admin.Show()
frm_Admin.LblLogAsAdmin_LCR.Text = txtUsername.Text
Me.Close()
ElseIf sqlRead("UserType") = "Staff" Then
MsgBox("Log in as " + txtUsername.Text, MsgBoxStyle.OkOnly Or MsgBoxStyle.DefaultButton2 Or MsgBoxStyle.Information, "Login Sucess")
frm_User.Show()
frm_User.TblogAsuser.Text = txtUsername.Text
Me.Close()
End If
End If
Else
MsgBox("Please input correct username and password", MsgBoxStyle.OkOnly Or MsgBoxStyle.DefaultButton2 Or MsgBoxStyle.Critical, "Login Failed")
txtPassword.Text = ""
con.Close()
End If
End If
If CbDept_login.Text = "DEPT2" Then
Dim conn As New SqlConnection("Data Source=XYZ-PC;Database=DATABASE2;Integrated Security =true")
conn.Open()
Dim rs As New SqlCommand("SELECT * FROM TABLE2 WHERE Username=#Username COLLATE SQL_Latin1_General_CP1_CS_AS AND Password=#Password COLLATE SQL_Latin1_General_CP1_CS_AS", con)
Dim UsernameParam As New SqlParameter("#Username", Me.txtUsername.Text)
Dim PasswordParam As New SqlParameter("#Password", Me.txtPassword.Text)
rs.Parameters.Add(UsernameParam)
rs.Parameters.Add(PasswordParam)
Dim sqlRead As SqlDataReader = rs.ExecuteReader
If sqlRead.HasRows Then
If sqlRead.Read = True Then
If sqlRead("UserType") = "Admin" Then
MsgBox("Log in as " + txtUsername.Text, MsgBoxStyle.OkOnly Or MsgBoxStyle.DefaultButton2 Or MsgBoxStyle.Information, "Login Sucess")
frm_Admin.Show()
frm_Admin.LblLogAsAdmin_LCR.Text = txtUsername.Text
Me.Close()
ElseIf sqlRead("UserType") = "Staff" Then
MsgBox("Log in as " + txtUsername.Text, MsgBoxStyle.OkOnly Or MsgBoxStyle.DefaultButton2 Or MsgBoxStyle.Information, "Login Sucess")
frm_User.Show()
frm_User.TblogAsuser.Text = txtUsername.Text
Me.Close()
End If
End If
Else
MsgBox("Please input correct username and password", MsgBoxStyle.OkOnly Or MsgBoxStyle.DefaultButton2 Or MsgBoxStyle.Critical, "Login Failed")
txtPassword.Text = ""
conn.Close()
End If
End If
End Sub
Hello, I'm currently facing a problem in my vb project. I'm using visual studio 2012 and SQL server 2012 for my database. I have a login form in which you can access to the different databases just by choosing department name in a combo box and it will check if you input a correct username and password using sqldatareader depends on the username and password value on the database of the department that you choose. Now my problem is when I run it, it will show an error "No source available". maybe my codes are wrong, please help me. thank you in advance. By the way, i put this code on my Login Button.

Creating a change password form in Visual Basic. How to update the SQL Server database?

I'm creating a login register with edit information. I'm stuck with the change password form.
Here's what I got - totally lost it, no errors but crashes when tested highlights my reader command
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Dim sql As String = "Select Username, Password From tblLog Where Username = #Username"
Dim cmd As SqlClient.SqlCommand
cmd = New SqlClient.SqlCommand(sql, con)
cmd.Parameters.Add("#Username", SqlDbType.VarChar).Value = My.Forms.formEdit.tbUser.Text
If con.State = ConnectionState.Closed Then
con.Open()
End If
Dim rd As SqlClient.SqlDataReader = cmd.ExecuteReader
Try
If rd.Read = False Then
MessageBox.Show("Incorrect Password")
tbOldPass.Clear()
tbNewPass.Clear()
tbConPass.Clear()
ElseIf tbConPass.Text <> tbNewPass.Text Then
MessageBox.Show("Password does not match")
tbOldPass.Clear()
tbNewPass.Clear()
tbConPass.Clear()
Else
Dim sqry As String = "Update tblLog Set Password = #Password" &
"Where Username = #Username And Password = #OldPassword"
rd.Close()
Dim scmd As New SqlClient.SqlCommand(sqry, con)
scmd.Parameters.AddWithValue("#Password", tbNewPass.Text)
scmd.Parameters.AddWithValue("#Username", My.Forms.formEdit.tbUser.Text)
scmd.Parameters.AddWithValue("#OldPassword", tbOldPass.Text)
scmd.ExecuteNonQuery()
MessageBox.Show("Information Updated")
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
con.Close()
End Sub
Edited: Changed the code a bit, it doesn't crash anymore but my database doesn't get updated
Dim sql As String = "Select Username, Password From tblLog Where Username = #Username And Password = #Password"
Dim cmd As New SqlClient.SqlCommand
cmd = New SqlClient.SqlCommand(sql, con)
cmd.Parameters.Add("#Password", SqlDbType.VarChar).Value = My.Forms.formEdit.tbPass.Text
cmd.Parameters.Add("#Username", SqlDbType.VarChar).Value = My.Forms.formEdit.tbUser.Text
If con.State = ConnectionState.Closed Then
con.Open()
End If
cmd.ExecuteNonQuery()
con.Close()
Try
If tbOldPass.Text <> My.Forms.formEdit.tbPass.Text = False Then
MessageBox.Show("Incorrect Password")
tbOldPass.Clear()
tbNewPass.Clear()
tbConPass.Clear()
ElseIf tbConPass.Text <> tbNewPass.Text Then
MessageBox.Show("Password does not match")
tbOldPass.Clear()
tbNewPass.Clear()
tbConPass.Clear()
Else
Dim sqry As String = "Update tblLog Set [Password] = #Pss Where Username = #Use And Password = #OldPassword"
Dim scmd As New SqlClient.SqlCommand(sqry, con)
scmd.Parameters.AddWithValue("#Pss", tbNewPass.Text)
scmd.Parameters.AddWithValue("#Use", My.Forms.formEdit.tbUser.Text)
scmd.Parameters.AddWithValue("#OldPassword", My.Forms.formEdit.tbPass.Text)
If con.State = ConnectionState.Closed Then
con.Open()
End If
scmd.ExecuteNonQuery()
con.Close()
MessageBox.Show("Information Updated")
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
Try Adding space before where in query:
Dim sqry As String = "Update tblLog Set Password = #Password" &
" Where Username = #Username And Password = #OldPassword"
After tweaking my code a bit I realized that I was closing the form where the value of my parameters were taken. So I tried to just hide the form not close it, then it worked. Sorry for the troubles.
Edit:
Should I delete this question or just leave it? I can't select my own answer as the correct for 2 more days

Invalid Column name while column is there

I am trying to create a login window with MDI. It is connected to a SQL Server table test. I have changed the datatypes and deleted and recreated the DB. I have 2 columns: usr and pwd of datatype nvarchar.
Dim connetionString As String
Dim cnn As SqlConnection
connetionString = "Data Source=.;Initial Catalog=test;User ID=sa;Password=sasql"
cnn = New SqlConnection(connetionString)
Dim cmd As SqlCommand
Dim myreader As SqlDataReader
Dim query As String
query = "Select usr From users WHERE (usr =" + TextBox1.Text + " and pwd = " + TextBox2.Text + ")"
cmd = New SqlCommand(query, cnn)
cnn.Open()
myreader = cmd.ExecuteReader()
If myreader.Read() Then
Else
MessageBox.Show("Incorrect username/password !", "LOGIN ERROR", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
cnn.Close()
Thank you so much.
If you are using Tortuga.Chain, the code would look like this:
Dim ds As New SqlServerDataSource(connetionString)
Dim user = ds.From("users", new With {.usr = TextBox1.Text, .pwd = TextBox2.Text}).ToString.Execute();
If user Is Not Nothing Then
Else
MessageBox.Show("Incorrect username/password !", "LOGIN ERROR", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
If you want to stick to raw ADO.NET code, you need to use a parameterized query.
Dim connetionString As String
Dim cnn As SqlConnection
connetionString = "Data Source=.;Initial Catalog=test;User ID=sa;Password=sasql"
cnn = New SqlConnection(connetionString)
Dim cmd As SqlCommand
Dim myreader As SqlDataReader
Dim query As String
query = "Select usr From users WHERE (usr = #user and pwd = #pwd )"
cmd = New SqlCommand(query, cnn)
cmd.Parameters.AddWithValue( "#usr", TextBox1.Text)
cmd.Parameters.AddWithValue( "#pwd", TextBox2.Text)
cnn.Open()
myreader = cmd.ExecuteReader()
If myreader.Read() Then
Else
MessageBox.Show("Incorrect username/password !", "LOGIN ERROR", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
cnn.Close()
Remove the spaces from the value of connectionString.
Your query compares textual data, which is invalid unless the user enters ' at the start and end of the textboxes. This would be syntactically correct:
"Select usr From users WHERE (usr ='" + TextBox1.Text + "' and pwd = '" + TextBox2.Text + "')"
but logically flawed, since the user might attempt to inject malicious SQL into your textboxes. Your application is extremely unsafe. You must protect it against SQL injection and you need to encrypt the password of the user as well.

Resources