How can i insert data again when it keeps saying open and close connection? - mysql

what is wrong with this code. i cannot insert data anymore, i kept
saying close and open the connection but when i open it i says . the
connection was already open. hope u help me
For employee_id As Integer = 0 To DataGridView1.Rows.Count - 1
If txt_employee_id.Text = DataGridView1.Rows(employee_id).Cells(0).Value.ToString Then
MessageBox.Show("Duplicate ID")
Else
cmd = con.CreateCommand()
cmd.CommandType = CommandType.Text
cmd.CommandText = "INSERT INTO employeelist VALUES('" + txt_employee_id.Text + "', '" + txt_password.Text + "', '" + txt_name.Text + "', '" + txt_address.Text + "', '" + txt_contact_info.Text + "', '" + txt_department.Text + "', '" + txt_position.Text + "', '" + txt_basic_salary.Text + "', '" + txt_usertype.Text + "' )"
cmd.ExecuteNonQuery()
txt_employee_id.Text = ""
txt_password.Text = ""
txt_name.Text = ""
txt_address.Text = ""
txt_contact_info.Text = ""
txt_department.Text = ""
txt_position.Text = ""
txt_basic_salary.Text = ""
txt_usertype.Text = ""
disp_data()
MessageBox.Show("Data Inserted")
End If
Next

You really ought to avoid having a common connection object in the first place, so this sort of thing can't happen. Store your connection string in a common location but then create, configure, open, use and destroy your connection object where it's needed, which will be the same place you create the command object, e.g.
Using connection As New MySqlConnection(connectionString),
command As New MySqlCommand(query, connection)
connection.Open()
command.ExecuteNonQuery()
End Using
Because you just created the connection, you know that it is not open so opening it will not be an issue. It gets closed implicitly at the end of the Using block.
That said, if you really want to use a common connection then you can. If you're being told to open it and that it was already open then obviously you're not closing it again after using it. Open, use, close. Simple:
con.Open()
cmd.ExecuteNonQuery()
con.Close()
If you do that every time you execute a command over the connection then it will work as expected. Don't open the connection anywhere that you're not using it and always close it afterwards.
Note that you don't need to open or close if you are calling Fill or Update on a data adapter, as it will do so implicitly. That said, if you are calling more than one method that will use the connection, e.g. ExecuteNonQuery multiple times or Fill or Update on multiple data adapters, you should call Open once at the start and Close once at the end. If you don't do that with data adapters then the connection will be implicitly closed and reopened between calls and that is inefficient.

can't open same connection object multiple time, for reopen you need to close it.
So just write below line above each execute command (cmd.ExecuteNonQuery()).
It will check connection is open or not if closed then open it
If con.State = ConnectionState.Closed Then con.Open()

Related

HOW TO USE UPDATE IN SQL WITH VB

