Related
I'm trying to make a login form and keep getting this error:
Visual basic System.Data.OleDb.OleDbException: 'No value given for one
or more required parameters.'
I'm using an access database with vb and everything is spelled correctly but I keep getting this error?
Private Sub Btn_Login_Click(sender As Object, e As EventArgs) Handles Btn_Login.Click
If DbConnect() Then
Dim SQLCmd As New OleDbCommand
With SQLCmd
.Connection = cn
.CommandText = "Select * From Tbl_Staff Where (Username = #sUsername) and (Password = #sPassword)"
.Parameters.AddWithValue("#sUsername", Txt_Username.Text)
.Parameters.AddWithValue("#sPassword", Txt_Password.Text)
Dim rs As OleDbDataReader = .ExecuteReader()
If rs.Read Then
PublicFirstname = rs("Firstname")
PublicStaffID = rs("StaffID")
'PublicAccessLevel = rs("AccessLevel")
frmMainMenu.Show()
Else
MsgBox("Sorry, incorrect log in details entered")
End If
rs.Close()
EDIT:
Changed my code but still getting the same error:
If DbConnect() Then
Using SQLCmd As New OleDbCommand
With SQLCmd
.Connection = cn
.CommandText = "Select * From Tbl_Staff Where (Username = ?) and ([Password] = ?)"
.Parameters.Add("#sUsername", OleDbType.VarChar).Value = Txt_Username.Text
.Parameters.Add("#sPassword", OleDbType.VarChar).Value = Txt_Password.Text
Using rs As OleDbDataReader = .ExecuteReader()
If rs.Read Then
Else
MsgBox("Sorry, incorrect log in details entered")
End If
rs.Close()
End Using
End With
End Using
End If
I see two problems here.
OleDbCommand does not support named parameters with CommandType set to Text.The order they are supplied is substantial.
PASSWORD is a reserved word in ms-access.Put it in square brackets.
Other things to enhance.
Use Using for the OleDbCommand and the OleDbDataReader.
Don't store passwords in clear-text.
So your code should look like following:
Using SQLCmd As New OleDbCommand
With SQLCmd
.Connection = cn
.CommandText = "Select * From Tbl_Staff Where (Username = ?) and ([Password] = ?)"
.Parameters.Add("#sUsername", OleDbType.VarChar).Value = Txt_Username.Text
.Parameters.Add("#sPassword", OleDbType.VarChar).Value = Txt_Password.Text
Using rs As OleDbDataReader = .ExecuteReader()
If rs.Read Then
Else
MsgBox("Sorry, incorrect log in details entered")
End If
rs.Close()
End Using
End With
End Using
EDIT:
As the column names are not Username and Password but sUsername and sPassword, you have to change the CommandText as follows:
.CommandText = "Select * From Tbl_Staff Where (sUsername = ?) and (sPassword = ?)"
I have a problem with Do until loop. When the record successfully saved and message-box appeared, after clicking the OK button it just shows the message-box and repeat it endlessly. I don't know what's the code for that. Please help.
MySqlConn.Open()
Dim last, midd, first, age, occu, phone As MySqlDataReader
Dim cmd1, cmd2, cmd3, cmd4, cmd5, cmd6, cmd7, cmd8, cmd9, cmd10, cmd11 As New MySqlCommand
Dim query1, query2, query3, query4, query5, query6, query7, query8, query9, query10, query11 As String
'lastname query
query1 = "SELECT * FROM newpatient WHERE Lastname ='" & txtLastname.Text & "'"
cmd1 = New MySqlCommand(query1, MySqlConn)
last = cmd1.ExecuteReader
'first query
query2 = "SELECT * FROM newpatient WHERE Firstname ='" & txtFirstname.Text & "'"
cmd2 = New MySqlCommand(query2, MySqlConn)
last.Close()
first = cmd2.ExecuteReader
'middle query
query3 = "SELECT * FROM newpatient WHERE Middlename ='" & txtMiddlename.Text & "'"
cmd3 = New MySqlCommand(query3, MySqlConn)
first.Close()
midd = cmd3.ExecuteReader
'age query
query4 = "SELECT * FROM newpatient WHERE Age ='" & txtAge.Text & "'"
cmd4 = New MySqlCommand(query4, MySqlConn)
midd.Close()
age = cmd4.ExecuteReader
'gender query
query5 = "SELECT * FROM newpatient WHERE Occupation ='" & txtOccupation.Text & "'"
cmd5 = New MySqlCommand(query5, MySqlConn)
age.Close()
occu = cmd5.ExecuteReader
'phone query
query6 = "SELECT * FROM newpatient WHERE Mobile_Number ='" & txtMobileNumber.Text & "'"
cmd6 = New MySqlCommand(query6, MySqlConn)
occu.Close()
phone = cmd6.ExecuteReader
Do While last.HasRows = 0 And first.HasRows = 0 And midd.HasRows = 0 And occu.HasRows = 0 And phone.HasRows = 0 And age.HasRows = 0
Dim cmd As MySqlCommand = MySqlConn.CreateCommand
cmd.CommandText = String.Format("INSERT INTO newpatient (ID, Lastname, Firstname, Middlename, Age, Mobile_Number, Gender, Address, Occupation, Month, Day, Year )" &
"VALUES ('{0}' ,'{1}' ,'{2}' ,'{3}' ,'{4}' ,'{5}' , '{6}', '{7}', '{8}', '{9}', '{10}', '{11}' )",
txtID.Text,
txtLastname.Text,
txtFirstname.Text,
txtMiddlename.Text,
txtAge.Text,
txtMobileNumber.Text,
cmbGender.SelectedItem,
txtAddress.Text,
txtOccupation.Text,
cmbMonth.SelectedItem,
cmbDay.SelectedItem,
cmbYear.SelectedItem)
phone.Close()
Dim affectedrows As Integer = cmd.ExecuteNonQuery()
If affectedrows > 0 Then
MsgBox("Record successfully saved!", MsgBoxStyle.Information, "Success")
'AUTO GENERATE RANDOM IDs
Dim random As New Random
Dim id As Integer
id = (random.Next(100000000, 1000000000))
txtID.Text = id
'CLEARS TEXTBOXES
txtMobileNumber.Text = ""
txtLastname.Text = ""
txtFirstname.Text = ""
txtMiddlename.Text = ""
txtAge.Text = 0
cmbGender.SelectedItem = ""
cmbDay.SelectedItem = ""
cmbMonth.SelectedItem = ""
cmbYear.SelectedItem = 0
txtAddress.Text = ""
txtOccupation.Text = ""
txtLastname.Select()
Else
MsgBox("Saving record failed.", MsgBoxStyle.Critical, "Failed")
'AUTO GENERATE RANDOM IDs
Dim random As New Random
Dim id As Integer
id = (random.Next(100000000, 1000000000))
txtID.Text = id
'CLEARS TEXTBOXES
txtMobileNumber.Text = ""
txtLastname.Text = ""
txtFirstname.Text = ""
txtMiddlename.Text = ""
txtAge.Text = 0
cmbGender.SelectedItem = ""
cmbDay.SelectedItem = ""
cmbMonth.SelectedItem = ""
cmbYear.SelectedItem = 0
txtAddress.Text = ""
txtOccupation.Text = ""
txtLastname.Select()
End If
Loop
'CLEARS TEXTBOXES
txtMobileNumber.Text = ""
txtLastname.Text = ""
txtFirstname.Text = ""
txtMiddlename.Text = ""
txtAge.Text = 0
cmbGender.SelectedItem = ""
cmbDay.SelectedItem = ""
cmbMonth.SelectedItem = ""
cmbYear.SelectedItem = 0
txtAddress.Text = ""
txtOccupation.Text = ""
MsgBox("Patient has already registered!", MsgBoxStyle.Critical, "Already registered")
MySqlConn.close()
To stop the loop requires a call to Exit, like so:
Exit Do
Having said that, you should never just call Exit without requiring a condition to be met, or you can encounter unexpected behavior.
But you've got much larger problems here. I'm going to list them out quickly and include a quick pseudocode suggestion (as in I've never used MySql in .Net, so not at all familiar with the API, so this code WILL need modified before it would work)
Dim cmd As MySqlCommand = MySqlConn.CreateCommand
cmd.CommandText = "INSERT INTO newpatient (ID, Lastname, Firstname, Middlename, Age, Mobile_Number, Gender, Address, Occupation, Month, Day, Year )" &
"VALUES (:ID, :Lastname, :Firstname, :Middlename, :Age, :Mobile_Number, :Gender, :Address, :Occupation, :Month, :Day, :Year)"
cmd.Parameters.Add(new MySqlParameter(":ID", txtID.Text))
cmd.Parameters.Add(new MySqlParameter(":Lastname", txtLastname.Text))
cmd.Parameters.Add(new MySqlParameter(":Firstname", txtFirstname.Text))
cmd.Parameters.Add(new MySqlParameter(":Middlename", txtMiddlename.Text))
cmd.Parameters.Add(new MySqlParameter(":Age", txtAge.Text))
cmd.Parameters.Add(new MySqlParameter(":Mobile_Number", txtMobileNumber.Text))
cmd.Parameters.Add(new MySqlParameter(":Gender", cmbGender.SelectedItem))
cmd.Parameters.Add(new MySqlParameter(":Address", txtAddress.Text))
cmd.Parameters.Add(new MySqlParameter(":Occupation", txtOccupation.Text))
cmd.Parameters.Add(new MySqlParameter(":Month", cmbMonth.SelectedItem))
cmd.Parameters.Add(new MySqlParameter(":Day", cmbDay.SelectedItem))
cmd.Parameters.Add(new MySqlParameter(":Year", cmbYear.SelectedItem))
Dim affectedrows As Integer = cmd.ExecuteNonQuery()
If affectedrows = 1 Then
MsgBox("Record successfully saved!", MsgBoxStyle.Information, "Success")
Else
If affectedrows = 0 Then
'Most likely the record already existed, call an update here and if you get 1 result, the record existed and you just saved changes
MsgBox("Patient has already registered!", MsgBoxStyle.Critical, "Already registered")
'You could change the above to a Yes/No question about updating the record and have the result in an if to update the record at the user's discretion.
cmd = MySqlConn.CreateCommand
cmd.CommandText = "UPDATE newpatient " &
"SET Lastname = :Lastname, Firstname = :Firstname, Middlename = :Middlename, Age = :Age, Mobile_Number = :Mobile_Number, " &
" Gender = :Gender, Address = :Address, Occupation = :Occupation, Month = :Month, Day = :Day, Year = :Year " &
"WHERE ID = :ID"
cmd.Parameters.Add(new MySqlParameter(":ID", txtID.Text))
cmd.Parameters.Add(new MySqlParameter(":Lastname", txtLastname.Text))
cmd.Parameters.Add(new MySqlParameter(":Firstname", txtFirstname.Text))
cmd.Parameters.Add(new MySqlParameter(":Middlename", txtMiddlename.Text))
cmd.Parameters.Add(new MySqlParameter(":Age", txtAge.Text))
cmd.Parameters.Add(new MySqlParameter(":Mobile_Number", txtMobileNumber.Text))
cmd.Parameters.Add(new MySqlParameter(":Gender", cmbGender.SelectedItem))
cmd.Parameters.Add(new MySqlParameter(":Address", txtAddress.Text))
cmd.Parameters.Add(new MySqlParameter(":Occupation", txtOccupation.Text))
cmd.Parameters.Add(new MySqlParameter(":Month", cmbMonth.SelectedItem))
cmd.Parameters.Add(new MySqlParameter(":Day", cmbDay.SelectedItem))
cmd.Parameters.Add(new MySqlParameter(":Year", cmbYear.SelectedItem))
affectedrows = cmd.ExecuteNonQuery()
If affectedrows = 1 Then
MsgBox("Record successfully saved!", MsgBoxStyle.Information, "Success")
Else
MsgBox("Saving record failed.", MsgBoxStyle.Critical, "Failed")
End If
Else
'Should never get here. We covered 0 and 1 in the other two logic branches.
'In this small demo, handling when more than 1 record gets updated is out of scope.
End If
End If
'CLEARS TEXTBOXES
txtMobileNumber.Text = ""
txtLastname.Text = ""
txtFirstname.Text = ""
txtMiddlename.Text = ""
txtAge.Text = 0
cmbGender.SelectedItem = ""
cmbDay.SelectedItem = ""
cmbMonth.SelectedItem = ""
cmbYear.SelectedItem = 0
txtAddress.Text = ""
txtOccupation.Text = ""
txtLastname.Select()
MySqlConn.close()
Never build queries from strings where you rely on a user for some of those strings. This leaves you vulnerable to SQL injection attacks (try putting a name with an apostrophe in it in one of the name fields and watch the flurry of errors. Then realize someone with malicious intentions could do serious damage to your database if you don't sanitize your inputs) Always parameterize your queries wherever possible!!
Don't repeat yourself! (AKA the DRY principle) If you find yourself copying/pasting the same block of code from place to place, that means you're doing something wrong. In this case, it was that you got stuck on the idea that you HAD to have a loop, and to make sure you're input fields were cleared, you just copied the code to clear them to 3 different places in the codepath. If you find that you NEED to run the same code repeatedly throughout your programs codepath, then generalize it and put it in a function. Your eyes and the eyes of the next person to read/maintain your code will appreciate it!
You need some more knowledge/experience with SQL, and that's ok, everyone had to start somewhere. In the sample, I removed ALL of your select queries in favor of trying ONE insert query and branching the logic based on the result of that 1 query. Much easier to read/maintain. Also, Identity values should be handle BY your sql instance, not in code. You generally want them used sequentially to avoid collisions and you don't want them modified by/visible to end users. Correcting the properties of the ID column allows removal of the random generation code. Just remember that when you insert into a table with an identity column that you don't need to include the identity column in your INSERT statement (SQL will fill that column for you)
Private Sub Save_Record()
Dim conn As New OleDbConnection
Dim cmd As New OleDbCommand
Dim sSQL As String = String.Empty
Try
conn = New OleDbConnection(Get_Constring)
conn.Open()
cmd.Connection = conn
cmd.CommandText = CommandType.Text
If Me.txt_Forename.Tag = 0 Then
sSQL = "INSERT INTO PlayerDatabase ( Age_Group, Surname, Forename, Rating, DOB, Address, Email, Position, Foot, Mins_Played, Goals, Assists, Yellow_Cards, Red_Cards)"
sSQL = sSQL & " VALUES(#Age_Group, #Surname, #Forename, #Rating, #DOB, #Address, #Email, #Position, #Foot, #Mins_Played, #Goals, #Assists, #Yellow_Cards, #Red_Cards)"
Else
sSQL = "UPDATE PlayerDatabase set Age_Group = #Age_Group, Surname = #Surname, Forename = #Forename, Rating = #Rating, DOB = #DOB, Address = #Address, Email = #Email, Position = #Position, Foot = #Foot, Mins_Played = #Mins_Played, Goals = #Goals, Assists = #Assists, Yellow_Cards = #Yellow_Cards, Red_Cards = #Red_Cards WHERE ID = #id"
cmd.CommandText = sSQL
End If
cmd.Parameters.Add("#Surname", OleDbType.VarChar).Value = IIf(Len(Trim(Me.txt_Surname.Text)) > 0, Me.txt_Surname.Text, DBNull.Value)
cmd.Parameters.Add("#Forename", OleDbType.VarChar).Value = IIf(Len(Trim(Me.txt_Forename.Text)) > 0, Me.txt_Forename.Text, DBNull.Value)
cmd.Parameters.Add("#DOB", OleDbType.Date).Value = Me.dtp_DOB.Text
cmd.Parameters.Add("#Address", OleDbType.VarChar).Value = Me.txt_Address.Text
cmd.Parameters.Add("#Age_Group", OleDbType.VarChar).Value = Me.cb_AgeGroup.Text
cmd.Parameters.Add("#Rating", OleDbType.VarChar).Value = Me.cb_Rating.Text
cmd.Parameters.Add("#Email", OleDbType.VarChar).Value = Me.txt_Email.Text
cmd.Parameters.Add("#Position", OleDbType.VarChar).Value = Me.cb_Position.Text
cmd.Parameters.Add("#Foot", OleDbType.VarChar).Value = Me.cb_Foot.Text
cmd.Parameters.Add("#Mins_Played", OleDbType.VarChar).Value = Me.nup_MinsPlayed.Text
cmd.Parameters.Add("#Goals", OleDbType.VarChar).Value = Me.nup_Goals.Text
cmd.Parameters.Add("#Assists", OleDbType.VarChar).Value = Me.nup_Assists.Text
cmd.Parameters.Add("#Yellow_Cards", OleDbType.VarChar).Value = Me.nup_YellowCards.Text
cmd.Parameters.Add("#Red_Cards", OleDbType.VarChar).Value = Me.nup_RedCards.Text
cmd.Parameters.Add("#ID", OleDbType.Numeric).Value = Me.txt_Forename.Tag
cmd.ExecuteNonQuery()
If Me.txt_Forename.Tag = 0 Then
cmd.CommandText = "Select ##Identity"
Me.txt_Forename.Tag = cmd.ExecuteScalar()
End If
MsgBox("Data has been saved.")
Catch ex As Exception
MsgBox(ErrorToString)
Finally
conn.Close()
End Try
End Sub
Not sure what I'm doing wrong here. This is a adding to an Access database from various textboxes, comboboxes etc. This procedure runs when a button is pressed on a form that has the inputs. I'm a beginner at vb.net and programming in general so if it's something obvious I apologise.
Thanks
The word POSITION is reserved in MS-Access Jet Sql. This is the reason of the SYNTAX ERROR.
If you want to use it as a name for a column or for a table you need to put it between square brackets
sSQL = "INSERT INTO PlayerDatabase ( Age_Group, Surname, Forename, Rating, DOB, " & _
"Address, Email, [Position], Foot, Mins_Played, Goals, Assists, Yellow_Cards, Red_Cards)"
....
sSQL = "UPDATE PlayerDatabase set Age_Group = #Age_Group, Surname = #Surname, " & _
"Forename = #Forename, Rating = #Rating, DOB = #DOB, Address = #Address, " & _
"Email = #Email, [Position] = #Position, Foot = #Foot, Mins_Played = #Mins_Played, " & _
"Goals = #Goals, Assists = #Assists, Yellow_Cards = #Yellow_Cards, " & _
"Red_Cards = #Red_Cards WHERE ID = #id"
A part from this you have another problem. OleDb doesn't recognize the parameters by their names. Usually you should use a question mark instead of a name, but Access allows this probably for some kind of portability toward its big cousin Sql Server. In any case you should add the parameters in the OleDbCommand collection in the same order in which the named placeholders appears in your query. So you need this order:
cmd.Parameters.Add("#Age_Group", OleDbType.VarChar).Value = Me.cb_AgeGroup.Text
cmd.Parameters.Add("#Surname", OleDbType.VarChar).Value = IIf(Len(Trim(Me.txt_Surname.Text)) > 0, Me.txt_Surname.Text, DBNull.Value)
cmd.Parameters.Add("#Forename", OleDbType.VarChar).Value = IIf(Len(Trim(Me.txt_Forename.Text)) > 0, Me.txt_Forename.Text, DBNull.Value)
cmd.Parameters.Add("#Rating", OleDbType.VarChar).Value = Me.cb_Rating.Text
cmd.Parameters.Add("#DOB", OleDbType.Date).Value = Me.dtp_DOB.Text
cmd.Parameters.Add("#Address", OleDbType.VarChar).Value = Me.txt_Address.Text
cmd.Parameters.Add("#Email", OleDbType.VarChar).Value = Me.txt_Email.Text
cmd.Parameters.Add("#Position", OleDbType.VarChar).Value = Me.cb_Position.Text
cmd.Parameters.Add("#Foot", OleDbType.VarChar).Value = Me.cb_Foot.Text
cmd.Parameters.Add("#Mins_Played", OleDbType.VarChar).Value = Me.nup_MinsPlayed.Text
cmd.Parameters.Add("#Goals", OleDbType.VarChar).Value = Me.nup_Goals.Text
cmd.Parameters.Add("#Assists", OleDbType.VarChar).Value = Me.nup_Assists.Text
cmd.Parameters.Add("#Yellow_Cards", OleDbType.VarChar).Value = Me.nup_YellowCards.Text
cmd.Parameters.Add("#Red_Cards", OleDbType.VarChar).Value = Me.nup_RedCards.Text
and this last parameter should be added only if you have the UPDATE path not for the INSERT. (Assuming the ID column to be an AutoIncrement one)
If Me.txt_Forename.Tag <> 0 Then
cmd.Parameters.Add("#ID", OleDbType.Numeric).Value = Me.txt_Forename.Tag
End If
Also another problem at the end when you try to read the ##IDENTITY value. Using the same command is fine, but you need to clear the parameters collection
If Me.txt_Forename.Tag = 0 Then
cmd.Parameters.Clear()
cmd.CommandText = "Select ##Identity"
Me.txt_Forename.Tag = cmd.ExecuteScalar()
End If
I have a table full of stock price data. Each row has a unique combination of Ticker symbols and dates. I load new data all the time by obtaining CSV files containing stock price data for everyday for every ticker. I know that there are duplicates in the CSV files. I only want to add that data that is not already in my data table. What is the quickest way to do this?
Should I try to add every row and catch each exception? Or, should I compare each row against my data table by reading my data table to see that line already exists? Or, is there another alternative?
Additional Info
This is what I have been doing. For each line in the CSV file I read my data table to see if it already exists.
Dim strURL As String
Dim strBuffer As String
strURL = "http://ichart.yahoo.com/table.csv?s=" & tickerValue
strBuffer = RequestWebData(strURL)
Dim sReader As New StringReader(strBuffer)
Dim List As New List(Of String)
Do While sReader.Peek >= 0
List.Add(sReader.ReadLine)
Loop
List.RemoveAt(0)
Dim lines As String() = List.ToArray
sReader.Close()
For Each line In lines
Dim checkDate = line.Split(",")(0).Trim()
Dim dr As OleDbDataReader
Dim cmd2 As New OleDb.OleDbCommand("SELECT * FROM " & tblName & " WHERE Ticker = ? AND [Date] = ?", con)
cmd2.Parameters.AddWithValue("?", tickerValue)
cmd2.Parameters.AddWithValue("?", checkDate)
dr = cmd2.ExecuteReader
If dr.Read() = 0 Then
Dim cmd3 As OleDbCommand = New OleDbCommand("INSERT INTO " & tblName & " (Ticker, [Date], [Open], High, Low, [Close], Volume, Adj_Close) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", con)
cmd3.Parameters.Add("#Ticker", OleDbType.VarChar).Value = tickerValue
cmd3.Parameters.Add("#[Date]", OleDbType.VarChar).Value = checkDate
cmd3.Parameters.Add("#[Open]", OleDbType.VarChar).Value = line.Split(",")(1).Trim
cmd3.Parameters.Add("#High", OleDbType.VarChar).Value = line.Split(",")(2).Trim
cmd3.Parameters.Add("#Low", OleDbType.VarChar).Value = line.Split(",")(3).Trim
cmd3.Parameters.Add("#[Close]", OleDbType.VarChar).Value = line.Split(",")(4).Trim
cmd3.Parameters.Add("#Volume", OleDbType.VarChar).Value = line.Split(",")(5).Trim
cmd3.Parameters.Add("#Adj_Close", OleDbType.VarChar).Value = line.Split(",")(6).Trim
cmd3.ExecuteNonQuery()
Else
End If
This is what I have switched to and it gives this exception: The changes you requested to the table were not successful because they would create duplicate values in the index, primary key, or relationship. Change the data in the field or fields that contain duplicate data, remove the index, or redefine the index to permit duplicate entries and try again. I could catch this exception every time and ignore it until I hit a line that is new.
Dim strURL As String = "http://ichart.yahoo.com/table.csv?s=" & tickerValue
Debug.WriteLine(strURL)
Dim strBuffer As String = RequestWebData(strURL)
Using streamReader = New StringReader(strBuffer)
Using reader = New CsvReader(streamReader)
reader.ReadHeaderRecord()
While reader.HasMoreRecords
Dim dataRecord As DataRecord = reader.ReadDataRecord()
Dim cmd3 As OleDbCommand = New OleDbCommand("INSERT INTO " & tblName & " (Ticker, [Date], [Open], High, Low, [Close], Volume, Adj_Close) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", con)
cmd3.Parameters.Add("#Ticker", OleDbType.VarChar).Value = tickerValue
cmd3.Parameters.Add("#[Date]", OleDbType.VarChar).Value = dataRecord.Item("Date")
cmd3.Parameters.Add("#[Open]", OleDbType.VarChar).Value = dataRecord.Item("Open")
cmd3.Parameters.Add("#High", OleDbType.VarChar).Value = dataRecord.Item("High")
cmd3.Parameters.Add("#Low", OleDbType.VarChar).Value = dataRecord.Item("Low")
cmd3.Parameters.Add("#[Close]", OleDbType.VarChar).Value = dataRecord.Item("Close")
cmd3.Parameters.Add("#Volume", OleDbType.VarChar).Value = dataRecord.Item("Volume")
cmd3.Parameters.Add("#Adj_Close", OleDbType.VarChar).Value = dataRecord.Item("Adj Close")
cmd3.ExecuteNonQuery()
End While
End Using
End Using
I just want to use the most efficient method.
Update
Per the answers below, this is the code I have so far:
Dim strURL As String = "http://ichart.yahoo.com/table.csv?s=" & tickerValue
Dim strBuffer As String = RequestWebData(strURL)
Using streamReader = New StringReader(strBuffer)
Using reader = New CsvReader(streamReader)
' the CSV file has a header record, so we read that first
reader.ReadHeaderRecord()
While reader.HasMoreRecords
Dim dataRecord As DataRecord = reader.ReadDataRecord()
Dim cmd3 As OleDbCommand = New OleDbCommand("INSERT INTO " & tblName & "(Ticker, [Date], [Open], High, Low, [Close], Volume, Adj_Close) " & "SELECT ?, ?, ?, ?, ?, ?, ?, ? " & "FROM DUAL " & "WHERE NOT EXISTS (SELECT 1 FROM " & tblName & " WHERE Ticker = ? AND [Date] = ?)", con)
cmd3.Parameters.Add("#Ticker", OleDbType.VarChar).Value = tickerValue
cmd3.Parameters.Add("#[Date]", OleDbType.VarChar).Value = dataRecord.Item("Date")
cmd3.Parameters.Add("#[Open]", OleDbType.VarChar).Value = dataRecord.Item("Open")
cmd3.Parameters.Add("#High", OleDbType.VarChar).Value = dataRecord.Item("High")
cmd3.Parameters.Add("#Low", OleDbType.VarChar).Value = dataRecord.Item("Low")
cmd3.Parameters.Add("#[Close]", OleDbType.VarChar).Value = dataRecord.Item("Close")
cmd3.Parameters.Add("#Volume", OleDbType.VarChar).Value = dataRecord.Item("Volume")
cmd3.Parameters.Add("#Adj_Close", OleDbType.VarChar).Value = dataRecord.Item("Adj Close")
cmd3.Parameters.Add("#Ticker", OleDbType.VarChar).Value = tickerValue
cmd3.Parameters.Add("#[Date]", OleDbType.VarChar).Value = dataRecord.Item("Date")
cmd3.ExecuteNonQuery()
End While
End Using
End Using
It gives me this error Data type mismatch in criteria expression.
Most DBMS support a (non-standard) clause for the INSERT command to ignore duplicates, e.g.:
MySQL: INSERT IGNORE INTO ...
SQLite: INSERT OR IGNORE INTO INTO ...
This is the quickest way in non-batch mode, as you don't have to read the database before you write.
You can do the same with standard SQL using:
INSERT INTO ...
SELECT <your values>
WHERE NOT EXISTS ( <query for your values by id> );
Or (when you explicitly need a FROM clause):
INSERT INTO ...
SELECT <your values>
FROM DUAL
WHERE NOT EXISTS ( <query for your values by id> );
EDIT
MS Access does not have a built-in DUAL table (i.e., a table that always contains just one single row), but Access requires a FROM clause. So you have to build your own DUAL table:
CREATE TABLE DUAL (DUMMY INTEGER);
INSERT INTO DUAL VALUES (1);
You just do this once and for all. Then, in your code you would do inserts like
INSERT INTO MyTable (A,B,C,D)
SELECT 123, 456, 'Hello', 'World'
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM MyTable WHERE A = 123 AND B = 456);
Thus, for your example, use:
Dim cmd3 As OleDbCommand = New OleDbCommand(_
"INSERT INTO " & tblName & _
"(Ticker, [Date], [Open], High, Low, [Close], Volume, Adj_Close) " & _
"SELECT ?, ?, ?, ?, ?, ?, ?, ? " & _
"FROM DUAL " & _
"WHERE NOT EXISTS (SELECT 1 FROM tblName WHERE Ticker = ? AND [Date] = ? AND ...)", con)
(WHERE clause depending on your key columns)
I get error on updating. I am just new to this code. I would really appreciate any help.
Private Sub Save_Record()
Dim conn As New OleDbConnection
Dim cmd As New OleDbCommand
Dim sSQL As String = "SELECT * FROM Instructor"
Try
'get connection string declared in the Module1.vb and assing it to conn variable
conn = New OleDbConnection(Get_Constring)
conn.Open()
cmd.Connection = conn
cmd.CommandType = CommandType.Text
'I just use the textbox tag property to idetify if the data is new or existing.
sSQL = "UPDATE Instructor set fname = ?, lname =?, mname =? , [password] = ?, [level]=?, where Username = ?"
cmd.CommandText = sSQL
cmd.Parameters.AddWithValue("#p1", txtfname.Text)
cmd.Parameters.AddWithValue("#p2", txtlname.Text)
cmd.Parameters.AddWithValue("#p3", txtinitial.Text)
cmd.Parameters.AddWithValue("#p4", txtpass.Text)
cmd.Parameters.AddWithValue("#p5", lbllevel.Text)
cmd.Parameters.AddWithValue("#p6", txtusername.Text)
cmd.ExecuteNonQuery()
MsgBox("Data has been save.")
Catch ex As Exception
MsgBox(ErrorToString)
Finally
conn.Close()
End Try
End Sub
you have an additional coma just before where [level]=?, where Username. Try this
sSQL = "UPDATE Instructor set fname = ?, lname =?, mname =? , [password] = ?, [level]=? where Username = ?"