I'm doing a program and I'm in a part that I need to create users in the database in access. But after entering the data and clicking the create user button it gives me an error. If you add users to the database it works but if you try to add it by the program's the result is a syntax error
Else
Try
Dim myconnection As OleDbConnection
Dim constring As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=E:\Software_Simples\Software\DataBase.accdb"
myconnection = New OleDbConnection(constring)
myconnection.Open()
Dim sqlQry As String
'sqlQry = "INSERT INTO Usernames(Username, Password) VALUES(" & TextBox2.Text & "," & TextBox3.Text & ")"
sqlQry = "INSERT INTO Usernames(ID_User, Username, Password) VALUES(Null,TextBox2.Text,TextBox3.Text )"
Dim cmd As New OleDbCommand(sqlQry, myconnection)
cmd.ExecuteNonQuery()
myconnection.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
'Fechar
Me.Close()
MessageBox.Show("Utilizador criado com suecesso: " & username_create, "Aviso", MessageBoxButtons.OK)
End If
There are at least three problems in your code:
1) Password is a reserved keyword. Needs to be between square brackets
2) String values when passed to a database need to be between single quotes, but.. see point 3
3) Use parameters instead of string concatenation (what if password contains a single quote?)
4) Dispose the disposable object like the connection and the command.
So rewriting it
Dim constring = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=E:\Software_Simples\Software\DataBase.accdb"
Dim sqlQry = "INSERT INTO Usernames(Username, [Password]) VALUES(#name, #pwd)"
Try
Using myconnection = New OleDbConnection(constring)
Using cmd As New OleDbCommand(sqlQry, myconnection)
myconnection.Open()
cmd.Parameters.Add("#name", OleDbType.VarWChar).Value = TextBox2.Text
cmd.Parameters.Add("#pwd", OleDbType.VarWChar).Value = TextBox3.Text
cmd.ExecuteNonQuery()
End Using
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
It should read:
sqlQry = "INSERT INTO Usernames (ID_User, Username, [Password]) VALUES (Null,'" + TextBox2.Text + "','" + TextBox3.Text + "')"
Related
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.
While i was adding data to access database, i got error:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
TB2.Clear()
NameofG.Clear()
NunberofG.Clear()
UnitofG.Clear()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
pro = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Piyawat\Desktop\PPCC\Stock.accdb;"
connstring = pro
myconnection.ConnectionString = connstring
If myconnection.State = ConnectionState.Closed Then
myconnection.Open()
End If
command = "insert into Stock([InvoiceID],[Type],[Item],[Amout],[Unit]) Value ('" & TB2.Text & "','" & CB1.Text & "','" & NameofG.Text & "','" & NunberofG.Text & "','" & UnitofG.Text & "')"
Dim cmd As OleDbCommand = New OleDbCommand(command, myconnection)
cmd.Parameters.Add(New OleDbParameter("InvoiceID", CType(TB2.Text, String)))
cmd.Parameters.Add(New OleDbParameter("Type", CType(CB1.Text, String)))
cmd.Parameters.Add(New OleDbParameter("Item", CType(NameofG.Text, String)))
cmd.Parameters.Add(New OleDbParameter("Amout", CType(NunberofG.Text, String)))
cmd.Parameters.Add(New OleDbParameter("Unit", CType(UnitofG.Text, String)))
MsgBox("Record Save")
Try
cmd.ExecuteNonQuery()
cmd.Dispose()
TB2.Clear()
CB1.Text.DefaultIfEmpty
NameofG.Clear()
NunberofG.Clear()
UnitofG.Clear()
Catch ex As Exception
MsgBox("Mistake")
End Try
End Sub
How to fix the error? Please help. Thanks
I would AWAYS ensure that after you use the connection, you close it.
however, you can get .net to automatics do this for you.
Also, go into project->settings and add your connection string there - that way you NEVER have to place or have connection strings in code - (bad idea).
Hence, your code should and would look like this:
Dim strSQL As String = "INSERT INTO Stock([InvoiceID],[Type],[Item],[Amout],[Unit]) " &
"VALUES (#TB2, #CB1, #NameofG, #NunberofG, #UnitofG)"
Using cmd As New OleDbCommand(strSQL, New OleDbConnection(My.Settings.Test44))
cmd.Parameters.Add("#TB2", OleDbType.VarWChar).Value = TB2.Text
cmd.Parameters.Add("#CB1", OleDbType.VarWChar).Value = CB1.Text
cmd.Parameters.Add("NameofG", OleDbType.VarWChar).Value = NameofG.Text
cmd.Parameters.Add("#NumberofG", OleDbType.Integer).Value = NunberofG.Text
cmd.Parameters.Add("#UnitofG", OleDbType.Integer).Value = UnitOfG.Text
cmd.Connection.Open()
Try
cmd.ExecuteNonQuery()
MsgBox("Record Save")
Catch ex As Exception
MsgBox("Error = " & ex.Message)
End Try
End Using
note the following:
No messy string concentation.
No messy quotes for strings, non quotes for numbers.
clean easy to read.
use parmaters - safe.
And with a using block, we do NOT have to dispose or close the conneciton - it is automatic for you. So ALWAYS assume it is closed.
note how we don't have a seperate conneciton object - don't need one.
note how the command object is REALLY nice.
The command object has:
a connection object - you don't need to create a new one
command text
a reader!!! - you can use command object - no need to load + create a reader
I moved the database code to a separate method.
Starting with the user interface code, you first want to validate the input. I had to guess at the datatypes because your code made them all look like strings. I hope this is not true.
It seems you got mixed up with Parameters. I am very glad that you tried to used them but they don't appear in your sql string so they are not being used. You don't want to concatenate strings with user input because it risks sql injection.
The # sign preceding the parameter names is just a convention that makes it easy to recognize.
You need to keep database objects local to the method where they are used. That way they can be closed and disposed with Using...End Using blocks as quickly as possible.
Private ConStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Piyawat\Desktop\PPCC\Stock.accdb;" '"Your connection string"
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Validate input
Dim ID As Integer
Dim Amt As Decimal
Dim Unt As Integer
Dim message = "Please enter a number for the"
If Not Integer.TryParse(TB2.Text, ID) Then
MessageBox.Show(message & " Invoice ID.")
Return
End If
If Not Decimal.TryParse(NunberofG.Text, Amt) Then
MessageBox.Show(message & " Amount.")
Return
End If
If Not Integer.TryParse(UnitofG.Text, Unt) Then
MessageBox.Show(message & " Unit")
Return
End If
'Call the insert method
Try
InsertInvoice(ID, CB1.Text, NameofG.Text, Amt, )
Catch ex As Exception
MsgBox(ex.Message)
Return
End Try
MessageBox.Show("Record Saved")
TB2.Clear()
CB1.Text.DefaultIfEmpty
NameofG.Clear()
NunberofG.Clear()
UnitofG.Clear()
End Sub
Private Sub InsertInvoice(InvoiceID As Integer, Type As String, Item As String, Amount As Decimal, Unit As Integer)
Dim Command = "insert into Stock([InvoiceID],[Type],[Item],[Amout],[Unit]) Value (#InvoiceID,#Type,#Item,#Amount,#Unit)"
Using myconnection As New OleDbConnection(ConStr),
cmd As New OleDbCommand(Command, myconnection)
With cmd.Parameters
.Add("#InvoiceID", OleDbType.Integer).Value = InvoiceID
.Add("#Type", OleDbType.VarChar).Value = Type
.Add("#Item", OleDbType.VarChar).Value = Item
.Add("#Amout", OleDbType.Decimal).Value = Amount
.Add("#Unit", OleDbType.Integer).Value = Unit
End With
End Using
End Sub
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.
I am having a problem with my code where i am only able to add so many lines of text before i get an error "system resources exceeded".
This is my code:
Dim x As Integer = MsgBox("Update Record?", MsgBoxStyle.YesNo, "Are you sure?")
If x = MsgBoxResult.Yes Then
Dim accessconn As New _
System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & "MyDB.accdb")
Dim com As System.Data.OleDb.OleDbCommand
accessconn.Close()
Try
For Each strLine As String In TextBox1.Text.Split(vbNewLine)
accessconn.Open()
Dim str As String
Dim dr As OleDbDataReader
str = "SELECT * FROM Table4 WHERE MD5='" & strLine & "'"
Dim cmd As OleDbCommand = New OleDbCommand(str, accessconn)
dr = cmd.ExecuteReader
If dr.Read() Then
Label2.Text = Label2.Text + 1
Else
accessconn.Open()
com = New System.Data.OleDb.OleDbCommand("INSERT INTO Table4(MD5) VALUES('" & strLine & "')", accessconn)
com.ExecuteReader(CommandBehavior.CloseConnection)
Label3.Text = Label3.Text + 1
com.Dispose()
accessconn.Close()
End If
Next
accessconn.Close()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
MsgBox("Done")
PopulateGridview4()
End If
I would like to be able to add unlimited rows of text to the database if possible. Please Help.
You should change your code to something like the following. Note that
Everything that returns an object like OleDbConnection, OleDbCommand, or OleDbDataReader is wrapped in a Using block. These objects all implement the IDisposable interface, which means they should be cleaned up as soon as you're done with them.
Also note that your INSERT did not return any data, so you should use ExecuteNonQuery instead of ExecuteReader.
Finally, please don't get into the habit of putting Try/Catch/End Try blocks around everything. You were displaying the exception (you displayed ex.ToString, which is a good thing), but you then ignored the exception. As a good general rule, don't catch exceptions unless you can fix them.
Code:
Dim x As Integer = MsgBox("Update Record?", MsgBoxStyle.YesNo, "Are you sure?")
If x = MsgBoxResult.Yes Then
Using accessconn As New _
System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & "MyDB.accdb")
accessconn.Open()
For Each strLine As String In TextBox1.Text.Split(vbNewLine)
Dim str As String = "SELECT * FROM Table4 WHERE MD5='" & strLine & "'"
Using cmd As OleDbCommand = New OleDbCommand(str, accessconn)
Using dr As OleDbDataReader = cmd.ExecuteReader
If dr.Read() Then
Label2.Text = Label2.Text + 1
Else
Using com As OleDbCommand = New System.Data.OleDb.OleDbCommand("INSERT INTO Table4(MD5) VALUES('" & strLine & "')", accessconn)
com.ExecuteNonQuery()
End Using
Label3.Text = Label3.Text + 1
End If
End Using
End Using
Next
MsgBox("Done")
PopulateGridview4()
End Using
End If
P.S. you could probably have made this a little less indented by using If x <> MsgBoxResult.Yes Then get out, but I don't know if this is inside of a Sub or Function, so "get out" could be different.
I'm trying a new approach for a project that I'm working on and I'm just starting to learn about Access Databases. I using VB.net and my question is: How do you see if a record exists in the table of the database. I thought I had it understood but that is not the case. I'm creating a login and I want it to check if the Username that they typed in exists before it tries to compare what you typed with what's in the database. I see alot of questions on how to do this...but not for VB.net and MS Access
Here's my code:
Imports System.Data.OleDb
Public Class LoginForm1
Dim provider As String
Dim dataFile As String
Dim connString As String
Public myConnection As OleDbConnection = New OleDbConnection
Public dr As OleDbDataReader
Dim Errors As String
Public Sub AccessAccountDatabase()
provider = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source ="
dataFile = "C:\Users\Richard\Documents\Visual Studio 2010\Projects\CybSol Journal Database\CybSol Journal Database\cgi-bin\Data.mdb"
connString = provider & dataFile
myConnection.ConnectionString = connString
Errors = ""
Try
myConnection.Open()
Dim str As String
str = "SELECT * FROM Accounts WHERE Username='" & UsernameTxt.Text & "' AND Password='" & PasswordTxt.Text & "'"
Dim cmd As OleDbCommand = New OleDbCommand(str, myConnection)
dr = cmd.ExecuteReader
dr.Read()
If UsernameTxt.Text = dr("Username").ToString AndAlso PasswordTxt.Text = dr("Password").ToString Then
Dim Welcome As String = "SELECT * FROM Accounts WHERE Real_Name=" & "Username"
MsgBox("Welcome back " & dr("Real_Name") & "!")
Else
MsgBox("Login Failure")
End If
myConnection.Close()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub OkayBtn_Click(sender As System.Object, e As System.EventArgs) Handles OkayBtn.Click
AccessAccountDatabase()
End Sub
End Class
So now my question is... How do you get it to check if a record exists in the database, because when you type in the correct information (The correct username and password that exists in the database) it says welcome and all. But when you type in the wrong Username and/or Password it doesn't work. Without the "Try Catch" statement the program just freezes. With the try catch it states this:
System.InvalidOperationException: No data exists for the row/column.
at System.Data.OleDb.OleDbDataReader.DoValueCheck(Int32 ordinal)
at System.Data.OleDb.OleDbDataReader.GetValue(Int32 ordinal)
at System.Data.OleDb.OleDbDataReader.get_Item(String name)
at CybSol_Journal_Database.LoginForm1.AccessAccountDatabase() in c:\users\richard\documents\visual studio 2010\Projects\CybSol Journal Database\CybSol Journal Database\LoginForm1.vb:line 36
Addition information: line 36 is this: If UsernameTxt.Text = dr("Username").ToString AndAlso PasswordTxt.Text = dr("Password").ToString Then
First problem:
PASSWORD is a reserved keyword in Access. You should encapsulate in square brackets:
"SELECT * FROM Accounts WHERE Username='" & UsernameTxt.Text & _
"' AND [Password]='" & PasswordTxt.Text & "'"
Second problem:
NEVER use string concatenation to create sql text. ALWAYS use parameters
str = "SELECT * FROM Accounts WHERE Username=? AND [Password]=?"
Dim cmd As OleDbCommand = New OleDbCommand(str, myConnection)
cmd.Parameters.AddWithValue("user", UserNameTxt.Text)
cmd.Parameters.AddWithValue("pass", PasswordTxt.Text)
dr = cmd.ExecuteReader
Why? look here what could happen if you concatenate strings from user input
Third problem: Test if your command returns rows
If dr.Read() Then
......
End if
I added some Using statements so you don't have to manually close the connections. Also, I parameterized the SQL statement to prevent SQL Injection.
Public Class LoginForm1
Dim provider As String
Dim dataFile As String
Dim connString As String
'Public myConnection As OleDbConnection = New OleDbConnection
'Public dr As OleDbDataReader
Dim Errors As String
Public Sub AccessAccountDatabase()
provider = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source ="
dataFile = "C:\Users\Richard\Documents\Visual Studio 2010\Projects\CybSol Journal Database\CybSol Journal Database\cgi-bin\Data.mdb"
connString = provider & dataFile
myConnection.ConnectionString = connString
Errors = ""
Try
Using myConnection As OleDbConnection = New OleDbConnection(connString)
myConnection.Open()
Dim str As String
str = "SELECT * FROM Accounts WHERE Username=#USER AND [Password]=#PWD "
Using cmd As OleDbCommand = New OleDbCommand(str, myConnection)
cmd.Parameters.AddWithValue("#USER", UsernameTxt.Text)
cmd.Parameters.AddWithValue("#PWD", PasswordTxt.Text)
Using dr As OleDbDataReader = cmd.ExecuteReader
If dr.HasRows Then
dr.Read()
If UsernameTxt.Text = dr("Username").ToString AndAlso PasswordTxt.Text = dr("Password").ToString Then
Dim Welcome As String = "SELECT * FROM Accounts WHERE Real_Name=" & "Username"
MsgBox("Welcome back " & dr("Real_Name") & "!")
Else
MsgBox("Login Failure")
End If
Else
MsgBox("Login Failure")
End If
End Using
End Using
End Using
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub OkayBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OkayBtn.Click
AccessAccountDatabase()
End Sub
End Class
You're on the right track. The OleDbDataReader.Read returns a boolean indicating whether or not it successfully read an existing row. Therefore, you can check to see if it returned True before trying to read the record. For instance:
If dr.Read() Then
If UsernameTxt.Text = dr("Username").ToString AndAlso PasswordTxt.Text = dr("Password").ToString Then
Dim Welcome As String = "SELECT * FROM Accounts WHERE Real_Name=" & "Username"
MsgBox("Welcome back " & dr("Real_Name") & "!")
Else
MsgBox("Login Failure")
End If
End If
Also, I feel I should at least mention that storing a password in plain text is never a good idea.
You don't have to check for the username and password in your code again since if does not match in the database, no rows will be returned.
You can simply do
dr = cmd.ExecuteReader
If dr.HasRows Then
//it matched
Else
//it didn't match. could not log in
End If
Your approach is below if you still want to keep it but it's not necessary
dr = cmd.ExecuteReader
If dr.HasRows Then
dr.Read()
If UsernameTxt.Text = dr("Username").ToString AndAlso PasswordTxt.Text = dr("Password").ToString Then
Else
End If
End If
Use the Read() method on your DataReader (note that this keeps your connection to the database open and you'll be unable to execute any other commands on the database while your DataReader is still Reading.
If String.Compare(dr("Username").ToString(), UsernameTxt.Text, true) AndAlso String.Compare(dr("Password").ToString(), PasswordTxt.Text.ToString() Then
' The username and password for the record match
' the input from the login form
ProcessLogin()
Else
' Invalid username or password, send an error
End If