Can you please help me, what the problem of my code:
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
'UPDATE Data
openCon()
Try
cmd.Connection = con
cmd.CommandText = "UPDATE emp_table SET FNAME = '" & TextBox1.Text & "', LNAME= '" & TextBox2.Text & "', AGE = '" & TextBox3.Text & "', GENDER ='" & Gender & "', OFFICE STAFF= '" & ComboBox1.Text & "' Where ID ='" & TxtID.Text & "' "
cmd.ExecuteNonQuery()
con.Close()
MsgBox("Suceessfully Updated Record")
TxtID.Clear()
TextBox1.Clear()
TextBox2.Clear()
TextBox3.Clear()
RBMale.Checked = False
RBFemale.Checked = False
ComboBox1.Text = ""
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
There are many problems in your code and if you look around this site I think you will find many partial answers that step by step will help you solve your problems. So I try to give you an answer where all the problems are examined, discussed and solved.
First problem: How do you handle the connection.
It seems that you have a global connection instance called con that you open with openCon. This is not a good approach and always a source of problems. You always need to check if the connection is closed properly or not. For example, in the code above you have forgot to close the connection in case of exception and this will lead to other exceptions in some code not related to this one. You keep resources on the server locked to you and this will decrease the performance of every one connection to that server.
I would change your openCon to this
Public Function openCon() as MySqlConnection
Dim con as MySqlConnection = new MySqlConnection(....here connection string ...)
con.Open()
return con
End Function
This will create a new instance of the MySqlConnection every time you call this method Now you can remove the global connection instance and use the one returned by openCon in this way
Using con As MySqlConnection = openCon()
.... code that use the local con object
End Using
This will close and destroy the connection even if an exception occurs inside the Using block and the ADO.NET libraries are smart enough to use a thing called Connection Pooling to reduce the time required to build and open a connection with the same connection string.
Second problem: The syntax error.
Looking at the point of the error suggested by the message I can see a field name composed by two words separated by a space. This is fine, but then you should remember that the sql parser cannot understand this and you need to help it enclosing the two words in a backtick character (ALT+096) so the parser understand that this is a single field name. Given the fact column names are an internal information of no concern for your end user then why use spaces in column names? If possible remove the space in column names.
Third problem: Sql Injection and other syntax errors
You are concatenating strings to build an sql command. But this is an easy target for wannabe hackers. Suppose that I write in your textBox1 this string instead of a First Name: Mario'; --
Then your command becomes
UPDATE emp_table SET FNAME = 'Mario'; -- xxxxxxxxxxxx
everything after -- is considered a comment and the query is still executable, but it changes every record in emp_table to have a first name equal to Mario.
But the query could fail as well if someone writes a Last Name that contains an apostrophe like O'Leary just now the query is no more syntactically valid.
The solution to this is always one. Use Parameters.
Recap of changes to your code.
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Dim cmdText as String = "UPDATE emp_table SET FNAME = #fname,
LNAME= #lname, AGE = #age, GENDER =#gender,
`OFFICE STAFF` = #staff
Where ID =#id"
Using con as MySqlConnection = openCon()
Using cmd as MySqlCommand = new MySqlCommand(cmdText, con)
Try
cmd.Parameters.Add("#fname", MySqlDbType.VarChar).Value = textBox1.Text
cmd.Parameters.Add("#lname", MySqlDbType.VarChar).Value = textBox2.Text
cmd.Parameters.Add("#age", MySqlDbType.VarChar).Value = textBox3.Text
cmd.Parameters.Add("#gender", MySqlDbType.VarChar).Value = gender
cmd.Parameters.Add("#staff", MySqlDbType.VarChar).Value = combobox1.Text
cmd.Parameters.Add("#id", MySqlDbType.VarChar).Value = txtID.Text
cmd.ExecuteNonQuery()
MsgBox("Suceessfully Updated Record")
TxtID.Clear()
TextBox1.Clear()
TextBox2.Clear()
TextBox3.Clear()
RBMale.Checked = False
RBFemale.Checked = False
ComboBox1.Text = ""
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Using
End Using
End Sub
In the recap I have added parameters for every single field that you want to update. But remember. Parameters should have a Type (The MySqlDbType here) that should match the type of the field and the value should be of the same type. For example it seems improbable that Age is a varchar field. So you should convert TextBox3.Text to an integer if the field is an integer.

Im trying to insert a data into database using vb

I am trying to add a new data in mySql database using vb . But the error always says [unit_type] is not allowed to be null . I even changed the column's setting in the main database . I disabled the not null checkbox .
Dim datetoday = Date.Today
Try
command = "INSERT INTO assets_table ([date_created], [unit_type]) VALUES ('" & datetoday & "' , '" & frm_viewAssets.lbl_fetch.Text & "')"
Dim cmd As MySqlCommand = New MySqlCommand(command, myconn.open())
cmd.Parameters.Add(New MySqlParameter("date_created", CType(datetoday, String)))
cmd.Parameters.Add(New MySqlParameter("unit_type", CType(frm_viewAssets.lbl_fetch.Text, String)))
Try
cmd.ExecuteNonQuery()
cmd.Dispose()
myconn.close()
Catch ex As Exception
myconn.close()
End Try
You did the right thing by trying to use parameters but you did it wrong. You added the parameters to the command but, instead of using parameter place-holders in your SQL, you still inserted the literal values. This:
command = "INSERT INTO assets_table ([date_created], [unit_type]) VALUES ('" & datetoday & "' , '" & frm_viewAssets.lbl_fetch.Text & "')"
should be this:
command = "INSERT INTO assets_table ([date_created], [unit_type]) VALUES (#date_created, #unit_type)"
and then I think that you will need to add the "#" prefix to the parameter names when you create them as well.
Keep the database objects local so you can be sure they are closed and disposed. Using...End Using blocks will handle that for you even if there is an error.
Don't open the connection until directly before the .Execute.
I assumed the type of date_created to be a Date.
It can improve the efficiency of your sql to include the datatypes of your parameters.
If all you are doing in your Try/Catch is closing the connection you are just swallowing errors.
Private Sub OPCode()
Dim datetoday = Date.Today
Dim Command = "INSERT INTO assets_table ([date_created], [unit_type]) VALUES (#date_created , #unit_type);"
Using myconn As New MySqlConnection("Your connection string"),
cmd As New MySqlCommand(Command, myconn)
cmd.Parameters.Add("#date_created", MySqlDbType.Date).Value = datetoday
cmd.Parameters.Add("#unit_type", MySqlDbType.VarChar).Value = frm_viewAssets.lbl_fetch.Text
myconn.Open()
cmd.ExecuteNonQuery()
End Using
End Sub

