Sie sind auf Seite 1von 85

installed MySQL in your PC.

1.First thing to do is to insure that you have

2. Do download MySQL Connector Net 5.1.7, just


look over the internet. It is for free to use.
3. On your project references, Browse and Add
the MySQL.Data(if MySQL Connector Net 5.1.7
is installed, the MySQL.Data is located at
C:/Program Files/MySQL/MySQL Connector 5.1.7/Binaries/.Net2.0/
4. Add 5 textbox and 5 label and Name it as:

Label.Text

Textbox.Name

Server

txtServer

Port

txtPort

Username

txtMySqlUser

Password

txtMySqlPW

Database

txtDB

As appears on the screen shot design


5. On Form1 code Add the following
Imports MySql.Data.MySqlClient
Public Class Form1
Public SwsmsDBConn As New MySqlConnection

Private Sub cmdConnect_Click(ByVal sender As System.Object, ByVal e As


System.EventArgs) Handles cmdConnect.Click
If ConnectToSWSMSDB() = True Then
MsgBox("Connected")
Else
MsgBox("Not Connected")
end If
End Sub
Function ConnectToSWSMSDB() As Boolean
Try
If SwsmsDBConn.State = ConnectionState.Closed
Then
SwsmsDBConn.ConnectionString = "SERVER=" &
txtServer.Text & "; PORT=" & txtPort.Text _
& "; User Id=" & txtMySqlUser.Text & ";
Password=" & txtMySqlPW.Text & "; Database=" & txtdb.text & ";"
SwsmsDBConn.Open()
Return True
End If
Catch ex As MySqlException
MsgBox(ex.Message, MsgBoxStyle.Information)
Return False
End Try
End Function
End Class
6. If the connection is successful, you can do
the following to fetch data on MySQL
Dim cmd As New MySqlCommand
Dim adptr As New MySqlDataAdapter

Dim table As New DataTable


cmd.Connection = Conn
cmd.CommandText='MySqlCommand Strings here
adptr.SelectCommand = cmd
adptr.Fill(table)
'then all your data is in now the table so
you can access it anytime
Actually the number 6 is excluded in the
coverage for this article cause this article covers only on how to connect
VB.NET to MySQL.
Maybe on my Next Post i will cover how to fetch and display data from MySQL.
God Bless Readers!
Please leave a comment after wards,

Private Sub Search()


lviClientList.Items.Clear()
Dim strSqlSearch As String = "SELECT code, Company, StAdd, City,
ContactPerson, Phone, Mobile, Email, Remarks FROM tblclients WHERE '@Column'
LIKE '%" & txtSearchCriteria.Text & "%'"
Dim item As New ListViewItem()
If cboColumns.SelectedIndex = 0 Then
column = "code"
ElseIf cboColumns.SelectedIndex = 1 Then
column = "Company"
ElseIf cboColumns.SelectedIndex = 2 Then
column = "StAdd"

ElseIf cboColumns.SelectedIndex
column = "City"
ElseIf cboColumns.SelectedIndex
column = "ContactPerson"
ElseIf cboColumns.SelectedIndex
column = "Phone"
ElseIf cboColumns.SelectedIndex
column = "Mobile"
ElseIf cboColumns.SelectedIndex
column = "Email"
ElseIf cboColumns.SelectedIndex
column = "Remarks"
End If

= 3 Then
= 4 Then
= 5 Then
= 6 Then
= 7 Then
= 8 Then

Dim mysqlCommand As New MySqlCommand(strSqlSearch, mysqlConnection)


mysqlCommand.Parameters.AddWithValue("@Column", column)
Try
mysqlConnection.Open()
mysqlReader = mysqlCommand.ExecuteReader()
Do While mysqlReader.Read()
item = lviClientList.Items.Add(mysqlReader("code").ToString)
item.SubItems.Add(mysqlReader("Company").ToString)
item.SubItems.Add(mysqlReader("StAdd").ToString)
item.SubItems.Add(mysqlReader("City").ToString)
item.SubItems.Add(mysqlReader("ContactPerson").ToString)
item.SubItems.Add(mysqlReader("Phone").ToString)
item.SubItems.Add(mysqlReader("Mobile").ToString)
item.SubItems.Add(mysqlReader("Email").ToString)
item.SubItems.Add(mysqlReader("Remarks").ToString)
Loop
Catch ex As Exception
MsgBox("No results found.", MsgBoxStyle.OkOnly, "Project Analysis
System")
Finally
mysqlReader.Close()
mysqlConnection.Close()
End Try
End Sub

It is not clear why your code doesn't work well. Try to change the code in your Catch clause
MsgBox("No results found.", MsgBoxStyle.OkOnly, "Project Analysis System")

into

Msgbox(ex.Message.ToString(), MsgBoxStyle.OkOnly, "Project Analysis System")

so you will know what the exact error is.


You can concatenate the value for the ColumnName since it is statically set in your code. But the
value on WHERE should be parameterized as it is the one entered by the user.
Try this modified Code,
Private Sub Search()
lviClientList.Items.Clear()
Dim item As New ListViewItem()
Dim _isFound As Boolean = False
Dim colName() As String = {"code", "Company", "StAdd", "City",
"ContactPerson", "Phone", "Mobile", "Email", "Remarks"}
Dim strSqlSearch As String = "SELECT code, Company, StAdd, City, " & _
"ContactPerson, Phone, Mobile, Email,
Remarks " & _
"FROM tblclients " & _
"WHERE " &
colName(cboColumns.SelectedIndex) & " LIKE CONCAT('%', @valueName, '%')"
Using myConn As New MySqlConnection("connectionStringHere")
Using myComm As New MySqlCommand()
With myComm
.Connection = myConn
.CommandType = CommandType.Text
.CommandText = strSqlSearch
.Parameters.AddWithValue("@valueName",
txtSearchCriteria.Text);
End With
Try
myConn.Open()
Dim myReader As MySqlDataReader = myComm.ExecuteReader()
While myReader.Read()
_isFound = True
item = lviClientList.Items.Add(myReader("code").ToString)
item.SubItems.Add(myReader("Company").ToString)
item.SubItems.Add(myReader("StAdd").ToString)
item.SubItems.Add(myReader("City").ToString)
item.SubItems.Add(myReader("ContactPerson").ToString)
item.SubItems.Add(myReader("Phone").ToString)
item.SubItems.Add(myReader("Mobile").ToString)
item.SubItems.Add(myReader("Email").ToString)
item.SubItems.Add(myReader("Remarks").ToString)
End While
If Not _isFound Then
MsgBox("No results found.", MsgBoxStyle.OkOnly, "Project
Analysis System")
End If

Catch ex As MySqlException
Msgbox(ex.Message.ToString(), MsgBoxStyle.OkOnly, "Project
Analysis System")
End Try
End Using
End Using
End Sub

Using ADO.NET
60 out of 74 rated this helpful - Rate this topic
Paul D. Sheriff
PDSA, Inc.
January 2002
Summary: Discusses using ADO.NET Connection object, other ADO.NET objects, and
provides examples. (41 printed pages)

Objectives

Learn to create a Microsoft ADO.NET Connection object

Submit SQL through an ADO.NET Command object

Use the ADO.NET DataReader class

Learn to load objects into a list box

Use DataTable objects and DataSet objects

Modify data using DataSet objects

Assumptions
The following should be true for you to get the most out of this document:

You understand relational databases

You are familiar with ADO

You understand how to build Microsoft Windows Forms

You are familiar with and have access to Microsoft SQL Server or some other
database, like Microsoft Access

Contents
ADO.NET Connection
The ADO.NET Command Object
Using the ADO.NET DataReader
Using ADO.NET DataTables and DataSets
What's Different Between Visual Basic 6.0 and ADO?
Summary

ADO.NET Connection
You use the ADO.NET Connection object to create a connection between your program and a
database engine. You will normally keep this connection open just long enough to retrieve or
update data. By quickly opening, then closing a connection, you use server resources for as little
time as possible. This helps you develop scalable, fast applications that are resource-friendly. The
fewer resources you use, the more users you can support on your applications at one time.

If you are creating a database application, you will eventually need to open a connection to that
database. An ADO.NET Connection object allows you to create that connection. You will also
need to retrieve and modify data in the database, and that is where you will need to use the
ADO.NET Command object.
When connecting to SQL Server 7.0 or greater, you use the SqlConnection and SqlCommand
objects in the System.Data.SqlClient namespace. When connecting to other OLE DB
datasources, use the OleDbConnection and OleDbCommand in the System.Data.OleDb
namespace. The rest of the examples in this document show examples using the objects from the
System.Data.SqlClient namespace.
To modify data within a database
1. Create a SqlConnection or an OleDbConnection object and give it a connection string.
2. Open the connection to the database.
3. Create a SqlCommand or an OleDbCommand object and assign to it the connection
object you opened.
4. Place an SQL statement into the Command object.
5. Execute the SQL statement by invoking the ExecuteNonQuery method on the Command
object.

Connection and Command Objects


In this document, you will learn to create and open a connection to a SQL Server database using
a SqlConnection class. In addition, you will learn to submit an INSERT statement to the same
SQL Server database using the SqlCommand object.
Follow the steps below to learn how to open a connection to a SQL Server database. Figure 1
shows the sample form that you will use to test your connections. Create this form by following
the steps outlined below.

Figure 1: Submitting SQL statements to a SQL Server database


To create the sample form
1. Open Microsoft Visual Studio .NET.
2. Click New Project.
3. From the tree view on the left, select Visual Basic Projects.
4. From the project templates window, select Windows Application.
5. Set the Name to DataConnect.
6. Click OK.
7. Rename the form called Form1.vb to frmConnect.vb.
8. Set the Text property on this form to SQL Tester.
9. Create the controls for this form by referring to Table 1.
Table 1. Controls to build the form to test the ADO.NET objects

CommandButton
TextBox

Label
TextBox

CommandButton

Now let's write some code to make a connection to the database.


1. Double-click Connect.
2. Add the code shown below to the btnConnect_Click event procedure.
3. Private Sub btnConnect_Click( _
4. ByVal sender As System.Object, _
5. ByVal e As System.EventArgs) Handles btnConnect.Click
6.
Dim oConn As SqlClient.SqlConnection
7.
Dim strConn As String
8.
9.
Try
10.
' Create the Connection object
11.
oConn = New SqlClient.SqlConnection()
12.
13.
' Build the connection string
14.
strConn &= "Data Source=(local);"
15.
strConn &= "Initial Catalog=Northwind;"
16.
strConn &= "User ID=sa;"
17.
strConn &= "Password=;"
18.
19.
' Set the Connection String
20.
oConn.ConnectionString = strConn
21.
22.
' Open the Connection
23.
oConn.Open()
24.
25.
MessageBox.Show("Connection Open", _
26.
"btnConnect_Click()")
27.
28.
' Close the Connection
29.
oConn.Close()
30.
31.
Catch oExcept As Exception
32.
MessageBox.Show(oExcept.Message, _
33.
"btnConnect_Click()")
34.
35.
End Try
36.
37. End Sub

In this event procedure, you first create a new instance of a SqlConnection class. Then you fill in
the ConnectionString property prior to opening the connection.
In previous versions of ADO, you were allowed to set the ConnectionTimeout property to a
value from 0 to n. This represented the time to wait for a connection to be made before an
exception was thrown. In ADO.NET, this property is read-only. To set the ConnectionTimeout,
pass Connect Timeout=n in the provider string. In addition, you no longer set the individual
properties such as DataSource, Database, etc., as properties on the SqlConnection object. These
values are now read-only, and reflect the values that are parsed from the provider string.

Connection Strings
You next create a connection string that points to a SQL Server database. A connection string has
a set of semi-colon-separated attributes. Each .Net Data Provider connection string looks
different, depending on the type of .NET Data Provider you need to use and which attributes are
set for each different type of database system. For example, the connection string below is an
example of what you use to connect to a local SQL Server.
Data Source=(local);Initial Catalog=Northwind;User ID=sa;Password=;

The connection string shown below is an example of how you would connect to a Microsoft
Access 2000 database using the OleDbConnection object in System.Data.OleDb.
Provider=Microsoft.Jet.OleDb.4.0;Data Source=C:\Northwind.mdb

Note If you are using a different database engine, you will need to look up the appropriate
attributes to set for your particular engine. Consult the ADO.NET Help for more information on
setting the connection string for different providers.
Create this connection string in the string variable strConn, and then assign that variable to the
ConnectionString property of the Connection object.
After the ConnectionString property is set, invoke the Open method on the Connection object.
This causes the connection object to load the specified provider and open a connection to the
data source. If supplied, the User ID and Password attributes are used to log into the data source.
The Initial Catalog attribute tells the connection to make the default database the one specified in
this attribute.
After you are finished with the connection, you should always close it. In the example code you
just typed in, you simply open a connection and close it right away. Typically, you would
perform some operation on the connection prior to closing it. This will be shown in the next
section.
Try It Out
1. To run the project, press F5.

2. Click Connect to run the code you just typed in. If everything is set correctly, you should
see a message box informing you that the connection was opened.
Now that you know how to open a connection, you probably want to do something with it.
Unlike previous versions of ADO, ADO.NET does not allow execution of SQL statements
directly on a connection object. To submit SQL statements, you always use a Command object.

The ADO.NET Command Object


The Command object is very similar to the old ADO command object. It is used to store SQL
statements that need to be executed against a data source. The Command object can execute
SELECT statements, INSERT, UPDATE, or DELETE statements, stored procedures, or any
other statement understood by the database. In Figure 1 you saw an example of an INSERT
statement that you could execute against the Northwind database to add a row to the Customers
table. You will now learn to write the code that will execute that INSERT statement.
1. Open the frmConnect.vb form.
2. Double-click Execute SQL.
3. Write the code shown below in the btnExecute_Click event procedure.
4. Private Sub btnExecute_Click(ByVal sender As Object, _
5. ByVal e As System.EventArgs) Handles btnExecute.Click
6.
Dim oCmd As SqlClient.SqlCommand
7.
Dim strConn As String
8.
9.
Try
10.
' Build the connection string
11.
strConn &= "Data Source=(local);"
12.
strConn &= "Initial Catalog=Northwind;"
13.
strConn &= "User ID=sa;"
14.
strConn &= "Password=;"
15.
16.
' Create the Command Object
17.
oCmd = New SqlClient.SqlCommand()
18.
' Assign Connection to Command Object
19.
oCmd.Connection = _
20.
New SqlClient.SqlConnection(strConn)
21.
' Open the Connection
22.
oCmd.Connection.Open()
23.
' Assign the SQL to the Command Object
24.
oCmd.CommandText = txtSQL.Text
25.
' Execute the SQL,
26.
' Return Number of Records Affected
27.
txtRows.Text = _
28.
oCmd.ExecuteNonQuery().ToString()
29.
30.
MessageBox.Show("SQL statement succeeded", _
31.
"btnExecute_Click()")
32.

33.
' Close the Connection
34.
oCmd.Connection.Close()
35.
36.
Catch oExcept As Exception
37.
txtRows.Text = 0.ToString()
38.
MessageBox.Show("Error executing SQL: " & _
39.
oExcept.Message, "btnExecute_Click()")
40.
41.
End Try
42. End Sub

In the btnExecute_Click event procedure, you need to declare a variable named oCmd that
references a Command object. You then create a connection string used to create a connection to
the data source. Next, you instantiate the Command object and set its Connection property to a
New Connection object. Once you have created this new Connection object, you can open the
connection.
After the connection is open, you can fill in the CommandText property with the SQL statement
you wish to submit to the database. In this case, the SQL statement comes from the Text Box on
the form.
You invoke the ExecuteNonQuery method of the command object to submit the SQL to the
backend database. Use the ExecuteNonQuery method when executing a command that does not
return results, such as an INSERT, UPDATE or DELETE statement. These types of queries do
not return any rows as a result set, they simply modify data and return the number of rows
affected. This method returns the number of rows affected by the SQL statement submitted. You
convert this value to a string so it can be placed into the Text property of the txtRows text box.
Finally, you close the connection using the Close method on the Connection property.
Note Unlike in ADO, where you could wait until the Connection object went out of scope for
the connection to be closed, in ADO.NET you should always explicitly close the connection as
shown in this procedure. Calling Close() on the Connection will release the database connection
back to the pool for some other procedure to reuse as soon as possible.
Try it Out
You can try out this new button by writing an INSERT, UPDATE, or DELETE statement against
one of the tables in the Northwind database and submitting that to the database.
1. Run the program by pressing F5.
2. Type in a valid INSERT, UPDATE, or DELETE statement. You can use the INSERT
statement that is already placed into the text box as an example, if you like.
3. Click Execute SQL.
If everything works, you should see the number of rows affected show up in the text box that you
created to the left of the button.

Using the ADO.NET DataReader


In ADO.NET, you no longer have a Recordset. Instead, you have new objects such as DataSets,
DataTables, and DataReaders that will be used to retrieve records from data sources. Next, you
will learn about the DataReader object. You will learn about DataTables and DataSets later in this
document.
The DataReader object is a forward-only type of cursor that provides the fastest way to retrieve
records from a data source. Because its direction is limited to forward-only, it provides great
performance for programmatically processing results or loading list boxes, combo boxes, etc.

Load a List Box Using the DataReader


In this section you will load a list box with data from the Products table using the DataReader
object. In addition, you will retrieve a single record after clicking the list box. Figure 2 shows a
simple data entry screen that you might use to display, add, edit, and delete product information.

Figure 2: A typical Client/Server data entry screen


Follow the steps below to load the list box with the names of all of the products in the Products
table in the Northwind database.
1. Create a form that looks like Figure 2. Set the Name of this form to frmProducts.vb. The
name of the list box is lstProducts.

2. In Solution Explorer, double-click the frmProducts.vb file to display the products form.
3. Double-click anywhere on the form (make sure you are not clicking on a control). The
frmProduct_Load event procedure will now be displayed in the code window.
4. Within this Load event procedure, make a call to the ListLoad procedure that you are
going write in the next step. Your procedure should look something like the code shown
below.
5. Private Sub frmProduct_Load( _
6. ByVal sender As System.Object, _
7. ByVal e As System.EventArgs) Handles MyBase.Load
8.
ListLoad()
9. End Sub

10. Create the ListLoad procedure just below the End Sub of the frmProduct_Load event
procedure, and type the following code into this ListLoad procedure.
11. Private Sub ListLoad()
12.
Dim oCmd As SqlClient.SqlCommand
13.
Dim oDR As SqlClient.SqlDataReader
14.
Dim strSQL As String
15.
Dim strConn As String
16.
17.
strConn = ConnectStringBuild()
18.
19.
strSQL = "SELECT ProductName "
20.
strSQL &= "FROM Products"
21.
22.
Try
23.
oCmd = New SqlClient.SqlCommand()
24.
With oCmd
25.
.Connection = _
26.
New SqlClient.SqlConnection(strConn)
27.
.Connection.Open()
28.
.CommandText = strSQL
29.
oDR = .ExecuteReader()
30.
End With
31.
32.
lstProducts.Items.Clear()
33.
Do While oDR.Read()
34.
lstProducts.Items.Add(oDR.Item("ProductName"))
35.
Loop
36.
37.
Catch oExcept As Exception
38.
MessageBox.Show(oExcept.Message)
39.
40.
End Try
41. End Sub
42.

The code above declares two objects, one for the Command and one for the DataReader. The
Command object holds and executes the SELECT statement to send to the data source. The

DataReader is the object that retrieves the data from the result set that comes back from the
SELECT statement.
Set the Connection property on the Command object to a new instance of a Connection object.
You pass a connection string to this new Connection object; you will build your own
ConnectStringBuild function later in this section. After the proper connection string is set, you
can open the connection on the command object.
Place the SELECT statement into the CommandText property. When you invoke the
ExecuteReader method, the command object submits the SELECT statement to the back end data
source. The result is returned and the DataReader object is given a pointer to this result set. The
cursor is set just before the first record in this result set.
You will loop through each of the rows in the DataReader by invoking the Read method. The
Read method moves the cursor from one row to the next. After the Read method has executed,
you can pass the name of the column you wish to retrieve to the Item property on the
DataReader. This returns the actual data from that column.
The data returned from the Item property comes back as an Object data type. Because the items
you add to the list box are of type Object, no conversion is required when using the Add method
of the Items collection on the list box.
In this manner, you continue looping until the Read method returns a False. This means you have
hit the end of the rows of data that were returned from the SELECT statement.

Build the Connection String


Before you can try out this routine to see if the data is loaded correctly into the list box, you will
need to build the connection string.
1. Right after the End Sub of the ListLoad procedure, add a new procedure called
ConnectStringBuild.
2. Type in the code below to create this connection string. You may need to change the
connection string if you are using a different server name, or a different database engine.
3. Private Function ConnectStringBuild() As String
4.
Dim strConn As String
5.
6.
strConn &= "Data Source=(local);"
7.
strConn &= "Initial Catalog=Northwind;"
8.
strConn &= "User ID=sa"
9.
10.
Return strConn
11. End Function

12. Press F5 to run this application.

If you typed everything in correctly, you should see a list of products in the list box.

Issues With the Code


One of the problems with the above code is that you could have duplicate product names in your
table. If this is the case, there is no mechanism for you to store a primary key into this list box so
you can uniquely identify which record is which in the list. Unlike Microsoft Visual Basic 6.0,
the ListBox in .NET does not have an ItemData property. ItemData was used to store a long
integer data type that was tied to the text in the text box. .NET has eliminated the ItemData
property. However, there is a much better method to handle this type of situation: storing the
object in the ListBox itself.

Store an Object Into the ListBox


The key to making the connection string code work is to create a class with enough properties to
hold the data that you wish to place into the list box. One property of this class is used to display
the data in the text portion of the list box. The other property, or properties, will be used to hold
primary key information. For the Product table, you need one property for the ProductName
column and one property for the ProductID column. In fact, for many tables, you will just need
two properties like this.
Tip Create a generic class with two properties called Value and ID that you can re-use for
loading any list box or combo box with a description and a primary key value.

Create a Generic ListItem Class


Let's add a new file to your project. This new file contains the class definition for your generic
list item class.
1. On the Project menu, click Add Class to add a new class to your project.
2. Give it a name, such as clsListItems.vb.
3. Create a class like that shown in the code below.
4. Public Class PDSAListItemNumeric
5.
Private mstrValue As String
6.
Private mintID As Integer
7.
8.
Public Sub New()
9.
10.
End Sub
11.
12.
Public Sub New(ByVal strValue As String, _
13.
ByVal intID As Integer)
14.
mstrValue = strValue
15.
mintID = intID
16.
End Sub

17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39. End

Property Value() As String


Get
Return mstrValue
End Get
Set(ByVal Value As String)
mstrValue = Value
End Set
End Property
Property ID() As Integer
Get
Return mintID
End Get
Set(ByVal Value As Integer)
mintID = Value
End Set
End Property
Public Overrides Function ToString() As String
Return mstrValue
End Function
Class

The above class has two properties, Value and ID, which will be used to hold the text and
primary key for any table that you place into a list box. For any class that you intend to place into
the Items collection on a list control, you must override the ToString method. ToString is a
method on the default Object data type that from which all classes automatically inherit. When
the list box displays items in its Items collection, it will always call the ToString method to
retrieve the data. In the ToString method of this class, you return the Value property, as that is the
value you wish to display in the list box.

Use the New Class in ListLoad


Now that you have created this new generic class, let's use it in the ListLoad procedure. This
time, instead of adding the ProductName directly from the DataReader, add the ProductName
and ProductID to a new instance of your PDSAListItemNumeric class and add this object to the
list box.
1. Change the code in the ListLoad procedure you created earlier so it looks like the code
shown below.
2. Private Sub ListLoad()
3.
Dim oCmd As SqlClient.SqlCommand
4.
Dim oDR As SqlClient.SqlDataReader
5.
Dim oItem As PDSAListItemNumeric
6.
Dim strSQL As String
7.
Dim strConn As String
8.
9.
strConn = ConnectStringBuild()
10.
11.
strSQL = "SELECT ProductID, ProductName "

12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44. End

strSQL &= "FROM Products"


Try

oCmd = New SqlClient.SqlCommand()


With oCmd
.Connection = _
New SqlClient.SqlConnection(strConn)
.Connection.Open()
.CommandText = strSQL
oDR = _
.ExecuteReader()
End With
lstProducts.Items.Clear()
Do While oDR.Read()
oItem = New PDSAListItemNumeric()
With oDR
oItem.ID = CInt(.Item("ProductID"))
oItem.Value = _
.Item("ProductName").ToString()
End With
lstProducts.Items.Add(oItem)
Loop
If lstProducts.Items.Count > 0 Then
lstProducts.SetSelected(0, True)
End If

Catch oExcept As Exception


MessageBox.Show(oExcept.Message)
End Try
Sub

The major change you made to this routine is that you added the ProductID column to your
SELECT statement, and then added the instantiation of a new oItem object inside the Read loop.
Each time you read a new record, you create a new PDSAListItemNumeric object, store the
ProductID into the ID property and the ProductName into the Value property. You then add this
new object to your list box.
Try It Out
Now that you have changed this code to use a PDSAListItemNumeric class, run the project to
make sure you typed everything in correctly. Press F5 to see if you are still getting Products
loaded into your list box.

Displaying Product Detail Information


Once you have placed these objects into the list box, you can click an item in the list box to
retrieve that object and get the ID and Value properties. When you click an item in a list box, the
SelectedIndexChanged event procedure will fire. Within this event, you can write code to call
another subroutine that you will write next, called FormShow.

1. Bring up the Products form in design view mode.


2. Double-click the list box to display the SelectedIndexChanged event procedure.
3. Add a call to a routine named FormShow.
4. Private Sub lstProducts_SelectedIndexChanged( _
5. ByVal sender As Object, ByVal e As System.EventArgs) _
6. Handles lstProducts.SelectedIndexChanged
7.
FormShow()
8. End Sub

Now create this FormShow procedure after the End Sub statement of the above event procedure.
FormShow retrieves the PDSAListItemNumeric object from the list box and builds a SELECT
statement to retrieve all of the columns from the Products table for the particular item selected. It
then builds a DataReader object of that one row, reads the data from the data source, and puts all
of the detail information for that product into the appropriate text boxes on this form.
1. Create the FormShow procedure within this form.
2. Type in the code shown below.
3. Private Sub FormShow()
4.
Dim oCmd As SqlClient.SqlCommand
5.
Dim oDR As SqlClient.SqlDataReader
6.
Dim oItem As PDSAListItemNumeric
7.
Dim strSQL As String
8.
Dim strConn As String
9.
10.
strConn = ConnectStringBuild()
11.
12.
' Get Primary Key From List Box
13.
oItem = CType(lstProducts.SelectedItem, _
14.
PDSAListItemNumeric)
15.
16.
strSQL = "SELECT ProductID, ProductName, "
17.
strSQL &= " QuantityPerUnit, UnitPrice, "
18.
strSQL &= " UnitsInStock, UnitsOnOrder, "
19.
strSQL &= " ReorderLevel, Discontinued "
20.
strSQL &= " FROM Products "
21.
strSQL &= " WHERE ProductID = " & oItem.ID
22.
23.
Try
24.
oCmd = New SqlClient.SqlCommand()
25.
With oCmd
26.
.Connection = _
27.
New SqlClient.SqlConnection(strConn)
28.
.Connection.Open()
29.
.CommandText = strSQL
30.
oDR = .ExecuteReader()
31.
End With
32.
33.
If oDR.Read() Then

34.
With oDR
35.
txtID.Text = .Item("ProductID").ToString()
36.
txtName.Text = _
37.
.Item("ProductName").ToString()
38.
txtQty.Text = _
39.
.Item("QuantityPerUnit").ToString()
40.
txtPrice.Text = _
41.
.Item("UnitPrice").ToString()
42.
txtInStock.Text = _
43.
.Item("UnitsInStock").ToString()
44.
txtOnOrder.Text = _
45.
.Item("UnitsOnOrder").ToString()
46.
txtReorder.Text = _
47.
.Item("ReorderLevel").ToString()
48.
chkDisc.Checked = _
49.
CType(.Item("Discontinued"), Boolean)
50.
End With
51.
End If
52.
oDR.Close()
53.
oCmd.Connection.Close()
54.
55.
Catch oException As Exception
56.
MessageBox.Show(oException.Message)
57.
58.
End Try
59. End Sub

There's not too much new in the FormShow procedure as you are using the same kind of coding
you created in the ListLoad procedure. Retrieve the PDSAListItemNumeric object from the
SelectedItem property of the list box and place it into the variable oItem.
oItem = CType(lstProducts.SelectedItem, _
PDSAListItemNumeric)

The CType function converts one data type to another data type. In this case, you are converting
an Object type into a PDSAListItemNumeric type. All items placed into the Items collection of a
list box are stored as generic Object types.
The rest of the procedure creates a Command object, opens a connection and creates a
DataReader object to read the one record from the data source. It then takes each of the columns
and places the data into the appropriate text boxes.
Try It Out
Now that you have created the FormShow procedure, try it out to make sure it works.
1. Start the application by pressing F5.
2. Click an entry in the list box to make sure that the detail information for that particular
product shows up in the text boxes on the form.

Don't worry about the combo boxes for Supplier and Category; you will learn how to work with
those controls in the next section.

Loading Combo Boxes


On the Product form, there are two combo boxes that need to be loaded: Categories and
Suppliers. Both can be loaded just like you load a list box. Use a PDSAListItemNumeric class to
load both the primary key and the text for the combo box. For the Categories table, select the
columns CategoryID and CategoryName. For the Suppliers table, select the columns SupplierID
and CompanyName. In the Products table, the CategoryID and SupplierID columns are the
foreign keys into the Categories and Suppliers tables, respectively.
1. Create the CategoryLoad procedure within this form.
2. Type in the code shown below in the form's code window.
3. Private Sub CategoryLoad()
4.
Dim oCmd As SqlClient.SqlCommand
5.
Dim oDR As SqlClient.SqlDataReader
6.
Dim strSQL As String
7.
Dim strConn As String
8.
Dim oItem As PDSAListItemNumeric
9.
10.
strConn = ConnectStringBuild()
11.
12.
strSQL = "SELECT CategoryID, CategoryName "
13.
strSQL &= "FROM Categories"
14.
15.
Try
16.
oCmd = New SqlClient.SqlCommand()
17.
With oCmd
18.
.Connection = _
19.
New SqlClient.SqlConnection(strConn)
20.
.Connection.Open()
21.
.CommandText = strSQL
22.
' Closes connection when
23.
' closing DataReader object
24.
oDR = .ExecuteReader( _
25.
CommandBehavior.CloseConnection)
26.
End With
27.
28.
Do While oDR.Read()
29.
oItem = New PDSAListItemNumeric()
30.
With oDR
31.
oItem.ID = CInt(.Item("CategoryID"))
32.
oItem.Value = _
33.
.Item("CategoryName").ToString()
34.
End With
35.
36.
cboCategory.Items.Add(oItem)
37.
Loop
38.
oDR.Close()
39.
' No need to close this because of the

40.
'.CloseConnection on the ExecuteReader
41.
'oCmd.Connection.Close()
42.
43.
Catch oExcept As Exception
44.
MessageBox.Show(oExcept.Message)
45.
46.
End Try
47. End Sub

There is one difference between this routine and the ListLoad procedure you created earlier: on
the ExecuteReader method, you passed in a new constant, CloseConnection. This parameter tells
the DataReader class to close the connection when it is finished loading the list. This means that
you don't have to make an explicit call to the Close method on the command object's Connection
property.

Create the SupplierLoad Procedure


Create the SupplierLoad procedure just like the CategoryLoad procedure. In fact, you can copy
and paste the CategoryLoad procedure back into the form and just change the name.
1. Copy the CategoryLoad procedure into the clipboard, then paste a copy of it just below
the CategoryLoad procedure.
2. Change the name of the second procedure to SupplierLoad.
3. Change the appropriate column and table names in the SELECT statement. The columns
in the Suppliers table to use are SupplierID and CompanyName.
4. Change all references to the cboCategory combo box in this procedure to use the
cboSupplier combo box.

Call These Procedures When Loading the Form


You need to add a call to these procedures from the frmProducts_Load event procedure.

Change the frmProduct_Load event procedure to look like the following.

Private Sub frmProduct_Load( _


ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
' Load Suppliers
SupplierLoad()
' Load Categories
CategoryLoad()
' Load List Box of Products
ListLoad()
End Sub

Try It Out
Run the program to make sure that these routines are indeed loading the data into the appropriate
combo boxes on the screen. Press F5 to see if the category and supplier combo boxes got loaded.

Finding Values in Combo Boxes


Now that you have the category and supplier combo boxes loaded, you need to be able to
position the combo boxes to the appropriate values whenever you click a new product in the list
box. For example, when the CategoryID value in the Products table gets read in via the
DataReader object in the FormShow procedure, you need to find that CategoryID within the
objects that are loaded into the Category combo box. Let's try it.
1. Change the FormShow procedure and add a Dim statement at the beginning of the routine
with a variable named strID.
2. Dim strID As String

3. Change the FormShow procedure and add the CategoryID and SupplierID columns to the
SELECT statement.
4. Find the section of code shown below and add the line that is highlighted in bold.
5. strSQL = "SELECT ProductID, ProductName, "
6. strSQL &= " SupplierID, CategoryID, "
7. strSQL &= " QuantityPerUnit, UnitPrice, "
8. strSQL &= " UnitsInStock, UnitsOnOrder, "
9. strSQL &= " ReorderLevel, Discontinued "
10. strSQL &= " FROM Products "
11. strSQL &= " WHERE ProductID = " & oItem.ID

12. Find the section of code in FormShow that loads the data from the DataReader into the
text boxes, and add the following lines that are in bold.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.

txtID.Text = .Item("ProductID").ToString()
txtName.Text = .Item("ProductName").ToString()
strID = .Item("SupplierID").ToString()
Call FindItem(cboSupplier, strID)
strID = .Item("CategoryID").ToString()
Call FindItem(cboCategory, strID)
txtQty.Text = .Item("QuantityPerUnit").ToString()
txtPrice.Text = .Item("UnitPrice").ToString()
txtInStock.Text = .Item("UnitsInStock").ToString()
txtOnOrder.Text = .Item("UnitsOnOrder").ToString()
txtReorder.Text = .Item("ReorderLevel").ToString()

24. Next, create the FindItem function that accepts a combo box reference and a string
variable. This function finds that string variable within the ID property of the objects in
the combo box and sets the combo box to display the data located in that position.

25. Private Sub FindItem(ByVal cboCombo As ComboBox, _


26.
ByVal strID As String)
27.
Dim intLoop As Integer
28.
Dim boolFound As Boolean
29.
Dim oItem As PDSAListItemNumeric
30.
31.
oItem = New PDSAListItemNumeric()
32.
For intLoop = 0 To cboCombo.Items.Count - 1
33.
oItem = CType(cboCombo.Items(intLoop), _
34.
PDSAListItemNumeric)
35.
If oItem.ID = CInt(strID) Then
36.
cboCombo.SelectedIndex = intLoop
37.
boolFound = True
38.
Exit For
39.
End If
40.
Next
41.
If Not boolFound Then
42.
cboCombo.SelectedIndex = -1
43.
End If
44. End Sub

This FindItem function loops through all of the values in the combo box, removing an item from
the combo box each time through, and converting it to a PDSAListItemNumeric object. You can
compare the ID property of the returned object to see if it is equal to the value that is passed in as
the second parameter to this function. If it finds this value, it will set the SelectedIndex property
to this location, which forces the combo box to position itself to that value.

Performance Issues
You can further enhance performance for certain situations by passing in a different
CommandBehavior constant to the ExecuteReader method on the Command object. You are
allowed to specify KeyInfo, which reads in only primary key information. You can specify
SchemaOnly to read in just the column schema information with no data attached. You can
specify SingleColumn if you are only returning an aggregate value. Or, if you know that only
one row will be returned, specify SingleRow to get even better performance in this situation.

Modifying Data
You also need to create procedures for this client/server type of application to add, edit, and
delete data. Use the Command object to submit these INSERT, UPDATE, and DELETE
statements via the ExecuteNonQuery method of this object. As an example, here is the code to
write for updating the data in this screen.
Private
Dim
Dim
Dim

Sub DataUpdate()
oCmd As SqlClient.SqlCommand
strSQL As String
intRows As Integer

strSQL = "UPDATE Products SET "


strSQL &= "ProductName = " & _
Str2Field(txtName.Text) & ", "

strSQL &= "SupplierID = " & _


CType(cboSupplier.Items(cboSupplier.SelectedIndex), _
PDSAListItemNumeric).ID & ", "
strSQL &= "CategoryID = " & _
CType(cboCategory.Items(cboCategory.SelectedIndex), _
PDSAListItemNumeric).ID & ", "
strSQL &= "QuantityPerUnit = " & _
Str2Field(cboSupplier.Text) & ", "
strSQL &= "UnitPrice = " & txtPrice.Text & ", "
strSQL &= "UnitsInStock = " & txtInStock.Text & ", "
strSQL &= "UnitsOnOrder = " & txtOnOrder.Text & ", "
strSQL &= "ReorderLevel = " & txtReorder.Text & ", "
strSQL &= "Discontinued = " & _
CType(IIf(chkDisc.Checked, "1", "0"), String)
strSQL &= " WHERE ProductID = " & _
CType(lstProducts.SelectedItem, _
PDSAListItemNumeric).ID
Try

oCmd = New SqlClient.SqlCommand()


With oCmd
.Connection = New _
SqlClient.SqlConnection(ConnectStringBuild())
.Connection.Open()
.CommandText = strSQL
intRows = .ExecuteNonQuery()
If intRows <> 1 Then
MessageBox.Show("Did not insert row")
End If
.Connection.Close()
End With

Catch oException As Exception


MessageBox.Show(oException.Message)
End Try
End Sub

The code shown above uses the standard Command object to submit the UPDATE SQL
statement. The Str2Field function you see referenced adds a single quote around any string
values. Here is the String2Field function.
Private Function Str2Field(ByVal strValue As String) _
As String
If strValue.Trim() = "" Then
Return "Null"
Else
Return "'" & strValue.Trim() & "'"
End If
End Function

Using ADO.NET DataTables and DataSets

An ADO.NET DataSet object is like an in-memory database. This object holds a collection of
DataTable objects. Each DataTable object is a representation of the data that was retrieved via a
SELECT statement or stored procedure execution. The data in a DataSet can be written out or
read in as XML. DataSets also store schema information, constraints, and relationships between
multiple DataTable objects. Through a DataSet you can add, edit, and delete data.
DataSets can be used, among other things, to retrieve data from a data source to be displayed in
controls on a form. In this section, you will learn to create a data entry form using DataTable and
DataSet objects. Figure 3 shows the sample screen you will build which is basically the same
form you created earlier in this document. You will use the Products table in the Northwind
database. This sample database comes as an Access database and is installed as a part of SQL
Server.

Figure 3: Add/Edit/Delete Screen using DataSets


To create this form, copy the form you created earlier by following these steps.
1. In Solution Explorer, click the frmProducts.vb form.
2. Press Ctrl+C to copy the form to the clipboard.
3. Press Ctrl+V to paste a copy of this form back into Solution Explorer.
4. Rename the form to frmProductsDS.vb.

5. Open the code window for the form and change the line that reads Public Class Form1
to Public Class frmProductsDS.
6. When you copy the form, all of the procedures you wrote will be copied as well. You can
either keep this code, or you can delete all of the procedures.
You now have a new form that you can use to re-build the routines that you built earlier using the
DataReader to use DataTables and DataSets.

Loading a ComboBox Using a DataTable Object


There are two combo boxes on our Product Information form. One is for categories of products
and the other is for suppliers of products. Load the data into these combo boxes using the
DataTable object.
Follow these steps to load the Supplier combo box using the DataTable object.
1. Click the frmProductDS.vb form and then click the View Code icon (or, on the View
menu, click Code).
2. Create the SupplierLoad procedure just below the line that reads Windows Form
Designer Generated Code. Add the code shown below to this new procedure.
3. Private Sub SupplierLoad()
4.
Dim oAdapter As SqlClient.SqlDataAdapter
5.
Dim oTable As DataTable = New DataTable()
6.
Dim oItem As PDSAListItemNumeric
7.
Dim strSQL As String
8.
Dim strConn As String
9.
Dim intLoop As Integer
10.
11.
strConn = ConnectStringBuild()
12.
13.
strSQL = "SELECT SupplierID, CompanyName "
14.
strSQL &= "FROM Suppliers"
15.
16.
Try
17.
oAdapter = _
18.
New SqlClient.SqlDataAdapter(strSQL, strConn)
19.
oAdapter.Fill(oTable)
20.
21.
For intLoop = 0 To oTable.Rows.Count - 1
22.
oItem = New PDSAListItemNumeric()
23.
With oTable.Rows(intLoop)
24.
oItem.Value = _
25.
.Item("CompanyName").ToString()
26.
oItem.ID = CInt(.Item("SupplierID"))
27.
End With
28.
29.
cboSupplier.Items.Add(oItem)
30.
Next

31.
32.
Catch oExcept As Exception
33.
MessageBox.Show(oExcept.Message)
34.
35.
End Try
36. End Sub

You are going to need three objects for loading this combo box. You will need a DataAdapter,
which is the object that is used to fill up a DataTable or DataSet with data. You will need a
DataTable object, which holds all of the data retrieved by the SELECT statement submitted to
the data source. You will also need a PDSAListItemNumeric class into which you will place the
value to display in the combo box, along with the primary key value from the Suppliers table.
The PDSAListItemNumeric class is already built for you and is contained within the solution
you loaded at the beginning of this document.

Building a Connection String


Before you can submit a SQL statement to a data source through ADO.NET, you need to give
ADO.NET directions regarding where this data source resides and what provider to use to get at
this data. This is done via a connection string. In the SupplierLoad procedure you built, you
called a function called ConnectStringBuild that returns this provider string. Let's create this
function.
Add the following function just below the End Sub of the SupplierLoad procedure you just
created.
Ads not by this site

Private Function ConnectStringBuild() As String


Dim strConn As String
strConn &= "Data Source=(local);"
strConn &= "Initial Catalog=Northwind;"
strConn &= "User ID=sa"
Return strConn
End Function

You may need to change this connection string if you are using SQL Server that is somewhere on
your network, rather than on your local machine. If you do not have SQL Server, you can use the
Northwind.mdb file that comes with Microsoft Access as a sample database. If you are using
Access, you need to use the OleDbConnection, OleDbCommand, and OleDbDataAdapter object
found in the System.Data.OleDb namespace and change your connection string to something like
the following:
Provider=Microsoft.Jet.OleDb.4.0;Data Source=C:\Access\Northwind.mdb

Change the path in the Data Source attribute to the path where your Northwind.mdb is located.

Use a Data Adapter to Fill a DataTable

After you have built the connection string and the SQL string, create a new instance of a
DataAdapter object and pass to it the SQL string and the connection string. Invoke the Fill
method on the DataAdapter and pass to it the DataTable object. The Fill method opens a
connection to the database using the supplied connection string, fills the DataTable with data,
and then closes the connection.
Once you have the data loaded into the DataTable, you can loop through each DataRow object
that makes up the DataTable. Each time through the loop, you create a new
PDSAListItemNumeric object, add the primary key (SupplierID) to the ID property, and the
CompanyName column to the Value property. You then add this PDSAListItemNumeric object to
the ListBox.
Because there is no ItemData property in the list box control like there was in Visual Basic 6.0,
you will need to use the generic PDSAListItemNumeric class you built earlier to hold the
primary key data as well as the text value to display.

Load the Categories Combo Box


To load the categories into the combo box on this product's form, you can copy and paste the
SupplierLoad procedure, and then change the name, the columns, and the table name in the
SELECT statement.
1. Copy the complete SupplierLoad procedure into memory by highlighting the code and
pressing Ctrl+C.
2. Paste the code immediately below the End Sub of the SupplierLoad procedure by placing
the cursor and pressing Ctrl+V.
3. Change the name of this new procedure to CategoryLoad.
4. Change the SELECT statement to use the columns CategoryID and CategoryName.
5. Change the SELECT statement to use the table name Categories.
6. Change the columns that load the PDSAListItemNumeric class to CategoryID and
CategoryName.
Try It Out
Now that you have typed in all the code to use the DataTable object to load Suppliers and
Categories, let's see if they work.
1. Open the form so that you see the form in design mode.
2. Double-click anywhere on the form itself (not on a control), and write code within the
frmProduct_Load event procedure to call each of these routines you just wrote.

3. Private Sub frmProduct_Load( _


4. ByVal sender As System.Object, _
5. ByVal e As System.EventArgs) Handles MyBase.Load
6.
' Load Suppliers
7.
SupplierLoad()
8.
' Load Categories
9.
CategoryLoad()
10. End Sub

11. Now run the program by pressing F5.


If everything worked OK, you should see a blank product form, but the Supplier and Category
combo boxes should have data in them.

Creating a DataSet Object


The DataTable object holds a single table's amount of data and is useful for loading combo boxes
and list boxes. A DataSet object is like a wrapper around one or more DataTable objects. Let's
learn to use the DataSet object.
When you are putting together a data entry screen, it is helpful to create one DataSet that you
declare as a property of your Form class. This property can then be used throughout the form to
load data into the list box, and to add, edit, and delete data on the form.
1. Open the frmProducts.vb file in the sample project.
2. Open the code window and go to the very top of the form code.
3. Immediately after the Inherits statement, add a Private variable called moDS that is
declared as a DataSet class (see the bold text in the following code).
4. Public Class frmProduct
5.
Inherits System.Windows.Forms.Form
6.
7.
Private moDS As DataSet

This will create a private variable that can be used throughout the form. Next, you will
create the DataSet and load it up with data.
8. Create a new procedure called DataSetCreate and type in the code shown below into this
new procedure.
9. Private Sub DataSetCreate()
10.
Dim oAdapter As SqlClient.SqlDataAdapter
11.
Dim strSQL As String
12.
Dim strConn As String
13.
14.
' Get Connection String
15.
strConn = ConnectStringBuild()
16.

17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38. End

' Build SQL String


strSQL = "SELECT * "
strSQL &= "FROM Products"
moDS = New DataSet()
Try
' Create New Data Adapter
oAdapter = _
New SqlClient.SqlDataAdapter(strSQL, strConn)
' Fill DataSet From Adapter and give it a name
oAdapter.Fill(moDS , "Products")
' Create a Primary Key
With moDS.Tables("Products")
.PrimaryKey = New DataColumn() _
{.Columns("ProductID")}
End With
Catch oExcept As Exception
MessageBox.Show(oExcept.Message)
End Try
Sub

Most of the above code should look familiar by now. You build a connection string and a SQL
SELECT statement. You also create DataAdapter to load the DataSet, just like you did with the
DataTable. From there, things get a little different.
You still use the Fill method, but you pass it a DataSet object and the name that you wish to
associate with the new DataTable that is created within this DataSet. In the case above, you will
give this new DataTable the name Products. You can then use this name to reference which table
in the Tables collection of the DataSet you wish to use.
You can reference an individual DataTable by using the Tables collection. For example,
moDS.Tables("Products") returns the DataTable object created when you performed the Fill
method on the DataAdapter. Remember that you passed "Products" as the second parameter on
the Fill method, so it assigned this name to this DataTable. You can use this technique to tell the
DataTable which column is its primary key.
If you plan on doing any searching within this DataTable in the DataSet, you will need to tell the
DataTable which is the PrimaryKey column. You do this by setting the PrimaryKey property to a
New DataColumn array. Because tables can have one or more columns as their primary key, you
need to create an array of DataColumn objects to pass to this PrimaryKey property. What you
have done in the code above is to retrieve the .Columns("ProductID") column and enclose it in
braces {} immediately after declaring a new DataColumn array. The braces are how you declare
the elements that you wish to go into this new array. If you have multiple columns, you separate
each column by a comma within the braces.

Loading a List Box from a DataSet

You have created a DataSet of product data and stored it in the variable named moDS. You can
use that variable anywhere within this form. You will now build a routine that will load the
product data from the DataSet into the list box on this form.
1. Create a new procedure named ListLoad somewhere within the form.
2. Type in the following code into this procedure.
3. Private Sub ListLoad()
4.
Dim oItem As PDSAListItemNumeric
5.
Dim oRow As DataRow
6.
7.
LstProducts.Items.Clear()
8.
' Loop through each row and get a DataRow
9.
For Each oRow In moDS.Tables("Products").Rows
10.
' Create New Item to hold PK and Description
11.
oItem = New PDSAListItemNumeric()
12.
With oItem
13.
.ID = CInt(oRow.Item("ProductID"))
14.
.Value = oRow.Item("ProductName").ToString()
15.
End With
16.
17.
' Add Item to list box
18.
lstProducts.Items.Add(oItem)
19.
Next
20.
21.
lstProducts.SetSelected(0, True)
22. End Sub

The code in the ListLoad procedure is very simple. Each DataTable in a DataSet is made up of
DataRow objects. You can loop through each DataRow in the DataTable and each time through
the loop, you can build a PDSAListItemNumeric object to put the ProductID and ProductName
into. You then add this new object to the List Box.
Try It Out
You should now be able to run the code you typed in and have it load the list box full of product
names.
1. Change the frmProduct_Load event procedure to call these two new routines you created.
2. Add the lines of code shown below in bold.
3. Private Sub frmProduct_Load( _
4. ByVal sender As System.Object, _
5. ByVal e As System.EventArgs) Handles MyBase.Load
6.
' Load Suppliers
7.
SupplierLoad()
8.
' Load Categories
9.
CategoryLoad()
10.

11.
12.
13.
14.
15. End

' Initialize the DataSet


DataSetCreate()
' Load List Box of Products
ListLoad()
Sub

16. Press F5 to run this program.


When the form appears, you should have a list box full of product names.

Finding a Specific Row in the DataSet


When a user clicks on a product in the list box, the detail data should display for each product in
the appropriate controls to the right of the list box. The first thing you need to do is to write the
code that will respond to the user clicking the list box.
1. Bring up the Products form in design mode.
2. Double-click the list box to display the SelectedIndexChanged event procedure.
3. Add the code to call a procedure named FormShow as shown below.
4. Private Sub lstProducts_SelectedIndexChanged( _
5. ByVal sender As Object, ByVal e As System.EventArgs) _
6. Handles lstProducts.SelectedIndexChanged
7.
FormShow()
8. End Sub

9. Write the FormShow procedure that will find a specific row within the DataSet, retrieve
the information from that row, and fill in all of the appropriate controls on the Product
form.
10. Add a new procedure to the Product form and name it FormShow.
11. Write the code shown below.
12. Private Sub FormShow()
13.
Dim oDR As DataRow
14.
Dim strID As String
15.
16.
' Get Primary Key From List Box
17.
strID = CType(lstProducts.SelectedItem, _
18.
PDSAListItemNumeric).ID.ToString()
19.
20.
' Find row in DataSet
21.
oDR = moDS.Tables("Products").Rows.Find(CInt(strID))
22.
txtID.Text = oDR("ProductID").ToString()
23.
txtName.Text = oDR("ProductName").ToString()
24.
strID = oDR("SupplierID").ToString()
25.
Call FindItem(cboSupplier, strID)
26.
strID = oDR("CategoryID").ToString()

27.
28.
29.
30.
31.
32.
33.
34. End

Call FindItem(cboCategory, strID)


txtQty.Text = oDR("QuantityPerUnit").ToString()
txtPrice.Text = oDR("UnitPrice").ToString()
txtInStock.Text = oDR("UnitsInStock").ToString()
txtOnOrder.Text = oDR("UnitsOnOrder").ToString()
txtReorder.Text = oDR("ReorderLevel").ToString()
chkDisc.Checked = CType(oDR("Discontinued"), Boolean)
Sub

The first thing the FormShow procedure does is to return the SelectedItem from the list box.
Each item in the list box is a PDSAListItemNumeric object. Because the list box only holds
Object data types, you need to use the CType function to convert the Object into a
PDSAListItemNumeric data type. You can then retrieve the ID property from this object to get
the primary key for the row you just clicked.
The Find method on the Rows returns a single DataRow object. In the FormShow procedure, you
declared a variable named oDR as a DataRow object. You pass the ID property to the Find
method to have it return a reference to the found DataRow. Once you have this DataRow object,
you can get at the data in each individual column.

Adding Rows to a DataSet


At some point, you will want to allow users to add rows to the tables. You can do this by
submitting an INSERT statement through a Command object, or you can use the DataSet object
you have already created. There are a few steps to perform to add a new row to the DataSet and
to the database. Because the DataSet is disconnected from the database, you first need to add the
new data to the DataSet. Next, you need to build a connection to the database and build an
INSERT statement. Microsoft has provided an object that will build this INSERT statement for
you, called the CommandBuilder object.
1. Add a new procedure to your product form.
2. Name this procedure DataAdd.
3. Write the code shown below.
4. Private Sub DataAdd()
5.
Dim oAdapter As SqlClient.SqlDataAdapter
6.
Dim oBuild As SqlClient.SqlCommandBuilder
7.
Dim oDR As DataRow
8.
Dim strSQL As String
9.
Dim strConn As String
10.
11.
' Create New DataRow Object From DataSet
12.
oDR = moDS.Tables("Products").NewRow()
13.
oDR.BeginEdit()
14.
15.
' Load new data into row
16.
oDR("ProductName") = txtName.Text
17.
oDR("SupplierID") = CType(cboSupplier.SelectedItem, _

18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60. End

PDSAListItemNumeric).ID
oDR("CategoryID") = CType(cboCategory.SelectedItem, _
PDSAListItemNumeric).ID
oDR("QuantityPerUnit") = cboSupplier.Text
oDR("UnitPrice") = CDec(txtPrice.Text)
oDR("UnitsInStock") = CShort(txtInStock.Text)
oDR("UnitsOnOrder") = CShort(txtOnOrder.Text)
oDR("ReorderLevel") = CShort(txtReorder.Text)
oDR("Discontinued") = CBool(chkDisc.Checked)
' Tell DataRow you are done adding data
oDR.EndEdit()
' Add DataRow to DataSet
moDS.Tables("Products").Rows.Add(oDR)
Try
' Get Connection String
strConn = ConnectStringBuild()
' Build SQL String
strSQL = "SELECT * FROM Products "
' Create New DataAdapter
oAdapter = _
New SqlClient.SqlDataAdapter(strSQL, strConn)
' Create CommandBuilder for Adapter
' This will build INSERT, UPDATE and DELETE SQL
oBuild = New SqlClient.SqlCommandBuilder(oAdapter)
' Get Insert Command Object
oAdapter.InsertCommand = oBuild.GetInsertCommand()
' Submit INSERT statement through Adapter
oAdapter.Update(moDS, "Products")
' Tell DataSet changes to data source are complete
moDS.AcceptChanges()
' Reload the list box
ListLoad()
Catch oException As Exception
MessageBox.Show(oException.Message)
End Try
Sub

To add a new record to the table in the database, you first need to add a new row to the
DataTable in the DataSet. You can do this by using the NewRow method to create a new
DataRow. Invoke the BeginEdit method on this new DataRow so that you can place data into the
appropriate columns. When you have updated all of the columns, invoke the EndEdit method.
Add this new DataRow to the DataTable in the DataSet by passing the DataRow to the Add
method of the Rows collection in the DataTable.

Use a Command Builder Object to Create SQL

Now that the data is in the DataSet, you can build a DataAdapter to submit this new data to the
database. Create the DataAdapter by passing in the same SQL statement that you used to load the
DataSet and a connection string. You then pass the DataAdapter object to the constructor of the
CommandBuilder class and it creates a new Builder object for you. The GetInsertCommand
method can then be called on this CommandBuilder object to retrieve a command object that
contains an INSERT statement for this table. The INSERT statement uses question marks as
placeholders for each piece of data in the DataSet.
When using the SqlCommandBuilder, the INSERT statement will look something like this:
INSERT INTO "Products"( "ProductName" , "SupplierID" , "CategoryID" ,
"QuantityPerUnit" , "UnitPrice" , "UnitsInStock" , "UnitsOnOrder" ,
"ReorderLevel" , "Discontinued" ) VALUES ( @ProductName , @SupplierID ,
@CategoryID , @QuantityPerUnit , @UnitPrice , @UnitsInStock ,
@UnitsOnOrder , @Reorderlevel , @Discontinued )

When using the OleDbCommandBuilder the INSERT statement will look something like this:
INSERT INTO "Products"( "ProductName" , "SupplierID" , "CategoryID" ,
"QuantityPerUnit" , "UnitPrice" , "UnitsInStock" , "UnitsOnOrder" ,
"ReorderLevel" , "Discontinued" ) VALUES ( ? , ? , ? , ? , ? , ? , ? , ?
, ? )

Each parameter marker in the statement ("@<columnname>" for the SqlCommand and "?" for
the OleDbCommand) represents where the data from the DataSet will be placed when you
submit this INSERT statement through the DataAdapter. This replacement is done automatically
by the DataAdapter and requires no extra programming on your part. You tell the DataAdapter to
submit this INSERT statement by passing in the DataSet object and the name of the table in the
DataSet that is to be updated to the Update method of the DataAdapter. After this Update method
is completed, invoke the AcceptChanges method on the DataSet. This informs the new DataRow
that it has been updated in the database.
Try It Out
Now that you have created this routine to add a new row, you should give it a try.
1. Bring up the form in design mode.
2. Double-click Add.
3. In the btnAdd_Click event procedure, call the DataAdd procedure.
4. Private Sub btnAdd_Click(ByVal sender As Object, _
5. ByVal e As System.EventArgs) Handles btnAdd.Click
6.
DataAdd()
7. End Sub

8. Press F5 to run the application.

9. Type in A New Product into the Product Name text box.


10. Click Add. You should see the new product appear in the list box.

Updating Rows in a DataSet


Updating rows in a DataSet is almost identical to adding rows. Instead of adding a new row, you
find the existing row that you want to update. You then update the data into the appropriate
columns in the DataRow, build a DataAdapter and a CommandBuilder object, and retrieve the
UPDATE command object. You can then submit the UPDATE statement via the Update method
of the DataAdapter, accept the changes, and you are finished.
1. Type in the code below as a new procedure in this form.
2. Private Sub DataUpdate()
3.
Dim oAdapter As SqlClient.SqlDataAdapter
4.
Dim oBuild As SqlClient.SqlCommandBuilder
5.
Dim oDR As DataRow
6.
Dim strSQL As String
7.
Dim strID As String
8.
Dim strConn As String
9.
10.
' Get Primary Key From List Box
11.
strID = CType(lstProducts.SelectedItem, _
12.
PDSAListItemNumeric).ID.ToString()
13.
14.
' Find Row To Update
15.
oDR = moDS.Tables("Products").Rows.Find(CInt(strID))
16.
17.
' Begin the editing process
18.
oDR.BeginEdit()
19.
20.
' Load new data into row
21.
oDR("ProductName") = txtName.Text
22.
oDR("SupplierID") = CType(cboSupplier.SelectedItem, _
23.
PDSAListItemNumeric).ID
24.
oDR("CategoryID") = CType(cboCategory.SelectedItem, _
25.
PDSAListItemNumeric).ID
26.
oDR("QuantityPerUnit") = cboSupplier.Text
27.
oDR("UnitPrice") = CDec(txtPrice.Text)
28.
oDR("UnitsInStock") = CShort(txtInStock.Text)
29.
oDR("UnitsOnOrder") = CShort(txtOnOrder.Text)
30.
oDR("ReorderLevel") = CShort(txtReorder.Text)
31.
oDR("Discontinued") = CBool(chkDisc.Checked)
32.
33.
' End the editing process
34.
oDR.EndEdit()
35.
36.
Try
37.
' Get Connection String
38.
strConn = ConnectStringBuild()
39.
' Build SQL String
40.
strSQL = "SELECT * FROM Products "

41.
' Create New DataAdapter
42.
oAdapter = New _
43.
SqlClient.SqlDataAdapter(strSQL, strConn)
44.
' Create CommandBuild from Adapter
45.
' This will build INSERT, UPDATE and DELETE SQL
46.
oBuild = New SqlClient.SqlCommandBuilder(oAdapter)
47.
48.
' Get Update Command Object
49.
oAdapter.UpdateCommand = oBuild.GetUpdateCommand()
50.
51.
' Submit UPDATE through Adapter
52.
oAdapter.Update(moDS, "Products")
53.
' Tell DataSet changes to data source are complete
54.
moDS.AcceptChanges()
55.
56.
' Reload the list box
57.
ListLoad()
58.
59.
Catch oException As Exception
60.
MessageBox.Show(oException.Message)
61.
62.
End Try
63. End Sub
64.

As you can see, this code is almost identical to the DataAdd procedure you wrote previously. The
biggest difference is that instead of calling the GetInsertCommand method, you call the
GetUpdateCommand. You place the command object retrieved from the GetUpdateCommand
into the UpdateCommand property on the DataAdapter.
Try It Out
Now that you have created this routine to add a new row, you should give it a try.
1. Bring up the form in design mode.
2. Double-click Update.
3. In the btnUpdate_Click event procedure, call the DataUpdate procedure.
4. Private Sub btnUpdate_Click(ByVal sender As Object, _
5. ByVal e As System.EventArgs) Handles btnUpdate.Click
6.
DataUpdate()
7. End Sub

8. Press F5 to run the application.


9. Change one of the product names and maybe a couple of the other fields on one of the
records.
10. Click Update.

11. Click another product and then click back on the product you updated. You should see the
updated data appear in the controls on the product form.

Deleting Rows in a DataSet


By this time, you should be seeing a pattern for updating data through a DataSet object. In fact,
to delete data from a DataSet, you write almost the same code, but instead of updating the
appropriate data in the DataRow, you apply the Delete method instead. Then you submit this
change through the DataAdapter, just like you did in the DataAdd and DataUpdate procedures
you wrote.
1. Add a new procedure called DataDelete in the form.
2. Write the following code in this new procedure.
3. Private Sub DataDelete()
4.
Dim oAdapter As SqlClient.SqlDataAdapter
5.
Dim oBuild As SqlClient.SqlCommandBuilder
6.
Dim oDR As DataRow
7.
Dim strSQL As String
8.
Dim strID As String
9.
Dim strConn As String
10.
11.
' Get Connection String
12.
strConn = ConnectStringBuild()
13.
14.
' Get Primary Key From List Box
15.
strID = CType(lstProducts.SelectedItem, _
16.
PDSAListItemNumeric).ID.ToString()
17.
18.
' Find DataRow To Delete
19.
oDR = moDS.Tables("Products").Rows.Find(CInt(strID))
20.
' Mark DataRow for deletion
21.
oDR.Delete()
22.
23.
Try
24.
' Build SQL String
25.
strSQL = "SELECT * FROM Products "
26.
' Create New DataAdapter
27.
oAdapter = New _
28.
SqlClient.SqlDataAdapter(strSQL, strConn)
29.
' Create CommandBuild from Adapter
30.
' This will build INSERT, UPDATE and DELETE SQL
31.
oBuild = New SqlClient.SqlCommandBuilder(oAdapter)
32.
33.
' Get Delete Command Object
34.
oAdapter.DeleteCommand = oBuild.GetDeleteCommand()
35.
36.
' Submit DELETE through Adapter
37.
oAdapter.Update(moDS, "Products")
38.
' Tell DataSet changes to data source are complete
39.
moDS.AcceptChanges()
40.

41.
' Reload the list box
42.
ListLoad()
43.
44.
Catch oException As Exception
45.
MessageBox.Show(oException.Message)
46.
47.
End Try
48. End Sub
49.

In the above code, you find the row you wish to delete and then apply the Delete method to that
DataRow object. This marks the row for deletion in the DataSet. You again use the
CommandBuilder object to get the DeleteCommand object, and invoke the Update method on
the DataAdapter to submit this DELETE statement to the database.
Try It Out
Now that you have created this routine to delete a row, you should give it a try.
1. Bring up the form in design mode.
2. Double-click the Delete button.
3. In the btnDelete_Click event procedure, call the DataDelete procedure.
4. Private Sub btnDelete_Click(ByVal sender As Object, _
5. ByVal e As System.EventArgs) Handles btnUpdate.Click
6.
DataDelete()
7. End Sub

8. Press F5 to run the application.


9. Click one of the products in the list box.
10. Click Delete. You should now see this product disappear from the list box.

Dim SQL As String = "SELECT * FROM titles"


02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19

Dim myCommand As New


MySqlCommand
Dim myAdapter As New MySqlDataAdapter
Dim myData As New DataTable
Dim i As Integer
With myCommand
.CommandText = SQL
.Connection = conn
End With
With myAdapter
.SelectCommand = myCommand
.Fill(myData)
End With
titlelist.Items.Clear()
For i = 0 To myData.Rows.Count - 2

20
21
22
23
24
25
26
27
28

With titlelist
.Items.Add(myData.Rows(i)("title_id"))
With .Items(.Items.Count - 1).SubItems
.Add(myData.Rows(i)("title_name"))
.Add(myData.Rows(i)("title_cat"))
End With
End With
Next

Im trying to get interesting with MySQL to connect my Visual Basic.Net. First, you
will

need

to

download

the

MySQL

http://dev.mysql.com/downloads/connector/net/
http://dev.mysql.com/downloads/workbench/5.2.html

Connector/Net

from
and

for the MySQL GUI Tools

Bundle (Administrator, Query Browser, and Migration Toolkit). Once the connector is
installed, now begin a new project in VB.Net. Choose "Add Reference" from the
Project menu, then select "Browse" and browse to the installation folder where the
connector was installed, choose "MySQL.Data.dll". Now imports the Connector/NET
to use its Namespace shown below.
Imports MySql.Data.MySqlClient
Public Class Form1
It includes how connect MySQL to VB.NET and it enable to SELECT, UPDATE,
DELETE, and UPDATE records. Then, it can perform following tasks such as ADD,
DELETE, UPDATE, SAVE, and SEARCH records that populate using ListView.
In other tutorials, they use DataGridView because thats the easy way how to load

data from database. First, Ive already created a module. To do that, from the
project menu, select Add Module. Here is the code.
Imports MySql.Data.MySqlClient
Module MyModule
Public ConnString As String = "server=localhost;user
id=root;password=;database=dbinformation"
Public MyConnection As New MySqlConnection(ConnString)
End Module
Ads not by this site

The above code is MySQL connection. Actually, you can create a connection without
the help of module. The technique here is, create a method name for connection
and simply call the connection if needed. Once the method name is created, simply
put myconnection() in every form load to enable to connect from your database.
Note: there are different styles of coding to connect from database, its up to the
programmer.
Public Sub myconnection()
Dim sqlserver As String = "Server=127.0.0.1;User
ID=root;Password=;Database=DbTest" 'or you may used localhost instead 127.0.0.1
Dim sqlcon As New MySqlConnection
sqlcon.ConnectionString = sqlserver
Try
If sqlcon.State = ConnectionState.Closed Then
sqlcon.Open()
MessageBox.Show("Open")
Else
sqlcon.Close()
MessageBox.Show("closed")
End If

Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub

Under construction yet! continue

Form 1
Imports MySql.Data.MySqlClient
Public Class Form1
Public ds As New DataSet
Public strSQL As String
Public cmd As New MySqlCommand
Public dr As MySqlDataReader
Public table As New DataTable
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles MyBase.Load
'list()
mylistview()
End Sub
Private Sub btnsave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles btnsave.Click
strSQL = "Insert into tblinformation(Firstname,Lastname,Middlename,Gender) values ('" &
txtfname.Text &
"', '" & txtlname.Text & "', '" & txtmname.Text & "', '" & cbogender.Text & "')"
Dim da As New MySqlDataAdapter(strSQL, MyConnection)

da.Fill(ds)

txtfname.Clear()
txtlname.Clear()
txtmname.Clear()
cbogender.Text = ""
txtfname.Focus()
list()
End Sub
Private Sub btndelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles btndelete.Click
If lvinfo.Items.Count > 0 Then
For i = lvinfo.Items.Count - 1 To 0 Step -1
If lvinfo.Items(i).Checked = True Then
strSQL = "DELETE FROM tblinformation WHERE ID = '" & lvinfo.Items(i).Text & "'"
Dim da As New MySqlDataAdapter(strSQL, MyConnection)
da.Fill(ds)
End If
Next i
End If
list()
End Sub
Private Sub TextBox3_TextChanged(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles txtsearch.TextChanged
strSQL = "SELECT * FROM tblinformation WHERE Firstname LIKE '%" & txtsearch.Text & "%'
OR Lastname LIKE '%" & txtsearch.Text & "%'"
MyConnection.Open()
cmd = New MySqlCommand(strSQL, MyConnection)
dr = cmd.ExecuteReader()
lvinfo.Items.Clear()
Do While dr.Read()
Dim a = (dr.Item("ID").ToString())

Dim b = (dr.Item("Firstname").ToString())
Dim c = (dr.Item("Lastname").ToString())
Dim d = (dr.Item("Middlename").ToString())
Dim f = (dr.Item("Gender").ToString())
Dim lv As ListViewItem = lvinfo.Items.Add(a)
lv.SubItems.Add(b)
lv.SubItems.Add(c)
lv.SubItems.Add(d)
Loop
dr.Close()
MyConnection.Close()
MyConnection.Dispose()
End Sub
Private Sub ListView1_DoubleClick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles lvinfo.DoubleClick
If lvinfo.Items.Count > 0 Then
Form2.lblid.Text = lvinfo.SelectedItems(0).Text
Form2.txtfname.Text = lvinfo.SelectedItems(0).SubItems(1).Text
Form2.txtlname.Text = lvinfo.SelectedItems(0).SubItems(2).Text
Form2.txtmname.Text = lvinfo.SelectedItems(0).SubItems(3).Text
Form2.cbogender.Text = lvinfo.SelectedItems(0).SubItems(4).Text
End If
Form2.Show()
End Sub
Public Sub list()
strSQL = "SELECT * FROM tblinformation"
MyConnection.Open()
cmd = New MySqlCommand(strSQL, MyConnection)
dr = cmd.ExecuteReader()

lvinfo.Items.Clear()
Do While dr.Read()
Dim a = (dr.Item("ID").ToString())
Dim b = (dr.Item("Firstname").ToString())
Dim c = (dr.Item("Lastname").ToString())
Dim d = (dr.Item("Middlename").ToString())
Dim f = (dr.Item("Gender").ToString())
Dim lv As ListViewItem = lvinfo.Items.Add(a)
lv.SubItems.Add(b)
lv.SubItems.Add(c)
lv.SubItems.Add(d)
lv.SubItems.Add(f)
Loop
dr.Close()
cmd.Dispose()
MyConnection.Close()
End Sub

Private Sub btncancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)


Handles btncancel.Click
txtfname.Clear()
txtlname.Clear()
txtmname.Clear()
cbogender.Text = ""
txtfname.Focus()
End Sub
#Region "My Other Option to call listview"
Public Sub mylistview()
Dim sqladpater As New MySqlDataAdapter

Dim i As Integer
strSQL = "SELECT * FROM tblinformation"
With cmd
.CommandText = strSQL
.Connection = MyConnection
End With
With sqladpater
.SelectCommand = cmd
.Fill(table)
End With
lvinfo.Items.Clear()
For i = 0 To table.Rows.Count - 1
With lvinfo
.Items.Add(table.Rows(i)("ID"))
With .Items(.Items.Count - 1).SubItems
.Add(table.Rows(i)("Firstname"))
.Add(table.Rows(i)("Lastname"))
.Add(table.Rows(i)("Middlename"))
.Add(table.Rows(i)("Gender"))
End With
End With
Next
End Sub
#End Region
#Region "Listview properties"
Public Sub ListViewProperties()
' Set ListView Properties
lvinfo.View = View.Details
lvinfo.GridLines = True

lvinfo.FullRowSelect = True
lvinfo.HideSelection = False
lvinfo.MultiSelect = False
End Sub
#End Region

End Class

Module created
Imports MySql.Data.MySqlClient
Module MyModule
Public ConnString As String = "server=localhost;user
id=root;password=;database=dbinformation"
Public MyConnection As New MySqlConnection(ConnString)
End Module

Form2
Imports MySql.Data.MySqlClient
Public Class Form2
Dim strsql As String
Dim ds As New DataSet
Private Sub btnsave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles btnsave.Click
strsql = "Update tblinformation set Firstname = '" & txtfname.Text & "', Lastname = '" &
txtlname.Text & "', Middlename = '" &
txtmname.Text & "', Gender = '" & cbogender.Text & "' where ID = '" & lblid.Text & "'"
Dim da As New MySqlDataAdapter(strsql, MyConnection)

da.Fill(ds)
Me.Hide()

Form1.list()
End Sub
Private Sub btncancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles btncancel.Click
txtfname.Clear()
txtlname.Clear()
txtmname.Clear()
cbogender.Text = ""
txtfname.Focus()
Me.Hide()
End Sub
Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles MyBase.Load
lblid.Visible = False
End Sub
Private Sub cbogender_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles cbogender.SelectedIndexChanged
End Sub
End Class
Completely run! Add new record(s), Delete Record(s), Update Record(s), and Search Record(s)

- See more at: http://tesear.blogspot.in/2011/11/mysql-in-vbnet-withlistview.html#sthash.rsAYJ4OO.dpuf

Part II: Inserting and Reading of Data in MySQL Database Using Visual Basic.Net
Submitted by:
joken

Tuesday, September 3, 2013 - 14:22


Language:
Visual Basic .NET
Visitors have accessed this post 1518 times.

This tutorial is the continuation of Connecting MySQL Database using Visual Basic.NET. In this
part we will focus on how to insert Data and to load data and display it in a form using
DataGridview Object.
To start with, we will set up first our database table. To do this make sure that you have installed
XAMPP this software is free and open source cross-platform web server solution stack package,
consisting mainly of the Apache HTTP Server, MySQL database, and interpreters for scripts
written in the PHP and Pearl programming languages. If not installed you can download it to the
web and install it into your computer. After you have successfully installed it on your computer
just simply run the Apache Server and MySQL database using the XAMPP Control Panel
Application.
Next step open any browser available in your local computer. For example google chrome and
on the address bar just type http://localhost/phpmyadmin/ and press enter. After this on the List
of the Database then Select test Database as default the test database dont have any table(s)
available inside it. And on the menus Select the SQL tab and paste this code:
1. CREATE TABLE `test`.`users` (
2. `user_id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
3. `fullname` VARCHAR( 30 ) NOT NULL ,
4. `username` VARCHAR( 30 ) NOT NULL ,
5. `password` VARCHAR( 50 ) NOT NULL
6. ) ENGINE = MYISAM ;

So this code will create a table named users and it has a field such as user_id, fullname,
username and password. Now the users table will look like as shown below.

Now its time to proceed to our main goal of this tutorial, to do this lets open the first Part and
the title of this is Connecting MySQL Database using Visual Basic.Net and the project name of
this is VBMYSQL. After this step Go to Solution Explorer->right click the Project name>Click Add->Select Windows Form and automatically new form will open and the default name
of this is Form2.
Designing the User Interface

In the User Interface just add two Buttons, three Textbox, three Labels, one Groupbox and one
Datagridview.
Object

Property

Settings

Form2

Name
Text
Name
Text
Name
Text
Name
Name
Name
Text
Text
Text
Text
Name

manage_user
Manage User
btncreate
Create User
btnRead
Read User
txtfullname
txtusername
txtpassword
Full Name
Username
Password
User Info
dtguser

Button1
Button2
Textbox1
Textbox2
Textbox3
Label1
Label2
Label3
GroupBox1
DataGridView1

And the design looks like as shown below.

Hence we have designed our User Interface lets proceed to add functionality one of our button
specifically the Create User, to do this just Double Click Create User button after this you be
redirected to the code view. And add again were going to do something we have done in our
first tutorial that we put an Imports MySql.Data.MySqlClient above Public class so that we can
have access to our MySQL Objects. Then we need also to copy and paste our declaration of our
object the MySqlConnection Dim con As New MySqlConnection and together with this
declaration we need also to add declaration and the code now will like as shown below.
1. Imports MySql.Data.MySqlClient
2. Public Class Manage_user
3.

Dim con As New MySqlConnection

4.

Dim result As Integer

5.
6.

'MySqlCommand It represents a SQL statement to execute against a


MySQL Database

7.

Dim cmd As New MySqlCommand

8. Next will add code to our btncreate button and heres the code.
9. Private Sub btncreate_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btncreate.Click
10.

'this line of is simply we copy this one from our form

11.

con.ConnectionString = ("server=localhost;user
id=root;password=;database=test")

12.
13.

Try

14.

'we open Connection

15.

con.Open()

16.
17.
18.

With cmd
.Connection = con

19.

.CommandText = "INSERT INTO `test`.`users` (`user_id`,


`fullname`, `username`, `password`) " & _

20.

"VALUES (NULL, '" & txtfullname.Text &


"', '" & txtusername.Text & "', '" & txtpassword.Text & "');"

21.

'in this line it Executes a transact-SQL statements


against the connection and returns the number of rows affected

22.

result = cmd.ExecuteNonQuery

23.

'if the result is equal to zero it means that no rows


is inserted or somethings wrong during the execution

24.

If result = 0 Then

25.
26.
27.

MsgBox("Data has been Inserted!")


Else
MsgBox("Successfully saved!")

28.
29.

End If

30.
31.

End With
Catch ex As Exception

32.

MsgBox(ex.Message)

33.

End Try

34.

con.Close()

35.

End Sub

This time we will try to test if our code is working properly. But before this, we need to set first
that when the program runs it run first the Manage User Form. To do this, Go to Solution
Explorer->right click and select Properties. And on the properties choose the Application Tab
and under the Startup form choose the manage_user like as shown below.

Then just press f5 to run your application. And you test it by writing something in the textbox
provided and after just simply click Create User button.

After this you can view the result in phpmyadmin if you really successfully saved your user
inputted.

So we are designing and adding of code to our Create User we only need is to display all the
user saved in the database to our datagridview. To do this, double click Read user and Add this
code.
1.

Private Sub btnload_Click(ByVal sender As System.Object, ByVal e As


System.EventArgs) Handles btnload.Click

2.

'again we do this because we do not yet declare this as global,


but we do it for now beacause in later tutorial

3.
4.

5.

'we will do the moduling and more on refactoring of codes


con.ConnectionString = ("server=localhost;user
id=root;password=;database=test")
Try

6.

con.Open()

7.

With cmd

8.
9.

.Connection = con
'in this query it does simply selecting or getting all
the user found in the database.

10.

.CommandText = "Select * from users"

11.

End With

12.
13.

Catch ex As Exception

14.

MsgBox(ex.Message)

15.
16.
17.

End Try

18.

con.Close()

19.

da.Dispose()

20.

filltable(dtguser)

21.
22.

End Sub

After this add another sub procedure like this.


Ads not by this site

1. ' this our sub procedure that well always used


2.
3.

'this beacause it always catch all the result query


'and it will display to any kind of visual basic containers like
datagridview,listbox,listview, etc...

4.

Public Sub filltable(ByVal dtgrd As Object)

5.

'declare a variable as new datatable

6.

Dim publictable As New DataTable

7.
8.

Try

9.

'Gets or sets an SQL statement or stored procedure used to


select records in the database.
da.SelectCommand = cmd

10.

da.Fill(publictable)

11.

dtgrd.DataSource = publictable

12.

dtgrd.Columns(0).Visible = False

13.
14.

da.Dispose()

15.
16.

Catch ex As Exception

17.

MsgBox(ex.Message)

18.
19.

End Try

20.
21.

End Sub

And finally try to run your application and the final output will be look like as shown below.

these are all the source code in this tutorial.


1. Imports MySql.Data.MySqlClient
2. Public Class Manage_user
3.

Dim con As New MySqlConnection

4.

Dim result As Integer

5.

'MySqlCommand It represents a SQL statement to execute against a


MySQL Database

6.

Dim cmd As New MySqlCommand

7.

'Represents a set of data commands and a database connection that

8.

9.

'are used to fill a dataset and update a MySQL database. This class
cannot be inherited.
Dim da As New MySqlDataAdapter

10.
11.

Private Sub btncreate_Click(ByVal sender As System.Object, ByVal e


As System.EventArgs) Handles btncreate.Click

12.

'this line of is simply we copy this one from our form

13.

con.ConnectionString = ("server=localhost;user
id=root;password=;database=test")

14.
15.

Try

16.

'we open Connection

17.

con.Open()

18.
19.

With cmd

20.

.Connection = con

21.

.CommandText = "INSERT INTO `test`.`users` (`user_id`,


`fullname`, `username`, `password`) " & _

22.

"VALUES (NULL, '" & txtfullname.Text &


"', '" & txtusername.Text & "', '" & txtpassword.Text & "');"

23.

'in this line it Executes a transact-SQL statements


against the connection and returns the number of rows affected

24.

result = cmd.ExecuteNonQuery

25.

'if the result is equal to zero it means that no rows


is inserted or somethings wrong during the execution

26.

If result = 0 Then

27.

MsgBox("Data has been Inserted!")

28.

Else

29.

MsgBox("Successfully saved!")

30.
31.
32.
33.
34.
35.

End If
End With
Catch ex As Exception
MsgBox(ex.Message)
End Try

36.
37.

con.Close()
End Sub

38.
39.

Private Sub btnload_Click(ByVal sender As System.Object, ByVal e


As System.EventArgs) Handles btnload.Click

40.

'again we do this because we do not yet declare this as


global, but we do it for now beacause in later tutorial

41.

'we will do the moduling and more on refactoring of codes

42.

con.ConnectionString = ("server=localhost;user
id=root;password=;database=test")

43.

Try

44.

con.Open()

45.

With cmd

46.

.Connection = con

47.

'in this query it does simply selecting or getting all


the user found in the database.

48.
49.

.CommandText = "Select * from users"


End With

50.
51.
52.

Catch ex As Exception
MsgBox(ex.Message)

53.
54.
55.

End Try

56.

con.Close()

57.

da.Dispose()

58.

filltable(dtguser)

59.

60.

End Sub

61.

' this our sub procedure that well always used

62.

'this beacause it always catch all the result query

63.

'and it will display to any kind of visual basic containers like


datagridview,listbox,listview, etc...

64.

Public Sub filltable(ByVal dtgrd As Object)

65.

'declare a variable as new datatable

66.

Dim publictable As New DataTable

67.

Try

68.

'Gets or sets an SQL statement or stored procedure used to


select records in the database.

69.

da.SelectCommand = cmd

70.

da.Fill(publictable)

71.

dtgrd.DataSource = publictable

72.

dtgrd.Columns(0).Visible = False

73.
74.

da.Dispose()

75.
76.

Catch ex As Exception

77.

MsgBox(ex.Message)

78.
79.

End Try

80.
81.

End Sub

82. End Class

So that is for now folks. My Part III of my Tutorial will be focusing on completing the User
CRUD or the CREATE, READ, UPDATE AND DELETE.

Load and Search MySQL Data Using VB.NET 2005 in Windows Applications

By Ernest Bonat, Ph.D.


Visual WWW, Inc.
Introduction
Required Software
MySQL Data Load Using DataGridView Control
MySQL Data Search Using Stored Procedures
MySQL Data Search Using DataView Object
Conclusions
Introduction

MySQL data load and search are very important business requirements in any Windows or
Internet web application development. In general, any application needs to show a result set of
data and/or a single record to the end-users. In Windows applications it is very popular to show a

result set of data by using the DataGridView, ListView or TreeView controls. A single record can
be shown by the simple combination of the following controls: TextBox, ComboBox, ListBox,
CheckBox, RadioButton, etc. MySQL data search is provided by using the required ADO.NET
data objects and by refreshing the controls if necessary. These two processes, data load and
search, should be fast and should be done with the proper code which depends on the controls in
the Windows Form or Web Page. In this article I will show you how load and sort MySQL data
using the DataGridView control. To search MySQL data the LIKE SQL operator will be used.
Both programming implementations are done by using stored procedures for MySQL 5.0
database engine.
Required Software

MySQL Database Server 5.0.45

MySQL Connector/NET 5.0.8

Toad for MySQL Freeware 3.0.0

Microsoft Visual Basic 2005 Express Edition

MySQL Data Load Using DataGridView Control


I have received a lot of questions from many VB.NET developers around the world
about how to load MySQL data into the DataGridView Windows control. These
questions have been sent to me by e-mail (ebonat@evisualwww.com) or have been
posted at www.vbmysql.com website forum. In fact, I would like to invite you to
register and participate in our discuss forum. At this time, Im in charge of keeping
this website alive and responding all your MySQL/VB (VB 6.0 and VB.NET 2005)
related questions. In general all of the developers knew how to load the data by
using the DataSet or DataView ADO.NET objects. Most of the questions were about
the DataGridView format and data search after the grid was loaded. For some
reason(s) all of them were using dynamic SQL instead of stored procedures or
functions. Its very hard for me to believe that we still have developers up there
doing dynamic (embedding) or/and parameterized SQL programming in their
applications after MySQL AB Corporation released MySQL server version 5.0 with
stored procedures, functions, triggers and views database objects development. I
have made the decision to use stored procedures in this article to show them how
easy is to develop and call them in VB.NET 2005. I developed these stored
procedures using Toad for MySQL Freeware 3.0.0 freeware version from Quest
Software, Inc. In my experience, Toad for MySQL is a powerful database
management tool used to design and develop MySQL database objects like stored
procedures, functions, triggers and views. In my previous article MySQL Data
Loading with Lookup Tables, I show how to execute stored procedures in MySQL
5.0/VB.NET 2005 environment. Feel free to read the article and download the source

code to apply in your real production applications.


In Windows database applications the data gets loaded in the load event of the
form. Just in case, you need to be careful when to use this event to load the data as
you dont want to load a lot of data that it may slow down your form. I created a
simple solution project in VB.NET 2005 with a form represented in Figure 1. This
form named SearchForm contains a DataGridView with the contact info and a
Contact Name TextBox entry to search for it.

Figure 1: MySQL data load and search form


Listing 1 shows the load event of the Form SearchForm where the procedure SearchFormLoad()
is called.
Private Sub

SearchForm_Load(ByVal sender As System.Object, _


ByVal e As System.EventArgs) _
Handles MyBase.Load
Call SearchFormLoad()
End Sub

Listing 1: Load event of the form SearchForm


The code of the procedure SearchFormLoad() is shown in Listing 2. In this procedure the
ADO.NET Connection String (Server=xxx;Database=xxx;Uid=xxx;Pwd=xxx;) is passed as a
constructor to the class SearchClass (Listing 3). Just a reminder that this Connection String value
is defined and stored in the app.config file as I explained in the article Define and Store MySQL
ADO Connection String in VB.NET 2005. The Using statement creates and destroys the
instance of this class SearchObject. The procedure DataLoadingSearching() (Listing 4) is calling

by passing the DataGridView and the record count variable by reference. If an error does not
occurred the record count value is shown in the TextBox CountTextBox.
Private Sub SearchFormLoad()
Cursor = Cursors.WaitCursor
Try
Using SearchObject As New SearchClass(mMySQLConnectionString)
Call SearchObject.DataLoadingSearching(SearchDataGridView, _
mRecordCountInt32, _
mErrorMessageString)
If IsNothing(mErrorMessageString) Then
CountTextBox.Text = FormatNumber(mRecordCountInt32.ToString,
0)
Else
MessageBox.Show(mErrorMessageString, _
Me.Text, _
MessageBoxButtons.OK, _
MessageBoxIcon.Error)
End If
TextBoxName.Focus()
End Using
Catch exError As Exception
MessageBox.Show(exError.Message)
End Try
Cursor = Cursors.Default
End Sub

Listing 2: Procedure SearchFormLoad() for loading the data into the DataGridView
SearchDataGridView
Listing 3 shows the classes SearchClass and ObjectDisposeClass. Both classes are defined in the
Namespace SearchLibrary with MySqlClient imported library from Connector/NET 5.0.8. As
you can see the class ObjectDisposeClass implements the IDisposable interface to release
unmanaged resources created by class SearchClass. This implementation needs to be inherited by
the class SearchClass so the Using statement can be used properly. The parameterized contractor
has been included to store the ADO.NET Connection String mMySQLConnectionString as I
explained before.
Imports MySql.Data.MySqlClient
Namespace SearchLibrary
Public Class SearchClass
Inherits ObjectDisposeClass
Private mDataView As DataView
Private mMySQLConnectionString As String
Public Sub New(ByVal pMySQLConnectionString As String)
mMySQLConnectionString = pMySQLConnectionString
End Sub
End Class
Public Class ObjectDisposeClass
Implements IDisposable
Private disposedValue As Boolean = False
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then

If disposing Then
' TODO: free managed resources when explicitly called
End If
' TODO: free shared unmanaged resources
End If
Me.disposedValue = True
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
End Class
End Namespace

Listing 3: SearchClass and ObjectDisposeClass classes code


Listing 4 shows the overloaded procedure DataLoadingSearching() code. This is the main
procedure that formats and loads the contact name data into the DataGridView. The Using
statement is used for the following ADO.NET objects: Connection object mMySqlConnection,
Command object mMySqlCommand, DataAdapter object mMySqlDataAdapter and DataSet
object mDataSet. The command text property of the Command object is defined by the user
stored procedure `usp_select_all_data` (Listing 5). The Command object mMySqlCommand is
passed to the DataAdapter object mMySqlDataAdapter as a contractor that fills the DataSet
object mDataSet. The DataView object mDataView was created by using the Tables property of
the mDataSet. This DataView mDataView is the required object to load the DataGridView with
data by assigned it to the DataSource property. As you can see I did not use any dynamic or
parameterized SQL statement to set the command text property.
In Microsoft SQL Server 2005 and Oracle 10g, the stored procedures are precompiled SQL
statements in the database engine as a single unit of code. They are parsed and optimized when
they are first executed, and a compiled version of the stored procedure (execution plan) remains
in memory cache for later use. This results in tremendous application performance boosts. In
MySQL 5.0 database engine the stored procedures are recompiled each time when a connection
is made to the database. There is no global stored procedure compile cache (execution plan) on
the database server. I believe in future releases of MySQL we will see this important
implementation. In my sixteen years of experience developing database business applications for
many clients, I have found the following three main benefits of stored procedures (functions and
triggers) implementation:

Improve application performance by reducing network traffic

Provide a single tier of business rules development and maintenance

Enhance application security by reducing SQL injection attacks

I understand that development MySQL stored procedures, functions and triggers requires a good
knowledge of the SQL:2003 programming language. As a developer, its your responsibility to
learn this language and provide for your clients with the best of business applications
development. I cant image being hired today as a IT Application Developer and dont know how
to develop stored procedures, functions and triggers in MySQL 5.0 (SQL:2003), Oracle 10g
(PL/SQL) or MS SQL Server 2005 (T-SQL). Remember every business application that you
build for a client your name is behind it. So, always do the best programming practice you can
provide, even if you need to spend a lot time leaning out site the client environment. In my
particular case, in 2002 I learned VB.NET from 4:00 am to 8:00 am just a friendly thought. As
I said in my article MySQL Data Loading with Lookup Tables, a good starting point could be
reading a book published in 2006 by O'Reilly Media, Inc., ISBN: 0-596-10089-2, MySQL
Stored Procedure Programming by Guy Harrison and Steven Feuerstein. I highly recommend
reading this book for any Windows or Internet web application development with MySQL 5.0
database engine.
Public Overloads Sub DataLoadingSearching(ByRef pDataGridViewControl As
DataGridView, _
ByRef pRecordCountInt32 As Int32, _
ByRef pErrorMessageString As String)
Try
Using mMySqlConnection As New MySqlConnection(mMySQLConnectionString)
mMySqlConnection.Open()
Using mMySqlCommand As New MySqlCommand
With mMySqlCommand
.Connection = mMySqlConnection
.CommandType = CommandType.StoredProcedure
.CommandText = "usp_select_all_data"
End With
Using mMySqlDataAdapter As New MySqlDataAdapter(mMySqlCommand)
Using mDataSet As New DataSet
mDataSet.Clear()
mMySqlDataAdapter.Fill(mDataSet, "data")
mDataView = New DataView
mDataView.Table = mDataSet.Tables("data")
pRecordCountInt32 = mDataView.Count
End Using
End Using
End Using
End Using
Call DataGridViewFormat(pDataGridViewControl)
With pDataGridViewControl
.DataSource = mDataView
.AutoResizeRows()
End With
Catch exError As Exception
pErrorMessageString = exError.Message
End Try
End Sub

Listing 4: Overloaded procedure DataLoadingSearching() (data load) with user stored


procedure `usp_select_all_data`

DROP PROCEDURE IF EXISTS `vwww`.`usp_select_all_data`;


CREATE PROCEDURE `usp_select_all_data`()
BEGIN
SELECT `data`.`id`,
`data`.`name`,`data`.`birthdate`,`data`.`numberofchildren`,`data`.`married`,
`data`.`computerpc`,`data`.`computerlaptop`, `data`.`salary`,
`data`.`comment`
FROM `data`
ORDER BY `data`.`name`;
END;

Listing 5: User stored procedure `usp_select_all_data` to select all columns and data from
table `data`
Listing 6 shows the procedure DataLoading_DynamicSQL() with dynamic SQL statement SQL
"SELECT data.id, data.name, data.birthdate, data.numberofchildren, data.married,
data.computerpc,data.computerlaptop, data.salary, data.comment FROM data ORDER BY
data.name". As you can see the command type property of the Command object
mMySqlCommand is set to Text. I have provided this code so you can see the real different
between the procedures DataLoadingSearching() and DataLoading_DynamicSQL() (Listing 4
and 6).
Public Sub DataLoading_DynamicSQL(ByRef pDataGridViewControl As DataGridView,
_
ByRef pRecordCountInt32 As Int32, _
ByRef pErrorMessageString As String)
Dim SQLString As String
Try
SQLString = "SELECT data.id, data.name, data.birthdate,
data.numberofchildren,
data.married, data.computerpc,data.computerlaptop,
data.salary,
data.comment FROM data ORDER BY data.name"
Using mMySqlConnection As New MySqlConnection(mMySQLConnectionString)
mMySqlConnection.Open()
Using mMySqlCommand As New MySqlCommand
With mMySqlCommand
.Connection = mMySqlConnection
.CommandType = CommandType.Text
.CommandText = SQLString
End With
Using mMySqlDataAdapter As New MySqlDataAdapter(mMySqlCommand)
Using mDataSet As New DataSet
mDataSet.Clear()
mMySqlDataAdapter.Fill(mDataSet, "data")
mDataView = New DataView
mDataView.Table = mDataSet.Tables("data")
pRecordCountInt32 = mDataView.Count
End Using
End Using
End Using
End Using
Call DataGridViewFormat(pDataGridViewControl)
With pDataGridViewControl

.DataSource = mDataView
.AutoResizeRows()
End With
Catch exError As Exception
pErrorMessageString = exError.Message
End Try
End Sub

Listing 6: Procedure DataLoading_DynamicSQL() with dynamic SQL "SELECT data.id,


data.name, data.birthdate, data.numberofchildren, data.married,
data.computerpc,data.computerlaptop, data.salary, data.comment FROM data ORDER
BY data.name"
Before the data is loaded into the DataGridView, it must be formatted properly according to the
column names and data types defined in the SQL SELECT statement in the user stored procedure
`usp_select_all_data` (Listing 5). This statement selects all columns form the table `data` defined
in Listing 7.
DROP TABLE IF EXISTS `vwww`.`data`
CREATE TABLE `data`(
`id` int(20) NOT NULL auto_increment,
`name` varchar(50) NOT NULL,
`birthdate` date NOT NULL,
`numberofchildren` smallint(20) default NULL,
`married` tinyint(1) default '0',
`computerpc` tinyint(1) default '0',
`computerlaptop` tinyint(1) default '0',
`salary` double(10,2) default NULL,
`comment` varchar(300) default NULL,
PRIMARY KEY (`id`),
KEY `ix1_data` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Listing 7: Table `data` definition


The procedure DataGridViewFormat() formats the DataGridView as shown in Listing 8.One
particular thing to consider is that the first formatted column represents the `id` field and it
should be hidden from the end-user. We can do that by setting the Visible property of the column
to False after the column is formatted.
Private Sub DataGridViewFormat(ByRef pDataGridViewControl As DataGridView)
With pDataGridViewControl
.AlternatingRowsDefaultCellStyle.BackColor = Color.LightCyan
.SelectionMode = DataGridViewSelectionMode.FullRowSelect
.AllowUserToOrderColumns = True
.AllowUserToDeleteRows = False
.AllowUserToAddRows = False
.ReadOnly = True
.MultiSelect = False
.Columns.Clear()
Dim ColumnContactID As New DataGridViewTextBoxColumn
With ColumnContactID
.DataPropertyName = "id"

.Name = "id"
.HeaderText = "ID"
.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader
.DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleLeft
End With
.Columns.Add(ColumnContactID)
ColumnContactID.Visible = False
Dim ColumnContactName As New DataGridViewTextBoxColumn
With ColumnContactName
.DataPropertyName = "name"
.Name = "name"
.HeaderText = "Contact Name"
.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader
.DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleLeft
End With
.Columns.Add(ColumnContactName)
Dim ColumnBirthDate As New DataGridViewTextBoxColumn
With ColumnBirthDate
.DataPropertyName = "birthdate"
.Name = "birthdate"
.HeaderText = "Birth Date"
.DefaultCellStyle.Format = "d"
.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader
.DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleCenter
End With
.Columns.Add(ColumnBirthDate)
Dim ColumnNoOfChildren As New DataGridViewTextBoxColumn
With ColumnNoOfChildren
.DataPropertyName = numberofchildren
.Name = "numberofchildren"
.HeaderText = "No Of Children"
.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells
.DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleCenter
End With
.Columns.Add(ColumnNoOfChildren)
Dim ColumnMarried As New DataGridViewCheckBoxColumn
With ColumnMarried
.DataPropertyName = "married"
.Name = married
.HeaderText = "Married"
.ThreeState = True
.TrueValue = 1
.FalseValue = 0
.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader
.DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleCenter
End With
.Columns.Add(ColumnMarried)
Dim ColumnComputerPC As New DataGridViewCheckBoxColumn
With ColumnComputerPC
.DataPropertyName = "computerpc"
.Name = "computerpc"
.HeaderText = "PC"

.ThreeState = True
.TrueValue = 1
.FalseValue = 0
.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader
.DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleCenter
End With
.Columns.Add(ColumnComputerPC)
Dim ColumnComputerLaptop As New DataGridViewCheckBoxColumn
With ColumnComputerLaptop
.DataPropertyName = "computerlaptop"
.Name = "computerlaptop"
.HeaderText = "Laptop"
.ThreeState = True
.TrueValue = 1
.FalseValue = 0
.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells
.DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleCenter
End With
.Columns.Add(ColumnComputerLaptop)
Dim ColumnSalary As New DataGridViewTextBoxColumn
With ColumnSalary
.DataPropertyName = "salary"
.Name = "salary"
.HeaderText = "Monthly Salary"
.DefaultCellStyle.Format = "c"
.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells
.DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight
End With
.Columns.Add(ColumnSalary)
Dim ColumnComment As New DataGridViewTextBoxColumn
With ColumnComment
.DataPropertyName = "comment"
.Name = "comment"
.HeaderText = "Comment"
.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells
.DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleLeft
.DefaultCellStyle.NullValue = "None"
End With
.Columns.Add(ColumnComment)
End With
End Sub

Listing 8: Procedure DataGridViewFormat() for formatting the DataGridView


SearchDataGridView
MySQL Data Search Using Stored Procedures

Searching for data in any Windows or Internet web application is a must. I havent found any
business application without this requirement. You must find out the best way to implement this
requirement for that specific application. A common request from clients is for search functions
to be flexible and fast. Because of that, the first idea that comes to my head is stored procedures

implementation. As I explained before stored procedures improve application performance by


reducing network traffic. To show you this approach the Search button was created (Figure 2). As
you can see, after the letter c was entered in the Contact Name TextBox, the end-user clicks on
Search button and two records were found. Lets look at the code implementation.

Figure 2: MySQL data load and search form


Listing 9 shows the code of the click event of the Search button. First of all, before
searching for any Contact Name, the end-user needs to enter a string value. To
check for it the Length property was used. If the Length of the Contact Name
TextBox is equal to zero, a message will show requiring an entry. As you can see
from Listing 9 the overloaded procedure DataLoadingSearching() (Listing 10)
provides the searching code by passing by value a Contact Name
ContactNameString. Lets look closer at this procedure.
Private Sub SearchButton_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs)
Handles SearchButton.Click
Cursor = Cursors.WaitCursor
Dim ContactNameString As String
Try
ContactNameString = TextBoxName.Text.Trim
If ContactNameString.Length = 0 Then
Cursor = Cursors.Default
MessageBox.Show("Contact Name is required.", _
Me.Text, _
MessageBoxButtons.OK, _
MessageBoxIcon.Stop)
TextBoxName.Focus()
Exit Sub
End If
Using SearchObject As New SearchClass(mMySQLConnectionString)

Call SearchObject.DataLoadingSearching(SearchDataGridView, _
mRecordCountInt32, _
ContactNameString, _
mErrorMessageString)
If IsNothing(mErrorMessageString) Then
CountTextBox.Text = FormatNumber(mRecordCountInt32.ToString,
0)

If mRecordCountInt32 > 0 Then


SearchDataGridView.Focus()
Else
Cursor = Cursors.Default
MessageBox.Show("Contact Name " & ContactNameString & _
" was not found. Try again.", _
Me.Text, _
MessageBoxButtons.OK, _
MessageBoxIcon.Error)
TextBoxName.Focus()
TextBoxName.SelectAll()
End If

Else

MessageBox.Show(mErrorMessageString, _
Me.Text, _
MessageBoxButtons.OK, _
MessageBoxIcon.Error)
TextBoxName.Focus()
End If
End Using
Catch exError As Exception
MessageBox.Show(exError.Message, _
Me.Text, _
MessageBoxButtons.OK, _
MessageBoxIcon.Error)
End Try
Cursor = Cursors.Default
End Sub

Listing 9: Click event of the Search button


The overloaded procedure DataLoadingSearching() shown in Listing 10 provides the search by
Contact Name. The main idea of this procedure, compare to the first one, lies in the execution of
the user stored procedure `usp_find_name` with an input parameter par_contact_name (Listing
11). In the WHERE clause of the SELECT statement the LIKE comparison with the CONCAT()
string function have been included. The combination of both with a wildcard character % at the
beginning and the end of the parameter par_contact_name allows us to search for any Contact
Name containing the passing string parameter pContactNameString. In VB.NET 2005 to pass a
parameter to the stored procedure a MySqlParameter object NameMySqlParameter needs to be
created and added to the parameters collection. Five properties of this parameter object need to
be setup properly: ParameterName, Direction, MySqlDbType, Size and Value. The data type
MySqlDbType and the size need to be defined according with the column definition in the table
`data`. This is common mistake many developers make when these parameter settings do not
correspond with the column definition (data type and size). After this parameter has been added
to the parameter collection and the Command object mMySqlCommand is passed as a

constructor to the DataAdapter object mMySqlDataAdapter, the DataView object mDataView is


created in the same way that we explained before in Listing 4.
Public Overloads Sub DataLoadingSearching(ByRef pDataGridViewControl As
DataGridView, _
ByRef pRecordCountInt32 As Int32, _
ByVal pContactNameString As String,
_
ByRef pErrorMessageString As String)
Dim NameMySqlParameter As New MySqlParameter
Try
Using mMySqlConnection As New MySqlConnection(mMySQLConnectionString)
mMySqlConnection.Open()
Using mMySqlCommand As New MySqlCommand
With mMySqlCommand
.Connection = mMySqlConnection
.CommandType = CommandType.StoredProcedure
.CommandText = "usp_find_name"
With NameMySqlParameter
.ParameterName = "?par_contact_name"
.Direction = ParameterDirection.Input
.MySqlDbType = MySqlDbType.VarChar
.Size = 50
.Value = pContactNameString
End With
.Parameters.Add(NameMySqlParameter)
End With
Using mMySqlDataAdapter As New MySqlDataAdapter(mMySqlCommand)
Using mDataSet As New DataSet
mDataSet.Clear()
mMySqlDataAdapter.Fill(mDataSet, "data")
mDataView = New DataView
mDataView.Table = mDataSet.Tables("data")
pRecordCountInt3 = mDataView.Count
End Using
End Using
End Using
Call DataGridViewFormat(pDataGridViewControl)
With pDataGridViewControl
.DataSource = mDataView
.AutoResizeRows()
End With
End Using
Catch exError As Exception
pErrorMessageString = exError.Message
Finally
If Not IsNothing(NameMySqlParameter) Then
NameMySqlParameter = Nothing
End If
End Try
End Sub

Listing 10: Overloaded procedure DataLoadingSearching() (data search) with stored


procedure `usp_find_name`
DROP PROCEDURE IF EXISTS `vwww`.`usp_find_name`;

CREATE PROCEDURE `usp_find_name`(


IN par_contact_name VARCHAR(50)
)
BEGIN
SELECT `data`.`id`,
`data`.`name`,`data`.`birthdate`,`data`.`numberofchildren`,`data`.`married`,
`data`.`computerpc`,`data`.`computerlaptop`, `data`.`salary`,
`data`.`comment`
FROM `data`
WHERE `data`.`name` LIKE CONCAT('%',par_ contact _name,'%')
ORDER BY `data`.`name`;
END;

Listing 11: User stored procedure `usp_find_name` to search for Contact Name using LIKE
operator and string function CONCAT()
Listing 12 shows the procedure DataSearching_ DynamicSQL() using dynamic SQL statement
"SELECT data.id, data.name, data.birthdate, data.numberofchildren, data.married,
data.computerpc, data.computerlaptop, data.salary, data.comment FROM data WHERE
data.name LIKE CONCAT('%'," & "'" & pContactNameString & "'" & ",'%') ORDER BY
data.name". Comparing with procedure DataLoadingSearching() in Listing 10, the parameter
object NameMySqlParameter is not required because the Contact Name string value
pContactNameString is included in the dynamic SQL statement. Between procedures
DataLoadingSearching() and DataSearching_ DynamicSQL() you can see a quite big difference.
The procedure DataSearching_ DynamicSQL() looks more simple than procedure
DataLoadingSearching(). Whenever the program calls the procedure DataSearching_
DynamicSQL() the dynamic SQL statement needs to be compiled by the MySQL database
engine decreasing application performance by increasing network traffic. By the way, a very
good malicious SQL injection attack can look for your Contact Name data and I believe you
dont want that to happen. So, dynamic SQL implementation in your business database
applications is not a very good programming practice today. Here is what Wikipedia, The Free
Encyclopedia, says about SQL injection: SQL injection is a technique that exploits a security
vulnerability occurring in the database layer of an application. The vulnerability is present when
user input is either incorrectly filtered for string literal escape characters embedded in SQL
statements or user input is not strongly typed and thereby unexpectedly executed. It is in fact an
instance of a more general class of vulnerabilities that can occur whenever one programming or
scripting language is embedded inside another. Because of that I want you think twice if you
really need dynamic SQL implementation in your clients business applications.
Public Sub DataSearching_DynamicSQL(ByRef pDataGridViewControl As
DataGridView, _
ByRef pRecordCountInt32 As Int32, _
ByVal pContactNameString As String, _
ByRef pErrorMessageString As String)
Dim SQLString As String
Try
SQLString = "SELECT data.id, data.name, data.birthdate,
data.numberofchildren,

data.married, data.computerpc, data.computerlaptop,


data.salary, data.comment
FROM data WHERE data.name LIKE CONCAT('%'," & "'" &
pContactNameString & "'" & ",'%') ORDER BY data.name"
Using mMySqlConnection As New MySqlConnection(mMySQLConnectionString)
mMySqlConnection.Open()
Using mMySqlCommand As New MySqlCommand
With mMySqlCommand
.Connection = mMySqlConnection
.CommandType = CommandType.Text
.CommandText = SQLString
End With
Using mMySqlDataAdapter As New MySqlDataAdapter(mMySqlCommand)
Using mDataSet As New DataSet
mDataSet.Clear()
mMySqlDataAdapter.Fill(mDataSet, "data")
mDataView = New DataView
mDataView.Table = mDataSet.Tables("data")
pRecordCountInt32 = mDataView.Count
End Using
End Using
End Using
Call DataGridViewFormat(pDataGridViewControl)
With pDataGridViewControl
.DataSource = mDataView
.AutoResizeRows()
End With
End Using
Catch exError As Exception
pErrorMessageString = exError.Message
End Try
End Sub

Listing 12: Procedure DataSearching_ DynamicSQL() with dynamic SQL "SELECT


data.id, data.name, data.birthdate, data.numberofchildren, data.married,
data.computerpc, data.computerlaptop, data.salary, data.comment FROM data WHERE
data.name LIKE CONCAT('%'," & "'" & pContactNameString & "'" & ",'%') ORDER
BY data.name"
Before finishing this topic I want to explain why I find implementing stored procedures,
functions and triggers in my clients business applications to be very useful. The first thing that
comes to my mind is where and how to implement the clients business rules so that I dont need
to compile and deploy my application again and again. The answer to this is, code location and
organization, and of course, application upgrade and maintenance. I need to find an effective and
unique location to develop and maintain these rules easily. How about in the database engine? In
general, the database engine is a separated block (tier) of any normal Windows business
application. So if, in the future, I implement the business rules in the database engine tier, then
any possible upgrades will not require application compilation and deployment to the clients PC.
This is possible if the upgrade does not require changing the public interface of the stored
procedures (parameters name and data types definition). This covers the third benefit of stored
procedures, functions and triggers development. Referring to the code, lets look at a simple

example. As we saw before, Listing 11 shows the user stored procedure `usp_find_name` with
LIKE operator and string function CONCAT(). So far this stored procedure can find any Contact
Name record(s) if the input parameter par_contact_name value is anywhere inside the
`data`.`name` column. A possible upgrade could be useful to finding any Contact Name record(s)
that starts with any parameter par_contact_name value. The implementation of this upgrade is
very simple. It is done by removing the first wildcard character % in the CONCAT() string
function as show in Listing 13. At this point the upgrade was made to the stored procedure code,
not to the application code. So, because of that the application compilation and deployment back
to the clients PC is not necessary. The point Im trying to make is that implementing clients
business rules at the database tier allows you to locate, upgrade and maintain them easily. By the
way, I have no previous information of any database engine slow down process or resource
problems because stored procedures overhead implementation on Oracle, SQL Server or IBM
DB2 servers.
DROP PROCEDURE IF EXISTS `vwww`.`usp_find_name`;
CREATE PROCEDURE `usp_find_name`(
IN par_contact_name VARCHAR(50)
)
BEGIN
SELECT `data`.`id`,
`data`.`name`,`data`.`birthdate`,`data`.`numberofchildren`,`data`.`married`,
`data`.`computerpc`,`data`.`computerlaptop`, `data`.`salary`,
`data`.`comment`
FROM `data`
WHERE `data`.`name` LIKE CONCAT(par_ contact _name,'%')
ORDER BY `data`.`name`;
END;

Listing 13: User stored procedure to search for Contact Name using LIKE operator and
string function CONCAT()
An example of MySQL data searching using the stored procedure `usp_find_name` (Listing 13)
is shown in Figure 3. As you can see two records were found searching by letter m at the
beginning of the Contact Name data column.

Figure 3: MySQL data load and search form


MySQL Data Search Using DataView Object

Another way to search for MySQL data is by using Microsoft DataView ADO.NET object. Two
main properties of the DataView object are required for data searching: RowFilter() and
RowStateFilter(). The property RowFilter() gets or sets the expression used to filter which rows
are viewed in the DataView. The other one property RowStateFilter() gets or sets the row state
filter used in the DataView. Listing 14 shows the procedure DataSearching_DataView() using the
stored procedure `usp_select_all_data` for data selection and the DataView object for searching.
As you can see the filter string value FilterSQLString = "name LIKE " & "'%" &
pContactNameString & "%'" does not include the CONCAT() MySQL string function. This
function is not part of the Microsoft DataView ADO.NET object. if you include the the
CONCAT() function, an error will occurs saying: The expression contains undefined function
call CONCAT(). The property RowStateFilter() is set to the filter string and the
RowStateFilter() is set to return current rows state. I did not notice any speed differences
between stored procedures and DataView object implementation for MySQL data searching. As
you may have already found out Im a hardcode programmer. Here one of my programming
principles: I control the code and objects, the code and objects cant control me. Considering
that I prefer to use stored procedures approach for MySQL data searching, because I have full
control of the application code.
Public Sub DataSearching_DataView(ByRef
_
ByRef
ByVal
ByRef
Dim FilterSQLString As String

pDataGridViewControl As DataGridView,
pRecordCountInt32 As Int32, _
pContactNameString As String, _
pErrorMessageString As String)

Try

Using mMySqlConnection As New MySqlConnection(mMySQLConnectionString)


mMySqlConnection.Open()
Using mMySqlCommand As New MySqlCommand
With mMySqlCommand
.Connection = mMySqlConnection
.CommandType = CommandType.StoredProcedure
.CommandText = "usp_select_all_data"
End With
Using mMySqlDataAdapter As New MySqlDataAdapter(mMySqlCommand)
Using mDataSet As New DataSet
mDataSet.Clear()
mMySqlDataAdapter.Fill(mDataSet, "data")
mDataView = New DataView
mDataView.Table = mDataSet.Tables("data")
'An error occurred: The expression contains undefined
function call CONCAT()."
'FilterSQLString = "name LIKE CONCAT('%'," & "'" &
pContactNameString & "'" & ",'%')"
FilterSQLString = "name LIKE " & "'%" &
pContactNameString & "%'"
With mDataView
.RowFilter = FilterSQLString
.RowStateFilter = DataViewRowState.CurrentRows
.Sort = "name"
pRecordCountInt32 = .Count
End With
End Using
End Using
End Using
Call DataGridViewFormat(pDataGridViewControl)
With pDataGridViewControl
.DataSource = mDataView
.AutoResizeRows()
End With
End Using
Catch exError As Exception
pErrorMessageString = exError.Message
End Try
End Sub

Listing 14: Procedure DataSearching_DataView() for searching with DataView object


mDataView
Listing 15 shows the code of the click event of the Refresh button. The procedure
SearchFormLoad() is called again to refresh the data from the table `data` and the Contact Name
TextBox is clear to start a new search if necessary.
Private Sub RefreshButton_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles RefreshButton.Click
Call SearchFormLoad()
With TextBoxName
.Clear()
.Focus()

End With
End Sub

Listing 15: Click event of the Refresh button


Conclusions

Based on the presented here info the following conclusions could be made:
1. MySQL stored procedures, functions and triggers objects development is one of the best
programming practices for Windows database application implementation today. These objects
provide the following three main benefits:
1.1 Improve application performance by reducing network traffic
1.2 Provide a single tier of business rules development and maintenance
1.3 Enhance application security by reducing SQL injection attacks
2. MySQL data load using the DataGridView control requires a properly columns format based
on table definition.
3. MySQL data search using stored procedures in the database tier provides a flexible code
location and organization for application upgrades and maintenance.
4 .The ADO.NET DataView object can provide a complete implementation of MySQL data load
and search for Windows database applications development.