How to use MySqlHelper.UpdateDataSet - mysql

I've searched around the web looking for samples on how to use MySqlHelper.UpdateDataSet but all I've found is:
Public Shared Sub UpdateDataSet( _
ByVal connectionString As String, _
ByVal commandText As String, _
ByVal ds As DataSet, _
ByVal tablename As String _
)
I'll be grateful if someone will give me:
an example of commandText because I didn't understand what kind of command I need to give;
an explanation of tablename because I need to know if is the name of a table of the DB or of the DataSet or both (with the same name);
a vb.net code example (to start testing).
I tryed to use the command this way:
Private Sub Btn_Mod_Dataset_Click(sender As Object, e As EventArgs) Handles Btn_Mod_Dataset.Click
Dim SqlStr$ = "SELECT * FROM MyTest.Users"
Using DS_Test As DataSet = DB_Functions.mQuery(SqlStr)
With DS_Test
.Tables(0).TableName = "Users"
Dim User$ = .Tables(0).Rows(0)("UserName").ToString
MsgBox(User)
.Tables(0).Rows(0)("User") = "Upd_Test"
User = .Tables(0).Rows(0)("UserName").ToString
MsgBox(User)
End With
Dim DB_Name = "MyTest"
Dim connectionString$ = "datasource=localhost;username=" + UserDB _
+ ";password=" + Password + ";database=" + DB_Name
MySqlHelper.UpdateDataSet(connectionString, _
"Update MyTest.Users Set UserName = 'Test_Ok' WHERE UserName = 'Steve'", _
DS_Test, "Users")
End Using
End Sub
This gives me
System.NullReferenceException' in System.Data.dll
EDIT (to explain my code):
a) DB_Functions is a sepate class where I've stored some function to use on a MySql DataBase. mQuery is a function who extract query result into a dataset;
b) 'User' is a field Name : I've changed it to 'UserName' but same result;
d) The code between With and End With is just a test to see what happens;
NOTE that the code gives error but my DB is updated as in the commandText String. I don't understand what happens

This might get you part of the way.
First get rid of DB_Functions. MySQLHelper has a method to create the DataSet for you; in general, db Ops are so query-specific that there is very little that is generic and reusable. The exception to this is building the ConnectionString: MySQL has gobs of cool options you can enable/disable via the connection string. But for that you just need the standard MySqlConnectionStringBuilder.
Build a DataSet:
' form/class level vars
Private dsSample As DataSet
Private MySqlConnStr As String = "..."
...
Dim SQL = "SELECT Id, FirstName, Middle, LastName FROM Employee"
Using dbcon As New MySqlConnection(MySQLConnStr)
dsSample = MySqlHelper.ExecuteDataset(dbcon, SQL)
dsSample.Tables(0).TableName = "Emps"
End Using
There does not appear to be a way to specify a tablename when you build it, so that is a separate step.
Update a Record
To update a single row, you want ExecuteNonQuery; this will also allow you to use Parameters:
Dim uSQL = "UPDATE Employee SET Middle = #p1 WHERE Id = #p2"
Using dbcon As New MySqlConnection(MySQLConnStr)
Dim params(1) As MySqlParameter
params(0) = New MySqlParameter("#p1", MySqlDbType.String)
params(0).Value = "Q"
params(1) = New MySqlParameter("#p2", MySqlDbType.Int32)
params(1).Value = 4583
dbcon.Open()
Dim rows = MySqlHelper.ExecuteNonQuery(dbcon, uSQL, params)
End Using
Again, this is not really any simpler than using a fully configured DataAdapter, which would be simply:
dsSample.Tables("Emps").Rows(1).Item("Middle") = "X"
daSample.Update(dsSample.Tables("Emps"))
I am not exactly sure what value the UpdateDataSet method adds. I think it is the "helper" counterpart for the above, but since it doesn't provide for Parameters, I don't have much use for it. The docs for it are sketchy.
The commandtext would appear to be the SQL for a single row. Note that the DataAdapter.Update method above would add any new rows added, delete the deleted ones and update values for any row with changed values - potentially dozens or even hundreds of db Ops with one line of code.