Why this statement cannot be updated in the database

I am facing this issue with my query. I would like you to kindly help me resolve it.
MD = "UPDATE librarysystem.audit set timeout = '" & Today + "" + TimeOfDay & "' AND status='0' WHERE username = '" & AccountId & "'AND status = '1'"
cmd = New MySqlCommand(MD, con)
cmd.ExecuteNonQuery()
here's the code:
connect()
Dim result As Integer = MessageBox.Show("Are You Sure You Want To LOGOUT?", "Are You?", MessageBoxButtons.YesNo)
If result = DialogResult.No Then
Me.Show()
ElseIf result = DialogResult.Yes Then
connect()
Dim time As DateTime
time = Date.Today
Dim a As Integer = 0
MD = "UPDATE librarysystem.audit set timeout = '" & Today + "" + TimeOfDay & "' AND status='0' WHERE username = '" & AccountId & "'AND status = '1'"
cmd = New MySqlCommand(MD, con)
cmd.ExecuteNonQuery()
AccountSettings.Hide()
BorrowedBooks.Hide()
LogHistory.Hide()
Login.Hide()
ReturnedBooks.Hide()
SearchBooks.Hide()
End If
End Sub
:
Thank you in advance ^^
One of the deep hassles of SQL is that you're usually embedding one language in another. That makes it hard to read things in both languages clearly. Here's your SQL extracted from your vb.
UPDATE librarysystem.audit
set timeout = '" & Today + "" + TimeOfDay & "'
AND status='0'
WHERE username = '" & AccountId & "'AND status = '1'"
Here it is with some sample values substituted
UPDATE librarysystem.audit
set timeout = '2016-11-26 13:14:15'
AND status='0'
WHERE username = 'SomeUserName'AND status = '1'
You should be able to carry out that statement directly on your dbms and have it function correctly. But, look it over. What do you see?
I see an AND where there should be a , in the list of columns to update. AND only works in WHERE and ON clauses, not in lists of columns.
I see a missing space in the SQL in the sequence 'SomeUserName'AND.
I also see some potential confusion in the way your vb program created the value for timeout. It's not immediately clear whether your vb TimeOfDay variable will render in 24h format (13:14:15) or in am/pm format (01:14:15 PM).
Finally, I see an extraordinarily common mistake. The SQL statement is jammed onto one line, as if it had been written in the 1980s by a psychotic APL programmer. This makes your language-in-a-language program almost impossible to read.

Insert data to MySql and display in datagridveiw

