i'm having trouble fixing this problem "Syntax error in FROM Clause"
Here's my codes:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
myConnetion = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\iponz18\Documents\Visual Studio 2012\Projects\CanteenBillingSystem\CanteenBillingSystem\CanteenBillingSystem.accdb")
Dim table As String = "SELECT UserID FROM User WHERE UserID = " + TextBox1.Text + ";"
da = New OleDbDataAdapter(table, myConnetion)
ds = New DataSet
da.Fill(ds, "User")
If (ds.Tables("User").Rows.Count > 0) Then
Form2.Show()
Me.Close()
End If
End Sub
The error is on this line:
da.Fill(ds, "User")
please help me out...
User is a reserved keyword in MS-Access. You need to put it between square brackets
Dim table As String = "SELECT UserID FROM [User] WHERE UserID = ...
Said that, your query has other problems. A better approach is this one:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim table As String = "SELECT UserID FROM User WHERE UserID = #uid"
Using conn = New OleDbConnection(.....)
Using da = New OleDbDataAdapter(table, conn )
da.SelectCommand.Parameters.Add("#uid", OleDbType.VarWChar).Value = textBox1.Text
ds = New DataSet
da.Fill(ds, "User")
If (ds.Tables("User").Rows.Count > 0) Then
Form2.Show()
End If
End Using
End Using
End Sub
I have changed your string concatenated query text to a parameterized query. This approach is more safe because it avoids Sql Injection and remove the need to escape properly your strings.
Also another very important advice that I feel to give is to avoid at all costs global variables to keep objects like a connection or an adapter around. This will give you a lot of trouble when something unexpected happens and your connection is leaved in unpredictable state.
Finally, if you just need to check if you have a UserID in your table, then there is no need to build an OleDbDataAdapter, a DataSet and fill it. You could just use ExecuteScalar method of the OleDbCommand
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim table As String = "SELECT UserID FROM User WHERE UserID = #uid"
Using conn = New OleDbConnection(.....)
Using cmd = New OleDbCommand(table, conn )
cmd.Parameters.Add("#uid", OleDbType.VarWChar).Value = textBox1.Text
conn.Open()
Dim result = cmd.ExecuteScalar()
if result IsNot Nothing then
Form2.Show()
End If
End Using
End Using
End Sub
Related
I'm quite new to programming so excuse my lack of knowledge.
I'm trying to create a quiz for my project and am having trouble with it. Currently, I'm trying to make the quiz run until the number of questions is the same as the desired amount the user inputs in a Combobox from the previous form. Whilst this does partially work, the problem is that it is really slow and freezes when you click the button the second time.
Imports System.Data.OleDb
Public Class ArithmeticQuestions
Dim NoQ = ArQOP.NoQ
Dim dr As OleDbDataReader
Dim cm As New OleDbCommand
Dim cn As New OleDbConnection
Dim n As Integer = 1
Private Sub ArithmeticQuestions_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Label1.Hide()
RadioButton1.Hide()
RadioButton2.Hide()
RadioButton3.Hide()
RadioButton4.Hide()
SkipQues.Hide()
NxtQues.Hide()
End Sub
Sub Questions()
cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=login.accdb"
cn.Open()
cm.CommandText = "SELECT Questions FROM MCQ WHERE QuestionNumber ='" & n & "'"
cm.Connection = cn
dr = cm.ExecuteReader
dr.Read()
Label1.Text = dr.Item("Questions")
cn.Close()
End Sub
Private Sub NxtQues_Click(sender As Object, e As EventArgs) Handles NxtQues.Click
n = n + 1
Do
Call Questions()
Loop Until n = NoQ
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles StartQuiz.Click
Label1.Show()
RadioButton1.Show()
RadioButton2.Show()
RadioButton3.Show()
RadioButton4.Show()
SkipQues.Show()
NxtQues.Show()
StartQuiz.Hide()
Call Questions()
End Sub
End Class
Any help would be appreciated.
I am guessing that NoQ is the number of questions the user requested.
Keep you database objects local to the method where they are used so you can control that they are closed and disposed. Using...End Using blocks take care of this for you even if there is an error. You can pass the connection string directly to the constructor of the connection and the command text and connection directly to the constructor of the command.
Always use Parameters. I had to guess at the OleDbType. Check your database for the correct type and adjust the code accordingly. It appears that you are retrieving a single piece of data so you can use .ExecuteScalar to get the first column of the first row of the result set.
In the button code I just incremented the question number and checked if against the maximum number of questions.
Dim NoQ = ArQOP.NoQ
Dim n As Integer
Private Sub Questions()
Using cn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=login.accdb"),
cmd As New OleDbCommand("SELECT Questions FROM MCQ WHERE QuestionNumber = #QuestionNumber;", cn)
cmd.Parameters.Add("#QuestionNumber", OleDbType.Integer).Value = n
cn.Open()
Label1.Text = cmd.ExecuteScalar.ToString
End Using
End Sub
Private Sub NxtQues_Click(sender As Object, e As EventArgs) Handles NxtQues.Click
n += 1
If n <= NoQ Then
Questions()
End If
End Sub
so I made this code which is supposed to update the Delivery table in my MS Access database. The code runs fine and even says that data entry is successful, but upon checking the database file no new row entry is made.
Public Class NewDelivery
Dim ds As New DataSet
Dim da As OleDb.OleDbDataAdapter
Dim con As New OleDb.OleDbConnection
Public Shared stxtboxsupsel As TextBox
Public Shared supnum As String
Public Shared dgvitems As DataGridView
Private Sub NewDelivery_Load(sender As Object, e As EventArgs) Handles MyBase.Load
DateTimePicker1.Format = DateTimePickerFormat.Custom
DateTimePicker1.CustomFormat = "MM/dd/yyyy"
End Sub
Private Function OpenDBConnection()
If My.Settings.DatabaseLoc = "" Then
Dim directory As String = My.Computer.FileSystem.SpecialDirectories.MyDocuments
Return "PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source=" & directory & "\IE156.mdb"
Else
Return "PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source=" & My.Settings.DatabaseLoc
End If
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
My.Forms.ManageInventory.Show()
Me.Close()
End Sub
Private Sub btnSelSupp_Click(sender As Object, e As EventArgs) Handles btnSelSupp.Click
My.Forms.SelectSupplier.Show()
stxtboxsupsel = txtboxsupsel
End Sub
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
con.ConnectionString = OpenDBConnection()
con.Open()
Dim sql As String = "INSERT INTO Delivery(ItemPurchDate,SupNum) VALUES (#ItemPurchDate,#SupNum)"
Dim cmd As New OleDb.OleDbCommand(sql, con)
cmd.Parameters.AddWithValue("#ItemPurchDate", DateTimePicker1.Text)
cmd.Parameters.AddWithValue("#SupNum", supnum)
con.Close()
Me.Close()
MsgBox("New Delivery Recorded")
End Sub
The Delivery Table has 3 columns namely ItemPurchNum (Primary Key and Autonumber), ItemPurchDate(date/time) and SupNum(Number and has a many to one relationship with SupNum from my Supplier table).
I had no trouble adding new rows in my other forms following the similar code. Any thoughts on why it won't add a new row? Thank you in advance!
thanks for your help. Noticed that I skipped a line cmd.ExecuteNonQuery(), and now it works!
The is a database driven currency converter, where the program has to fetch the exchange rates from the database and display them.
This is what I've done so far.
Private Sub DateTimePicker1_ValueChanged(sender As Object, e As EventArgs) Handles DateTimePicker1.ValueChanged
Dim da As OleDb.OleDbDataAdapter
Dim ds As New DataSet
Dim sql As String
sql = "SELECT TOP 1 USD,EUR,GBP FROM dbexchangeRates WHERE Date='" & DateTimePicker1.Text.ToString & "'"
da = New OleDb.OleDbDataAdapter(sql, cnnOLEDB)
da.Fill(ds, "rates")
If ds.Tables("rates").Rows.Count > 0 Then
txtUSD.Text = ds.Tables("rates").Rows(0).Item(0).ToString
txtGBP.Text = ds.Tables("rates").Rows(0).Item(1).ToString
txtEUR.Text = ds.Tables("rates").Rows(0).Item(2).ToString
End If
End Sub
End Class
I recieve an Invalid operation exception on the
a.Fill(ds, "rates") '
What am i doing wrong?
Thank you for your time.
Try this:
Private Sub DateTimePicker1_ValueChanged(sender As Object, e As EventArgs) Handles DateTimePicker1.ValueChanged
Dim ds As New DataSet
Dim sql As String = "SELECT TOP 1 USD,EUR,GBP FROM dbexchangeRates WHERE Date= ?"
Using connection As New OleDb.OleDbConnection(strConnectionString),
command As New OleDb.OleDbCommand(sql, connection),
adapter As New OleDb.OleDbDataAdapter(command)
connection.Open()
adapter.SelectCommand.Parameters.Add("#dt", OleDb.OleDbType.Date).Value = DateTimePicker1.Value
adapter.Fill(ds, "rates")
connection.Close()
End Using
If ds.Tables("rates").Rows.Count > 0 Then
txtUSD.Text = ds.Tables("rates").Rows(0).Item(0).ToString
txtGBP.Text = ds.Tables("rates").Rows(0).Item(1).ToString
txtEUR.Text = ds.Tables("rates").Rows(0).Item(2).ToString
End If
End Sub
I haven't checked but I wonder if the method DateTimePicker1.ValueChanged is being called before cnnOLEDB has been initialised on MyBase.Load. This way the connection, command and adapter are all initialised at the same time. By implementing Using they will also be disposed.
You probably also want to do some data validation to ensure a valid date is set before calling the database with a query otherwise other exceptions could occur.
I'm having an Access DB and connecting to it through VB.NET.
First, I show a table records in GridView with the user having ability to update it. After the user updates, he will press a Button to take the updated data from the GridView and update the Access database.
But while doing that I get the error No value given for one or more required parameters. What I'm missing here?
Code:
Dim sConnectionString As String _
= "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\DB.accdb;Persist Security Info=False;"
Dim myConnection As OleDbConnection
Dim myAdapter As OleDbDataAdapter
Dim myTable As DataTable
Private Sub form1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
myConnection = New OleDbConnection(sConnectionString)
Dim myCommand As New OleDbCommand("SELECT ID,Test FROM T1", myConnection)
myConnection.Open()
myAdapter = New OleDbDataAdapter(myCommand)
myTable = New DataTable()
myAdapter.Fill(myTable)
setDataGridDataSource(myTable)
setLabelTxt("Row Count: " + myTable.Rows.Count.ToString(), RowCount)
DataGridView1.AllowUserToAddRows = True
DataGridView1.AllowUserToDeleteRows = True
DataGridView1.EditMode = DataGridViewEditMode.EditOnEnter
myConnection.Close()
End Sub
Private Sub button1_Click(sender As Object, e As EventArgs) Handles button1.Click
Me.Validate()
Dim command As OleDbCommand = New OleDbCommand("UPDATE T1 SET ID = ? , Test = ? WHERE ID = ?;", myConnection)
myAdapter.UpdateCommand = command
myAdapter.Update(myTable)
myTable.AcceptChanges()
End Sub
Your sql command with text "UPDATE T1 SET ID = ? , Test = ? WHERE ID = ?;" expects 3 parameters, but your are not setting them anywhere in the code. See this example and assign parameters to your command as in:
cmd.Parameters.AddWithValue("ID", txtID.Text);
cmd.Parameters.AddWithValue("Test", txtTest.Text);
... and so on
The code should be edited to this:
Private Sub button1_Click(sender As Object, e As EventArgs) Handles button1.Click
Me.Validate()
Dim cmdBuilder As OleDbCommandBuilder = New OleDbCommandBuilder(myAdapter)
Dim changes As DataTable = myTable.GetChanges
If changes IsNot Nothing Then
myAdapter.Update(myTable)
End If
myTable.AcceptChanges()
End Sub
Hi I am making a small database using sql server as the back and vb as the front end, I have nearly made it work however I have stumbled across this error.
My code is provided below would really appreciate some help.
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim cmd As New SqlCommand
conn = New SqlConnection(connectionstring)
conn.Open()
cmd = New SqlCommand("select tarif from tarif_sewa where kode_tarif = " & ComboBox1.Text & "", conn)
TextBox2.Text = cmd.ExecuteScalar
conn.Close()
End Sub
End Class
The correct approach at your query should be
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
Using conn = New SqlConnection(connectionstring)
Using cmd = New SqlCommand("select tarif from tarif_sewa where kode_tarif = #p1", conn)
conn.Open()
cmd.Parameters.AddWithValue("#p1", ComboBox1.Text)
Dim result = cmd.ExecuteScalar
If result IsNot Nothing Then
' A better conversion could be applied knowing the exact datatype of tarif '
TextBox2.Text = result.ToString
End If
End Using
End Using
End Sub
This will replace your string concatenation with a parameterized query and enclose your disposable object in a Using statement.
However I can't figure out how this error could be emitted by your code that (while it is not to be recommended as best practice) is not formally wrong