My funtion gets string query and returns datatable. So u can set dataset.tables .
Public Function mysql(ByVal str_query As String) As DataTable
Dim adptr As New MySqlDataAdapter
Dim filltab As New DataTable
Try
Using cnn As New MySqlConnection("server=" & mysql_server & _
";user=" & mysql_user & ";password=" & mysql_password & _
";database=" & mysql_database & ";Allow User Variables=True")
Using cmd As New MySqlCommand(str_query, cnn)
cnn.Open()
adptr = New MySqlDataAdapter(cmd)
adptr.Fill(filltab)
cnn.Close()
End Using
End Using
Catch ex As Exception
'you can log mysql errors into a file here log(ex.ToString)
End Try
Return filltab
End Function

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.

Object reference not set to an instance of an object Mysql VB.net

I'm trying to join tables and load data with a specific value from a Textbox but It's giving the following error:
"An exception of type 'System.NullReferenceException' occurred in Boxing.exe but was not handled in user code
Additional information: Object reference not set to an instance of an object."
My code:
Dim Joinloin As New MySqlCommand("SELECT boxno, specie, netweight, producttype, loin FROM loins, boxing WHERE loins.code = boxing.loin AND type = '" & Label9.text & "' ORDER BY loincode", conn.getConnection)
I tried to run without the "type = '" & Label9.text & "'" and works perfectly.
Because "Type" is a reserved word in SQL, you need to change it in your SQL Database and in your Query to something like "TypeX" and try again.
Connections and Commands need to have their Dispose methods called so they can release unmanaged resources. To do this they should be declared in the method they are are used. Using...End Using blocks handle the declare, and Close/Dispose.
Don not concatenate strings to build sq statements. Always use parameters.
Your join syntax went out with the last milenium. I made wild guesse about which field belonged to which table. Is there really a field called loincode?
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim dt = GetProductData(Label9.Text)
'Do something with the data table
End Sub
Private Function GetProductData(type As String) As DataTable
Dim dt As New DataTable
Using cn As New MySqlConnection("You connection string"),
cmd As New MySqlCommand("SELECT boxing.boxno, loins.specie, boxing.netweight, loins.producttype, boxing.loin
FROM boxing
JOIN loins ON boxing.loin = loins.code Where loins.[type] = #Type
ORDER BY boxing.loincode", cn)
cmd.Parameters.AddWithValue("#Type", type)
Using reader = cmd.ExecuteReader
dt.Load(reader)
End Using
End Using
Return dt
End Function

Parameterize SQL Queries

I want parameterize some SQL Statements so my code isn't vunerable to SQL Injections any longer But i have actually no plan how to parameterize for example a where clause.
Dim accID As String = DatabaseConnecter.readField("SELECT ID FROM accounts WHERE accountname ='" & user & "' AND password='" & pw & "';")
The Problem is if you type in a given username, for example test and extend the username with. You can log in without entering the password into the Application.
Edit:
Public Function readField(ByVal sql As String) As String
Dim output As String = "ERROR"
Using cn = New MySqlConnection(connString.ToString())
Using cmd = New MySqlCommand(sql, cn)
cn.Open()
Using rd = cmd.ExecuteReader()
Try
rd.Read()
output = rd.GetString(0)
rd.Close()
Catch ex As Exception
End Try
End Using
cn.Close()
End Using
End Using
Return output
End Function
ยดยดยด
To have a parameterized query you need to create parameters and write a proper SQL text where, in place of values typed directly from your user, you have parameter placeholders.
So, for example, you sql text should be something like this
Dim sqlText = "SELECT ID FROM accounts WHERE accountname =#name AND password=#pwd"
Now you have a parameterized text, but stil we need to create the parameters that will be sent to the database engine together with your sql command.
You can create the parameter (two in this case) in this way before calling the method that executes the query
Dim p1 as MySqlParameter = new MySqlParameter("#name", MySqlDbType.VarChar)
p1.Value = user
Dim p2 as MySqlParameter = new MySqlParameter("#pwd", MySqlDbType.VarChar)
p2.Value = password
Dim pms As List(Of MySqlParameter) = new List(Of MySqlParameter)()
pms.Add(p1)
pms.Add(p2)
Now we need to pass this list to your method (and this requires changes to your method signature)
DatabaseConnecter.readField(sqlText, pms)
The method itself should change to something like
Public Function readField(ByVal sql As String, Optional pms As List(Of MySqlParameter) = Nothing) As String
Dim output As String = "ERROR"
Using cn = New MySqlConnection(connString.ToString())
Using cmd = New MySqlCommand(sql, cn)
cn.Open()
' This block adds the parameter defined by the caller to the command
' The parameters are optional so we need to check if we have really received the list or not
if pms IsNot Nothing Then
cmd.Parameters.AddRange(pms.ToArray())
End If
Using rd = cmd.ExecuteReader()
Try
rd.Read()
output = rd.GetString(0)
rd.Close()
Catch ex As Exception
End Try
End Using
' no need to close when inside a using block
' cn.Close()
End Using
End Using
Return output
End Function
The method now has an optional parameter that will contain the list of the parameters required by the query (or nothing if your query doesn't require parameters). This list is added to the command parameters collection and the query is now executed.
Final Note: Storing passwords in clear text into a database is a well known security problem. I suggest you to search about how to store passwords in a database.
Private Function GetID(User As String, pw As String) As String
Using cmd As New SqlCommand("SELECT ID FROM accounts WHERE accountname =#user AND password=#password", New SqlConnection(SQLConnString))
cmd.Parameters.AddWithValue("#user", User)
cmd.Parameters.Add("#password", SqlDbType.NVarChar)
cmd.Parameters("#password").Value = pw
Try
cmd.Connection.Open()
Return cmd.ExecuteScalar()
Catch ex As Exception
'handle error
Return Nothing
Finally
cmd.Connection.Close()
End Try
End Using
End Function
I've demostrated two methods of setting the parameters. Search for more info or comparison.

How to read a value from mysql database?

I want to be able to read a value (in this case an Group ID). All the topics and tutorials I've watched/read take the data and put it into a textbox.
I don't want to put it in a textbox in this case; I want to grab the Group ID and then say:
If Group ID = 4 then login
Here is an image of the database.
Basically, but none of the tutorials I watch or the multiple forums. None of them take a a value and say if value = 4 then login or do something else.
If text = "1" Then
MysqlConn = New MySqlConnection
MysqlConn.ConnectionString =
"server='ip of server'.; username=; password=; database="
Dim READER As MySqlDataReader
Dim member_group_id As String
Try
MysqlConn.Open()
Dim Query As String
Query = "SELECT * FROM `core_members` where name='" & TextBox2.Text & "'"
Query = "SELECT * FROM `nexus_licensekeys` where lkey_key='" & TextBox1.Text & "'"
COMMAND = New MySqlCommand(Query, MysqlConn)
READER = COMMAND.ExecuteReader
Dim count As Integer
count = 0
While READER.Read
count = count + 1
End While
Here is what I have so far. I'm kind of new implementing mysql data with visual basic and only recently started to get into it. I'm not sure what comes next or how to even start with reading the group id etc.
As I said any help from here on out would be highly appreciated of how to read the group id and say if this group id = this number then do this or that. I'm sure you get the idea.
I divided the code into UI Sub, and Data Access Function that can return data to the UI. Your Event procedure code should be rather brief and the functions should have a single purpose.
Keep your database objects local to the method. This way you can have better control. The Using...End Using blocks ensure that your database objects are closed and disposed even if there is an error.
I leave it to you to add validation code. Checking for empty TextBox or no return of records.
I hope this serves as a quick introduction to using ADO.net. The take away is:
Use Parameters
Make sure connections are closed. (Using blocks)
Private ConnString As String = "server=ip of server; username=; password=; database="
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim GroupID As String = GetGroupID(TextBox1.Text)
If GroupID = "4" Then
'your code here
End If
Dim LocalTable As DataTable = GetLicenseKeysData(TextBox1.Text)
'Get the count
Dim RowCount As Integer = LocalTable.Rows.Count
'Display the data
DataGridView1.DataSource = LocalTable
End Sub
Private Function GetGroupID(InputName As String) As String
'Are you sure member_group_id is a String? Sure looks like it should be an Integer
Dim member_group_id As String = ""
'You can pass the connection string directly to the constructor of the connection
Using MysqlConn As New MySqlConnection(ConnString)
'If you only need the value of one field Select just the field not *
'ALWAYS use parameters. See comment by #djv concerning drop table
Using cmd As New MySqlCommand("SELECT g_id FROM core_members where name= #Name")
'The parameters are interperted by the server as a value and not executable code
'so even if a malicious user entered "drop table" it would not be executed.
cmd.Parameters.Add("#Name", MySqlDbType.VarChar).Value = InputName
MysqlConn.Open()
'ExecuteScalar returns the first column of the first row of the result set
member_group_id = cmd.ExecuteScalar.ToString
End Using
End Using
Return member_group_id
End Function
Private Function GetLicenseKeysData(InputName As String) As DataTable
Dim dt As New DataTable
Using cn As New MySqlConnection(ConnString)
Using cmd As New MySqlCommand("SELECT * FROM `nexus_licensekeys` where lkey_key= #Name;", cn)
cmd.Parameters.Add("#Name", MySqlDbType.VarChar).Value = InputName
cn.Open()
dt.Load(cmd.ExecuteReader())
End Using
End Using
Return dt
End Function

MySQL Data NOT Deleting from table VB.NET

Why won't this delete the data in my MySQL database!?
Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
Dim dbCon As MySqlConnection
Dim strQuery As String = ""
Dim SQLCmd As MySqlCommand
Dim DR As MySqlDataReader
Try
dbCon = New MySqlConnection("Server=Localhost;Database=myusers;Uid=root;Pwd=Mypassword")
strQuery = "DELETE settings FROM settings WHERE user=" & Me.loginuser.Text
'* FROM settings WHERE user = "Testuser"'
SQLCmd = New MySqlCommand(strQuery, dbCon)
' OPEN THE DB AND KICKOFF THE QUERY
dbCon.Open()
DR = SQLCmd.ExecuteReader
While DR.Read
req1.Text = "" And exlink.Text = ""
End While
' DONE! Close DB
DR.Close()
dbCon.Close()
Catch ex As Exception
TextBox8.Text = ("Fail" & vbCrLf & vbCrLf & ex.Message)
End Try
Here is a picture of my database:
Alternatively I could somehow make it replace what is already in the database, in which case please help me with that.
Try
strQuery = "DELETE FROM settings " _
& " WHERE user = '" & Me.loginuser.Text & "'"
but as was stated earlier, you should be using parameterized queries. If you had a user named O'Brien then your query (as composed above) would fail because of the embedded single quote. When you use DELETE, you are deleting entire records and you already specify the table name in the FROM clause.
I will try to change your code in this way
Using con = New MySqlConnection("Server=.....")
con.Open()
Dim sqlText = "DELETE * FROM settings WHERE user = #ulogin"
Using cmd = new MySqlCommand(sqlText, con)
cmd.Parameters.AddWithValue("#ulogin", Me.loginuser.Text)
cmd.ExecuteNonQuery()
End Using
End Using
First and foremost, do not use string concatenation to create command texts to pass to the database engine. In that way you risk Sql Injections, also, if the user name contains a single quote (i.e. O'Hara) your code will fail with a syntax error (Same problems arise for date formatting, parsing numeric decimals and other globalization issues). Instead a parametrized query like the one in code above will avoid all of these problems.
In a parametrized query, the text of the query doesn't contains the actual value for the search condition or the update or insert data. Instead it contains placeholders ( in our case it is called #ulogin). The correct value to insert at the placeholders position is specified using one or more MySqlParameter added to the Parameters collection of the MySqlCommand. In this case I have used the AddWithValue method that derives the correct datatype directly from the datatype of the value. Because Me.loginuser.Text is a string value then the parameter will be treated as a string value replacing incorrect single quotes and removing extraneus characters usually used to Mount Sql Injections Attacks. The engine will do the rest inserting the correct value at the placeholder at execution time
EDIT: Seeing your comment about the MySql connector used, I will try to update my answer to show a semi-equivalent version for NET 1.
Try
Dim con As MySqlConnection = New MySqlConnection("Server=.....")
con.Open()
Dim sqlText as String = "DELETE * FROM settings WHERE user = #ulogin"
Dim cmd As MySqlCommand = new MySqlCommand(sqlText, con)
Dim par As MySqlParameter = New MySqlParameter("#ulogin", MySqlDbType.VarChar)
par.Value = Me.loginuser.Text
cmd.Parameters.Add(par)
cmd.ExecuteNonQuery()
Finally
con.Close()
End Try
I am not sure if the connector 1.0.10 supports the parameter name with the # prefix or just the : prefix
i dont think you can use double quotes in mysql, i think its single quotes only. try
Query = "DELETE * FROM settings WHERE user = '" & Me.loginuser.Text & "'"