Recently i developed a pos but i have an problem inserting the data and displaying the names of the table in datagrid view
here is some code :
Dim Query As String
Query = "insert into baza.artikli(barkod,naziv,kupovna,prodazna,kolicina,proizvoditel,opis) values ('" & TextBoxBarkod.Text & "','" & TextBoxNaziv.Text & "','" & kupovnacena & "','" & prodaznacena & "','" & kolicina & "','" & TextBoxProizvoditel.Text & "','" & TextBoxOpis.Text & "')"
COMMAND = New MySqlCommand(Query, konekcija)
READER = COMMAND.ExecuteReader
MessageBox.Show("Артиклот е успешно внесен !")
TextBoxBarkod.Text = ""
TextBoxKupovna.Text = ""
TextBoxNaziv.Text = ""
TextBoxOpis.Text = ""
TextBoxProdazna.Text = ""
TextBoxProizvoditel.Text = ""
TextBoxKolicina.Text = ""
konekcija.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
konekcija.Dispose()
And i tried:
Private Sub prikazitabela()
konecija = New MySqlConnection
konecija.ConnectionString =
"server=localhost;userid=root;password=root;database=bazaartikli123"
Dim SDA As New MySqlDataAdapter
Dim bazaDataSet As New DataTable
Dim bajndsors As New BindingSource
Try
konecija.Open()
Dim Query As String
Query = "select barkod as 'Баркод',naziv as 'Назив на артикал',kupovna as 'Куповна цена',prodazna as 'Продажна цена',opis as'Опис',ddv as 'ДДВ',makproizvod as 'Македонски прозивод' from bazaartikli123.artikli"
COMMAND = New MySqlCommand(Query, konecija)
SDA.SelectCommand = COMMAND
SDA.Fill(bazaDataSet)
bajndsors.DataSource = bazaDataSet
DataGridView1.DataSource = bajndsors
SDA.Update(bazaDataSet)
konecija.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
konecija.Dispose()
End Try
End Sub`
There are several things that can be improved, starting with using SQL parameters and executing your query:
Dim Query As String = <sql>
insert into baza.artikli
(barkod,naziv,kupovna,prodazna,kolicina,proizvoditel,opis)
values (#p1,#p2,#p3,#p4,#p5,#p6,#p7 )
</sql>.Value
Using dbcon As New MySqlConnection(MySQLConnStr)
Using cmd As New MySqlCommand(Query, dbcon)
' I dont really know what datatype these really are
cmd.Parameters.Add("#p1", MySqlDbType.VarChar).Value = TextBoxBarkod.Text
cmd.Parameters.Add("#p2", MySqlDbType.DateTime).Value = DTPNaziv.Value
cmd.Parameters.Add("#p3", MySqlDbType.Int32).Value = Convert.ToInt32(Textkupovna.Text)
' ...
dbcon.Open()
' this was missing:
cmd.ExecuteNonQuery()
End Using
dt = New DataTable
Using cmd As New OleDbCommand("SELECT * FROM baza.artikli")
dt.Load(cmd.ExecuteReader())
dgv2.DataSource = dt
End Using
End Using
I used an XML literal for the SQL mainly to avoid scrolling here, but it can make your code much more readable
There is little context for the code in the question, but connections ought be created as needed; DBCommand objects are highly query specific, so they too ought be created as needed rather than using global ones.
Use Using blocks to assure that DbConnections and other objects with a Dispose() method are properly disposed. The code closes, but does not Dispose of the connection.
Use SQL Parameters always. These assure the correct data type is passed, avoid the cruft of " Foo -'" & foovar & "' AND ..." in code, protect against special characters in strings as well as prevent SQL injection attacks.
Then cmd.ExecuteNonQuery() performs the insert.
After that, you can run a new query to get whatever data you want to display. Note that you do not need to create a DataAdapter to fill a table. It is not clear what you want to display, so that will also have to be modified for what you want.
When AutoGenerateColumns is True, they will be created when you set the datasource and the column names (== 'names of the table' ?) will automatically show. If you want different text to display for the headers, you can either set them manually or uses aliases for them in your SQL, as shown on a previous answer

Open DataReader associated with this Connection which must be closed first

I am trying to make a POS (Point of Sales) Application and I got this error. "There is already an open DataReader associated with this Connection which must be closed first."
Below are my codes:
Database using MySQL
If txt_notr.Text = "" Or txt_kodep.Text = "" Or txt_item.Text = "" Or txt_gt.Text = "" Or txt_bayar.Text = "" Then
MsgBox("Data belum lengkap...!!!")
Exit Sub
Else
'Simpan ke tabel penjualan
db.Close()
db.Open()
Call Koneksi()
Dim simpan1 As String = "Insert Into tb_penjualan values('" & txt_notr.Text & "','" & Format(Now, "yyyy-MM-dd") & "','" & txt_kodep.Text & "','" & txt_item.Text & "','" & txt_gt.Text & "','" & txt_bayar.Text & "')"
cmd = New MySqlCommand(simpan1, db)
cmd.ExecuteNonQuery()
db.Close()
db.Open()
'Simpan ke tabel detail penjualan
For baris As Integer = 0 To DGV.Rows.Count - 2
Dim simpandet As String = "Insert into tb_detjual values('" & txt_notr.Text & "','" & DGV.Rows(baris).Cells(0).Value & "','" & DGV.Rows(baris).Cells(3).Value & "','" & DGV.Rows(baris).Cells(4).Value & "','" & DGV.Rows(baris).Cells(5).Value & "')"
cmd = New MySqlCommand(simpandet, db)
cmd.ExecuteNonQuery()
db.Close()
db.Open()
cmd = New MySqlCommand("Select * from tb_stok where id_obat = '" & DGV.Rows(baris).Cells(0).Value & "'", db)
dr = cmd.ExecuteReader
dr.Read()
If dr.HasRows Then
Dim kurangstok As String = "Update tb_stok set stok = '" & dr.Item("stok") - DGV.Rows(baris).Cells(4).Value & "' where id_obat = '" & DGV.Rows(baris).Cells(0).Value & "'"
cmd = New MySqlCommand(kurangstok, db)
cmd.ExecuteNonQuery() 'The Error shows here...
End If
Next
Call hapustemp()
Call bersih()
Call notrans()
End If
db.Close()
It's counter-intuitive, but ADO.Net providers use a feature called Connection Pooling, such that you really are better off creating a new connection object in most cases for individual calls to a database, rather than trying to keep a single database connection in your class to re-use. The code below shows the correct way to re-use the connection object: create a new connection for the method, and use it for the duration of the method. But then let the connection be collected when the method completes.
I noticed that you also have some seriously insecure code. Before doing any more work with databases, you should read up on Sql Injection. This is a HUGE issue. You should not be writing database code professionally if you don't know about it, and the correct way to avoid the problem.
Finally, the code uses some conventions that originated with older VBScript/VB6 and are no longer appropriate.
The code below solves all of those issues, and should be much faster by avoiding the need to run a SELECT from the database for each gridview row:
If String.IsNullOrWhiteSpace(txt_notr.Text) OrElse String.IsNullOrWhiteSpace(txt_kodep.Text) OrElse String.IsNullOrWhiteSpace(txt_item.Text) OrElse String.IsNullOrWhiteSpace(txt_gt.Text) OrElse String.IsNullOrWhiteSpace(txt_bayar.Text_ Then
MsgBox("Data belum lengkap...!!!")
Exit Sub
End If
'No need for an "Else". The "Exit Sub" takes care of it.
'Simpan ke tabel penjualan
'Note that I was able to let the database set the time stamp
Dim sql As String = "Insert Into tb_penjualan values(#notr, current_timestamp, #kodep, #item, #gt, #bayar);"
'The "Using" keyword will guarantee the connection closes, even if an exception is thrown
Using cn As New MySqlConnection(" connection string here "), _
cmd As New MySqlCommand(sql, cn)
'Use parameter placeholders rather than string concatenation. This avoids a SERIOUS security issue.
' I have to guess parameter types/lengths, but you should use actual types/lengths that match your database
cmd.Parameters.Add("#notr", MySqlDbType.Int32).Value = CInt(txt_notr.Text)
cmd.Parameters.Add("#kodep", MySqlDbType.VarChar, 20).Value = txt_kodep.Text
cmd.Parameters.Add("#item", MySqlDbType.VarString, 1000).Value = txt_item.Text
cmd.Parameters.Add("#gt", MySqlDbType.VarChar, 50).Value = txt_gt.Text
cmd.Parameters.Add("#bayar", MySqlDbType.VarChar, 50).Value = txt_bayar.Text
cn.Open()
cmd.ExecuteNonQuery()
'Two sql statements in a single call to the database.
'This is MUCH better than the Insert/Select/Update process you were using
sql = "INSERT INTO tb_detjual VALUES (#notr, #c0, #c3, #c4, #c5);" & _
"UPDATE tb_stok SET stok = stok - #c4 WHERE id_obat = #c0;"
'See how I was able to re-use the same parameters in the query.
cmd.Parameters.Clear()
cmd.CommandText = sql
cmd.Parameters.Add("#notr", MySqlDbType.Int32).Value = CInt(txt_notr.Text)
cmd.Parameters.Add("#c0", MySqlDbType.VarChar, 50)
cmd.Parameters.Add("#c3", MySqlDbType.VarChar, 50)
cmd.Parameters.Add("#c4", MySqlDbType.VarChar, 50)
cmd.Parameters.Add("#c5", MySqlDbType.VarChar, 50)
'Simpan ke tabel detail penjualan
For baris As Integer = 0 To DGV.Rows.Count - 2
'I'm able to re-use the same parameters for each loop
cmd.Parameters("#c0").Value = DGV.Rows(baris).Cells(0).Value
cmd.Parameters("#c3").Value = DGV.Rows(baris).Cells(3).Value
cmd.Parameters("#c4").Value = DGV.Rows(baris).Cells(4).Value
cmd.Parameters("#c5").Value = DGV.Rows(baris).Cells(5).Value
cmd.ExecuteNonQuery()
Next
End Using
hapustemp()
bersih()
notrans()