Quick one for you.
I'm using the following code to insert a record into two tables in my mysql db...
SQLConnection.ConnectionString = connectionstring
Try
If SQLConnection.State = ConnectionState.Closed Then
SQLConnection.Open()
Dim SQLStatement As String = "INSERT INTO hosts(name, description, host, type, port, hostname) VALUES('" & txtname.Text & "','" & txtdescription.Text & "','" & txthost.Text & "','" & cmbtype.Text & "','" & txtport.Text & "','" & Pinger.resolvedstatus.Text & "'); SELECT LAST_INSERT_ID()"
SaveData(SQLStatement)
SQLConnection.Open()
SQLStatement = "INSERT INTO credentials(hosts_linked_id, username, password, type) VALUES('" & hosts_linked_id & "','" & txtusername.Text & "','" & txtpwd.Text & "','" & cmbtype.Text & "')"
SaveData(SQLStatement)
the Savedata() bit calls this function...
Public Sub SaveData(ByRef SQLStatement As String)
Dim cmd As MySqlCommand = New MySqlCommand
cmd.CommandText = SQLStatement
cmd.CommandType = CommandType.Text
cmd.Connection = SQLConnection
cmd.ExecuteNonQuery()
hosts_linked_id = CInt(cmd.ExecuteScalar())
SQLConnection.Close()
MsgBox("Host has been added - Host ID " & hosts_linked_id & "")
txtname.Text = ""
txtdescription.Text = ""
txthost.Text = ""
cmbtype.Text = ""
txtport.Text = ""
End Sub
The code is working in that the necessary records are inserted into both the 'hosts' and 'credentials' tables, however in each table the record is inserted twice.
obviously I don't want duplicate records in my db, so can anyone help me stop it from performing the insert twice?
Thanks in advance!!
You call it twice:
cmd.ExecuteNonQuery()
hosts_linked_id = CInt(cmd.ExecuteScalar())
Once as ExecuteNonQuery and second time as ExecuteScalar()
You need to remove one of them. Looking at the code, I guess maybe you need to introduce a parameter to SaveData method to say which one to use.
cmd.ExecuteNonQuery()
hosts_linked_id = CInt(cmd.ExecuteScalar())
Remove cmd.ExecuteNonQuery() To avoid Insert Twice
Related
Good day! Can someone help me fix my code? I would like to show an error message if there is a duplication of record. For example, I entered a username "admin" but it is already in my database so it should show a message saying "Username already exists!". Otherwise, If the username isn't used yet then it will be added in my database. I'm using Visual Studio 2005 and Navicat for MySQL
Here is my code:
conn.Open()
Dim qadd As String = "SELECT * FROM tbl_user WHERE uname='" & txt_uname.Text & "'"
Dim cmd As New MySqlCommand(qadd, conn)
Dim data As MySqlDataReader = cmd.ExecuteReader
If data.Read Then
If data(0) = txt_uname.Text Then
MsgBox("User " & data(0) & " already exists! ", MsgBoxStyle.Critical)
Else
Dim qstr As String = "INSERT INTO tbl_user (uname, pword, ulvl) VALUES ('" & txt_uname.Text & "' , '" & txt_pword1.Text & "' , '" & txt_pword2.Text & "') ON DUPLICATE KEY UPDATE uname = '" & txt_uname.Text & "'"
Dim cm As New MySqlCommand(qstr, conn)
Dim dat As MySqlDataReader = cm.ExecuteReader
MsgBox("User has been added!", MsgBoxStyle.Information)
txt_uname.Clear()
txt_pword1.Clear()
txt_pword2.Clear()
txt_uname.Focus()
End If
End If
conn.Close()
Still a lot of room for improvement, and I typed this out on my phone with no syntax checking, but think it should get you heading in the right direction. Things for you to read up on is parametrising your query/insert statements and the Using keyword which can help with managing your db connections.
Dim qadd As String = "SELECT Count(uname) FROM tbl_user WHERE uname='" & txt_uname.Text & "'"
Dim cmd As New MySqlCommand(qadd, conn)
Dim userCounter as int = cmd.ExecuteScaler
if userCounter > 0 then
MsgBox("User " & data(0) & " already exists! ", MsgBoxStyle.Critical)
Else
Dim qstr As String = "INSERT INTO tbl_user (uname, pword, ulvl) VALUES ('" & txt_uname.Text & "' , '" & txt_pword1.Text & "' , '" & txt_pword2.Text & "') ON DUPLICATE KEY UPDATE uname = '" & txt_uname.Text & "'"
Dim cm As New MySqlCommand(qstr, conn)
Dim dat As MySqlDataReader = cm.ExecuteReader
MsgBox("User has been added!", MsgBoxStyle.Information)
txt_uname.Clear()
txt_pword1.Clear()
txt_pword2.Clear()
txt_uname.Focus()
End If
I want to prevent duplicate entries to my inventory form using vb.net and MySQL as the database, here is my code:
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
Dim myCommand As New MySqlCommand
Dim conn As MySqlConnection
Dim i As String
conn = New MySqlConnection
conn.ConnectionString = "server = localhost;username= root;password= a;database= secret"
Try
conn.Open()
Catch mali As MySqlException
MsgBox("connot establish connection")
End Try
Dim intReturn As Integer
Dim strSql As String = " select * from personnel where pcode = #pcode"
Dim sqlcmd As New MySqlCommand(strSql, conn)
With sqlcmd.Parameters
.AddWithValue("#pcode", CType(pcode.Text, String))
End With
intReturn = sqlcmd.ExecuteScalar
If (intReturn > 0) Then
cmd = New MySqlCommand("Insert into personnel values('" & pcode.Text & "','" & lname.Text & "','" & fname.Text & "','" & office.Text & "','" & designation.Text & "')")
i = cmd.ExecuteNonQuery
If pcode.Text <> "" Then
ElseIf i > 0 Then
MsgBox("Save Successfully!", MessageBoxIcon.Information, "Success")
mrClean()
ListView1.Tag = ""
Call objLocker(False)
Call LVWloader()
Call calldaw()
Else
MsgBox("Save Failed!", MessageBoxIcon.Error, "Error!")
End If
Else
MsgBox("Personnel ID Already Exist!", MessageBoxIcon.Error, "Error!")
End If
end sub
i found this while i search for answer, but when i tried to run it, it does not read the insert command but rather it goes directly to the msbox "Personnel ID Already Exist" even if theres no thesame Personnel ID.
can someone check why it does not read the insert please,
my Database tables values:
pcode = primary key
lname = longtext
fname = longtext
office = longtext
designation = longtext
any help will be much appreciated, thanks,
Sorry to say this is the wrong approach.
Databases have a built in system to prevent data being duplicated. That's through primary keys or unique key constraints. In your case, you have already created a primary key. So there is absolutely no need for you to do that SELECT COUNT(*) query.
Instead, just directly insert into the table and catch the integrity error when the pcode already exists.
Try
cmd = New MySqlCommand("Insert into personnel values('" & pcode.Text & "','" & lname.Text & "','" & fname.Text & "','" & office.Text & "','" & designation.Text & "')")
i = cmd.ExecuteNonQuery
If pcode.Text <> "" Then
ElseIf i > 0 Then
MsgBox("Save Successfully!", MessageBoxIcon.Information, "Success")
mrClean()
ListView1.Tag = ""
Call objLocker(False)
Call LVWloader()
Call calldaw()
Else
MsgBox("Save Failed!", MessageBoxIcon.Error, "Error!")
End If
Catch ex As MySqlException
MsgBox("Personnel ID Already Exist!", MessageBoxIcon.Error, "Error!")
End Try
Please also refer to the MySQL Manual Page PRIMARY KEY and UNIQUE Index Constraints
There should be the way you:
1) write a Trigger before Insert, and check if there is any similar row exist.
2) Put Unique Index on columns
found the answer, as what #e4c5 said, its a wrong approach, so I restructed my code and finally made it work, just want to share the answer maybe it will help others.
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
Dim myCommand As New MySqlCommand
Dim conn As MySqlConnection
Dim i As String
conn = New MySqlConnection
conn.ConnectionString = "server = localhost;username= root;password= a;database= secret"
Try
conn.Open()
Catch mali As MySqlException
MsgBox("connot establish connection")
End Try
Dim retval As String
Select Button4.Tag
Case "ADD"
with myCommand
.Connection = conn
.CommandText = "Select pcode from personnel where pcode = '" & pcode.Text & "'"
retval = .ExecuteScalar
If retval Is Nothing Then
.CommandText = "Insert into personnel values ('" & pcode.Text & "','" & lname.Text & "','" & fname.Text & "','" & office.text & "','" & designation.Text & "')"
.ExecuteNonQuery()
Else
MsgBox("Personnel ID Already Exist!", MessageBoxIcon.Error, "Error")
End If
End With
End Sub
Here's the code of my button_click:
Private Sub Button10_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button10.Click
Dim conn As New MySqlConnection
Dim cmd As New MySqlCommand
Dim dr As MySqlDataReader
conn.ConnectionString = "server = localhost; user id = root; database = db; password = root"
cmd.Connection = conn
conn.Open()
cmd.CommandText = " SELECT * FROM candidate WHERE idn = '" & TextBox4.Text & "'"
dr = cmd.ExecuteReader
If dr.HasRows Then
MessageBox.Show("Entry I.D. No. already exist", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
ElseIf TextBox4.Text = "" Or TextBox5.Text = "" Or TextBox6.Text = "" Or TextBox7.Text = "" Or ComboBox1.Text = "" Or TextBox3.Text = "" Then
MessageBox.Show("Please complete the required fields..", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Else
conn.Close()
con.ConnectionString = "server = localhost; user id = root; database = db; password = root"
cmd.Connection = con
con.Open()
Dim sqlQuery As String = "INSERT INTO candidate(idn,cfname,cmname,clname,cyr,sec,vyear,votes,pword) VALUES('" & TextBox4.Text & "','" & TextBox5.Text & "','" & TextBox6.Text & "','" & TextBox7.Text & "','" & ComboBox1.Text & "','" & TextBox3.Text & "',CONCAT(YEAR(NOW()),'-',(YEAR(NOW()) + 1),'0','" & TextBox2.Text & "')"
Dim sqlCommand As New MySqlCommand
With sqlCommand
.CommandText = sqlQuery
.Connection = con
.ExecuteNonQuery()
End With
MsgBox("Record Inserted")
End If
End Sub
what's wrong with my INSERT query? I can't seem to find anything wrong here, but VB.NET says it has error in " at line 1?
"INSERT INTO candidate(vyear) VALUES(CONCAT(YEAR(NOW()),'-',(YEAR(NOW()) + 1))"
There is a unbalanced open parenthesis before the second YEAR. Need to remove it
"INSERT INTO candidate(vyear) VALUES( CONCAT(YEAR(NOW()),'-',YEAR(NOW()) + 1) )"
Looking at the updated code you really need to start to use parameterized queries
Using con = new MySqlConnection(......)
Using cmd = con.CreateCommand()
con.Open()
Dim sqlQuery As String = "INSERT INTO candidate " & _
"(idn,cfname,cmname,clname,cyr,sec,vyear,votes,pword) VALUES(" & _
"#idn, #cfname, #cmname, #clname, #cyr, #sec, " & _
"CONCAT(YEAR(NOW()),'-',YEAR(NOW()) + 1), " & _
"#votes, #pword"
With cmd
.CommandText = sqlQuery
' is idn an integer field, then pass it as integer.
' instead if it is an autoincrement then remove it and let the db calculate for you
.Parameters.AddWithValue("#idn", Convert.ToInt32(TextBox4.Text))
.Parameters.AddWithValue("#cfname, TextBox5.Text)
.... and so on for every placeholder in the parameterized text above
.ExecuteNonQuery()
End With
MsgBox("Record Inserted")
End Using
End Using
Hey guys I have to extract some values from my DB and put them on my textbox. There's a problem at :
TextBox1.Text = TextBox1.Text & DR.Item("id") & Space(3) & DR.Item("Nume") & Space(3) & DR.Item("COUNT(pontaj.prezente)")
Error in VB:
This is how my select looks like:
Dim dbCon = New MySqlConnection("Server = localhost;Database = users; Uid=root; Pwd = password ")
'SELECT users1.id,users1.Nume, COUNT(pontaj.prezente) FROM users1, pontaj WHERE users1.id = pontaj.id
Dim strQuery = "SELECT users1.id,users1.Nume, COUNT(pontaj.prezente)" & _
"FROM users1, pontaj "
Dim SQLCmd = New MySqlCommand(strQuery, dbCon)
' Pwd = password
' Open
dbCon.Open()
Dim DR = SQLCmd.ExecuteReader
TextBox1.Text = TextBox1.Text & DR.Item("id") & Space(3) & DR.Item("Nume") & Space(3) & DR.Item("COUNT(pontaj.prezente)") & vbCrlf
While DR.Read
End While
'Close
DR.Close()
dbCon.Close()
Well, the error is clear, you cannot access the fields of a DataReader before calling Read.
The call is required to position the reader on the first record returned by the query and then to advance on the subsequent records until you reach the end of the returned records.
Also the syntax for your query seems incorrect and the way you reference the third column of your query
Dim dbCon = New MySqlConnection(............)
Dim strQuery = "SELECT users1.id,users1.Nume, COUNT(pontaj.prezente) as countPrezente " & _
"FROM users1 INNER JOIN pontaj ON users1.id = pontaj.id " & _
"GROUP BY users1.id, users1.Nume"
Dim SQLCmd = New MySqlCommand(strQuery, dbCon)
dbCon.Open()
Dim DR = SQLCmd.ExecuteReader
' If Read returns true then you have one or more record to show'
While DR.Read()
TextBox1.Text = TextBox1.Text & _
DR.Item("id") & Space(3) & _
DR.Item("Nume") & Space(3) & _
DR.Item("countPrezente") & vbCrlf
End While
DR.Close
dbCon.Close
Looking at your previous question, the Foreign Key between users1 and pontaj is named id, so I have used an explicit join between the two tables to link the records from the two tables
UPDATED QUESTION...SEE BELOW
I have an excel sheet which accesses a MySQL db as a backend....
I insert new records into MySql the following way, but I am not sure if this is the best way.
For rowline = 1 To 50
strSQL = myquerystring (INSERT 5 columns per excel row)
rs.Open strSQL, oConn, adOpenDynamic, adLockOptimistic
Next rowline
Basically the query string goes through each row in excel sheet (from 1 to 50) and the data on certain cells are added to the sql query and then inserted with rs.Open ....
(each row has some 5 columns which are inserted as a record)
Everything runs well, however I just want to know if there is a faster way (just one INSERT query), inserting all 50 (and 5 columns on each), from row 1 to 50, all at once.
At the moment it is doing 50 individual INSERT queries, so I am trying to reduce that to 1 but I don't know if it is possible.
NEW INFORMATION:
Hi, following your advice and links (thanks!) and some Googling, I ended up with the following code...
It works fine, HOWEVER to INSERT 100 rows it takes approx 15 seconds....this is far too much.
I am hoping I can get some code/ideas on how to Execute the query once, (inserting all 100 rows in one hit).
Please note that I am a beginner on this so if you can stir me into some samples on how it should be done it will be much appreciated.
Public Sub INSERT_to_MySQL()
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Dim strSQL As String
app_enable_false
On Error GoTo no_DB_connection_error
resume_after_connecting:
Set cmd = New ADODB.Command
cmd.ActiveConnection = oConn
' LOOP and INSERT the data
' 100 rows take approx 15 seconds to INSERT
For rowcursor= 1 To 100
the_table = "`global`.`filesaved` "
strSQL = "INSERT INTO " & the_table & " (Client_Name, OriginCity, DestinationCity, ValidFrom, ValidTo, Quote_Number, Cost1, Cost2, Cost3) "
strSQL = strSQL & " VALUES ('" & esc(Range("BB" & rowcursor)) & "','" & esc(Range("BC" & rowcursor)) & "','" & esc(Range("BD" & rowcursor)) & "','" & Format(Range("BE" & rowcursor), "yyyy-mm-dd") & "','" & Format(Range("BF" & rowcursor), "yyyy-mm-dd")
strSQL = strSQL & "','" & esc(Range("BH" & rowcursor)) & "','" & esc(Range("BJ" & rowcursor)) & "','" & esc(Range("BK" & rowcursor)) & "','" & esc(Range("BJ" & rowcursor)) & "')"
cmd.CommandText = strSQL
cmd.Execute
Next rowcursor
app_enable_true
Exit Sub
no_DB_connection_error:
ConnectDB
GoTo resume_after_connecting
End Sub
I would move the open command outside the loop, then use the Execute method to do the inserts in the loop. You don't want to do an open on the database every time.
Here's a good page of ADO methods.
Here's a question on Batch Inserting (and Updating).
EDIT: Looking at Remou's link in his comment, I realized that you probably don't even need the open. Just use the Execute method for the Inserts.
Find below a process which works, in case someone else has in future same problem.
Might not be the best solution but 100 records are saved all at once in less than a second, which is what I was after. Also there is only one INSERT query done (instead of 100 different ones for each row.
Thanks to all for your guidance.
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command
Dim rst_recordset As ADODB.Recordset
Dim strSQL As String
Dim strSQL2 as string
On Error GoTo no_DB_connection_error
resume_after_connecting:
Set cmd = New ADODB.Command
cmd.ActiveConnection = oConn
' LOOP and INSERT the data
lastrow = Range("BB65536").End(xlUp).Row
the_table = "`global`.`filesaved` "
strSQL = "INSERT INTO `global`.`filesaved` " & " (Client_Name, OriginCity, DestCity, ValidFrom, ValidTo, Quote_Number, Cost1, Cost2, Cost3) VALUES "
strSQL2 = ""
For excel_row = 1 To lastrow
strSQL2 = strSQL2 & " ('" & cells(excel_row,1) & "','" & cells(excel_row,2) & "','" & cells(excel_row,3) & "','" & cells(excel_row,4) & "','" & cells(excel_row,5) & "','" & cells(excel_row,6) & "','" & cells(excel_row,7) & "','" & cells(excel_row,8) & "','" & cells(excel_row,9) & "') ,"
next excel_row
strSQL = strSQL & strSQL2
Mid(strSQL, Len(strSQL), 1) = ";" ' gets rid of the last comma
cmd.CommandText = strSQL
cmd.Execute
If I run a statement and do not expect a reply back, I usually go for the Command object in VBA.
This code worked for me
Sub insertdata()
Dim year As String
Set rs = CreateObject("ADODB.Recordset")
Database_Name = Range("b3").Value ' Name of database
User_ID = Range("b4").Value 'id user or username
Password = Range("b5").Value 'Password
Server_Name =Range("b2").Value
' Query for fetching Maximum Date
' LOOP and INSERT the data
lastrow = Range("BB65536").End(xlUp).Row
the_table = "`admin`.`test` "
strSQL = "INSERT INTO `drawing`.`test` " & " (tests,test2) VALUES "
strSQL2 = ""
For excel_row = 1 To 100
strSQL2 = strSQL2 & " ('" & Cells(excel_row, 1) & "','" & Cells(excel_row, 2) & "') ,"
Next excel_row
strSQL = strSQL & strSQL2
Mid(strSQL, Len(strSQL), 1) = ";" '
' ADODB connection
Set Cn = CreateObject("ADODB.Connection") 'NEW STATEMENT
Cn.Open "Driver={MySQL ODBC 5.1 Driver};Server=" & Server_Name & ";Database=" & Database_Name & _
";Uid=" & User_ID & ";Pwd=" & Password & ";"
rs.Open strSQL, Cn, adOpenStatic
Dim myArray()
End Sub