You are on page 1of 165

ADO.

NET With MySQL and MSDE


http://www.functionx.com/mysqlnet/index.htm

Page |2

ADO.NET With MySQL and MSDE


Requirements
Introduction
The lessons on this site assume that you know C# but you don't need to know SQL (in Lesson 3, we will start introducing SQL as if you don't know it). To create the applications in our lessons, you will also need some additional libraries and a C# programming environment. Everything we will use in the lessons is freely available.

The .NET Framework


To create graphical applications of these lessons, you will need the .NET Framework. You can download it free from the http://www.asp.net web site. In most cases, it may already be installed in your computer. Otherwise, after downloading, you can following setup to install it.

MySQL
TO develop graphical MySQL applications, you must first install MySQL, which you can freely download from the http://www.mysql.com web site. After downloading it, you should install it. After installing MySQL, if you want to create .NET applications, you should install the MySQL Connector/Net driver that you can also download from the MySQL web site. Like that of MySQL, the installation of the MySQL Connector/Net is particularly easy.

MSDE
If you are planning to create MS SQL Server databases, you can install either Microsoft SQL Server or the Microsoft SQL Server 2000 Desktop Engine (MSDE). Both are freely available from the http://www.microsoft.com web site. The freely available MS SQL Server is in its Developer version as a trial version while the MSDE is completely free.

#develop
To create Windows graphical applications, you will need a C# compiler. If had installed the full version of the .NET Framework, it includes a free C# compiler. The .NET Framework and the freely available C# compiler are enough to create any type of application but you would be compiling your application from the Command Prompt. If you want to work visually, then you will need a programming environment that can assist you. To continue with free software, we will use #develop that you can freely download.

3|Page

Page |4

Connection to the MySQL Server


Using ADO.NET
Introduction to ADO.NET
ADO.NET is a group of libraries used to create powerful databases using various sources that include Microsoft SQL Server, Microsoft Access, Oracle, XML, etc. ADO.NET relies on the .NET Framework's various classes to process requests and perform the transition between a database system and the user. The operations are typically handled through the DataSet class. While ADO.NET is the concept of creating and managing database systems, the DataSet class serves as an intermediary between the database engine and the user interface, namely the Windows controls that the user uses to interact with the computer. Still, remember that a DataSet object is used to manage lists, any lists, not just those created using database engines.

Using the MySQL Connector/Net


To support the .NET Framework applications, MySQL provides a series of classes in the MySQL Connector/Net. To use these classes, you should (must) reference the MySql.Data.dll library. The classes used by the MySQL database engine are defined in the MySql.Data namespace.

Connection to a MySQL Database


Introduction
The MySQL Connector/Net allows you to create a graphical Windows application that is databased. When your application runs, it must connect to a MySQL database. To support this connection, you can use the MySqlConnection class that is defined in the MySql.Data.MySqlClient namespace. Before using this class, you can first include that namespace in your file. To connect to a database, you can declare a MySqlConnection variable using one of its two constructors. The default constructor allows you to declare the variable without specifying how the connection would be carried. The second constructor takes as argument a String value. Its syntax is: public MySqlConnection(string connectionString); If you want, you can first create the string that would be used to handle the connection, then pass that string to the second construction. This would be done as follows: private void btnConnect_Click(object sender, System.EventArgs e) { string strConnection = ""; MySqlConnection conSQL = new MySqlConnection(strConnection); } You can also directly create the necessary (but appropriate) string in the second constructor when declaring the variable: private void btnConnect_Click(object sender, System.EventArgs e) { MySqlConnection conSQL = new MySqlConnection(""); }

5|Page

If you prefer to use the default constructor, you can first define a string value. To pass it to the default constructor, the MySqlConnection class is equipped with a property called ConnectionString that is of type string. You would use it as follows: private void btnConnect_Click(object sender, System.EventArgs e) { string strConnection = ""; MySqlConnection conServer = new MySqlConnection(); } conServer.ConnectionString = strConnection; To use a MySqlConnection object, you must provide various pieces of information, packaged as one and made available to the variable. These pieces are joined into a string but are separated from each other with a semi-colon ";". Each piece appears as a Key=Value format. In our lesson, we will refer to each of these pieces (Key=Value) as an attribute of the connection string. When joined, these attributes appear as follows: Key1=Value1;Key2=Value2;Key_n=Value_n Anything that part of this string is not case-sensitive. Remember that this whole ensemble is either passed as a string to the second constructor: MySqlConnection conServer = new MySqlConnection("Key1=Value1;Key2=Value2;Key_n=Value_n"); or assigned as a string to the MySqlConnection.ConnectionString property: MySqlConnection conServer = new MySqlConnection(); string strConnection = "Key1=Value1;Key2=Value2;Key_n=Value_n"; conServer.ConnectionString = strConnection; How you create these attributes depends on the type of computer you are connecting to, whether you are connecting to a database, what level the security you would use (or need), etc. There are various of these attributes, some of them are always required, some of them are usually optional, and some others depend on the circumstances.

The Source of Data


To establish a connection, you must specify the computer you are connecting to, that has MySQL installed. To indicate the computer you are connecting to, use the Data Source, the DataSource, the Host, the Server, the Addr, the Address, or the Network Address attribute of the connection string. If you are connecting to a local database (installed in the same computer where the application is running), you can omit specifying the name of the computer. Otherwise, you can assign localhost to this attribute. Here is an example private void btnLoad_Click(object sender, System.EventArgs e) { MySqlConnection cnnVideos = new MySqlConnection("Data Source=localhost;"); }

The Database
If you have already created a database you want to connect to, you can specify it in your connection string. If you are not trying to connect to a particular database, you don't need to specify one. To specify the database you want to connect to, the connection string includes an attribute named Database or Initial Catalog. This attribute allows you to specify the name of the database you are connecting to, if any. If you are connecting to an existing database, assign its

Page |6

name to this attribute. If you are not connecting to a database, you can omit this attribute. Alternatively, you can assign nothing to this attribute. Here is an example: MySqlConnection conDatabase = new MySqlConnection("Address=localhost;Database=; "); Another alternative is to assign an empty, single-quoted, string to this attribute. Here is an example: MySqlConnection conDatabase = new MySqlConnection("Network Address=localhost;Initial Catalog=''; "); As mentioned above, the Database or Initial Catalog attribute is optional, especially if you are only connecting to the computer and not to a specific database.

Security
An important aspect of establishing a connection to a computer is security. Even if you are developing an application that would be used on a standalone computer, you must take care of this issue. The security referred to in this attribute has to do with the connection, not how to protect your database. To support security, the connection string of the MySqlConnection class includes an attribute called Persist Security Info that can have a value of true, false, yes, no. If you are establishing a trusted or simple connection that doesn't need to be verified, you can assign a value of true. Here is an example: private void btnLoad_Click(object sender, System.EventArgs e) { MySqlConnection cnnVideos = new MySqlConnection( "Network Address=localhost;Initial Catalog='Famille';Persist Security Info=true;"); } If the connection exists already, to find it out, remember that you can can get the value of the MySqlConnection.ConnectionString property. If you had set the Persist Security Info attribute to true, the person getting this information may see the username and the password that were used to establish the connection. If you don't want this information available, you should set this attribute to false or no. If you do this, when somebody inquires about the connection string, he or she would not get the username and the password.

The Username
If you are connecting to a MySQL server and you want to apply authentication, you can specific a username and a password. To specify the user name, use the User Id, the Uid, the User name, or the Username attribute and assign it a valid MySQL login username. Here is an example: MySqlConnection conDatabase = new MySqlConnection("Server=localhost;Persist Security Info=no;User ID=MammaMia");

The Password
When using authentication during connection, after specifying (if you had specified) the username, you must also provide a password to complete the authentication. To specify the password, you can user either the PASSWORD or the PWD (remember that the attributes are not case-sensitive) attribute and assign it the exact password associated with the User Id, the Uid, the User name, or the Username attribute of the same connection string. Here is an example:

7|Page

private void btnLoad_Click(object sender, System.EventArgs e) { MySqlConnection cnnVideos = new MySqlConnection("Network Address=localhost;" + "Initial Catalog='Famille';" + "Persist Security Info=no;" + "User Name='root';" + "Password='R0gerMiLl@'"); }

Additional Attributes
There are various other attributes used in the connection string. They include Encrypt, Connection Timeout (or Connect Timeout), CharSet (or Character Set), Port, Protocol, Logging, Allow Batch, Shared Memory Name, Allow Zero Datetime, Old Syntax (or OldSyntax), Connection Lifetime, Max Pool Size, Min Pool Size, Pooling, and Pipe Name (or Pipe). After creating the connection string, when the application executes, the compiler would "scan" the string to validate each key=value section. If it finds an unknown Key, an unknown value, or an invalid combination of key=value, it would throw an ArgumentException exception and the connection cannot be established.

Operations on a MySQL Server Database Connection


Opening a Connection
After creating a connection string, to apply it and actually establish the connection, you must call the MySqlConnection.Open(). Its syntax is: public void Open(); As you can see, this method doesn't take any argument. The MySqlConnection object that calls it is responsible to get the connection string ready. If the connection fails, the compiler would throw a MySqlException exception. If the connection string doesn't contain a data source or server, the compiler would throw an InvalidOperationException exception.

Closing a Connection
After using a connection and getting the necessary information from it, you should terminate it. To close a connection, you can call the MySqlConnection.Close() method. Its syntax is: public void Close(); This method is simply called to close the current connection. While you should avoid calling the Open() method more than once if a connection is already opened, you can call the Close() method more than once.

Page |8

Introduction to SQL and ADO.NET

Actions on a MySQL Database


Introduction
In the previous lesson, we learned how to establish a connecting to a server. After establishing a connection, if you are successful, the database system becomes available to you and you can take actions, such as creating a database and/or manipulating data. An action you perform on the database server or on a database is carried by a object called a command. To support the various actions that you can perform on a MySQL server database, the MySQL Connector/Net provides the MySqlCommand class. To use it, you can declare a variable of type MySqlCommand using one of its constructors.

SQL on Command
The MySqlCommand class is equipped with four constructors. The default constructor allows you to initiate a command without specifying what action would be taken. The action to perform is created as a string statement. This action is represented by the MySqlCommand.CommandText property which is of type string. If you want to use the default constructor, you can then create a string that would carry the action to perform. Once the string is ready, you can assign it the CommandText property. This would be done as follow: MySqlCommand cmdSQL = new MySqlCommand(); string strCommandToExecute = "Blah Blah Blah"; cmdSQL.CommandText = strCommandToExecute; After creating the action that would be performed, you must specify what connection would carry it. To do this, you can first create a MySqlConnection object. To provide it to the command, the MySqlCommand class is equipped with a Connection property that is of type MySqlConnection. After creating a MySqlConnection object, to provide it to the command, you can assign it to the MySqlCommand.Connection property. Instead of declaring a MySqlCommand variable and the command text separately, as an alternative, you can define the command text when declaring the MySqlCommand variable. To do this, you can use the second constructor of the MySqlCommand class. The syntax of this constructor is: public MySqlCommand(string cmdText); Once again, after using this constructor, you must specify what connection would carry the action. To do this, you can assign a MySqlConnection object to the Connection property of your MySqlCommand. Instead of assigning the MySqlConnection to the SqlCommand.Connection property, you can specify what connection would carry the action at the same time you are creating the command. To specify the connection when declaring the MySqlCommand variable, you can use the third constructor of this class. Its syntax is: public MySqlCommand(string cmdText, MySqlConnection connection); The second argument to this constructor is an established connection you would have defined. If you had initiated the action using the default constructor of the MySqlCommand class, you

9|Page

can assign a MySqlConnection object to the Connection property of the MySqlCommand class. In the next sections and future lessons, we will study the types of commands that would be carried.

Command Execution
After establishing a connection and specifying what command needs to be carried, you can execute it. To support this, the MySqlCommand class is equipped with the ExecuteNonQuery() method. Its syntax is: public int ExecuteNonQuery(); This method doesn't take any argument. The MySqlCommand object that calls it must have prepared a valid command. In future lessons, we will see that there are other ways a MySqlCommand object can execute commands.

Well, the Command Timed Out


In some cases, some actions take longer than others to execute. For this type of command, the compiler would keep trying to execute a command until successful. If there is a problem, this operation can take long or too long. You can specify how long the compiler should wait to try executing the command, again. The MySqlCommand.CommandTimeOut property allows you to specify the time to wait before trying to execute a command. The default value of this property is 30 (seconds). If you want a different value, assign it to your MySqlCommand variable.

The Type of Command


In this and the next few lessons, all of the commands we perform will be communicated as strings. When we study (stored) procedures, we will see other types of commands. To allow you to specify the type of command you want to perform, the MySqlCommand class is equipped with the CommandType property, which is based on the CommandType enumerator. The CommandType enumerator has three members: StoredProcedure, TableDirect, and Text. For a MySqlCommand object, the default value is Text.

The Structured Query Language


Introduction
The Structured Query Language, known as SQL, is a universal language used on various computer systems to create and manage databases. SQL can be pronounced Sequel or S. Q. L. In our lessons, we will consider the Sequel pronunciation. For this reason, the abbreviation will always be considered as a word, which would result in A SQL statement instead of "An SQL statement". Also, we will regularly write, The SQL instead of The SQL language, as the L already represents Language.

P a g e | 10

Like other non-platform specific languages such as C/C++, Pascal, or Java, the SQL you learn can be applied to various database systems. Although MySQL highly adheres to the SQL standards, it has some internal details that may not be applied to other database systems like Microsoft SQL Server, Oracle, Paradox, or Microsoft Access, etc; although they too fairly conform to the standard.

The SQL we will learn and use here is the one implemented in MySQL. In other words, we will assume that you are using MySQL as your platform for learning about databases. As a computer language, the SQL is used to give instructions to an internal program called an interpreter. As we will learn in various sections, you must make sure you give precise instructions. Unlike C# and XML, SQL is not case-sensitive. This means that the words CREATE, create, and Create mean the same thing. It is a tradition to write SQL's own words in uppercase. This helps to distinguish SQL instructions with the words you use for your database.

SQL Code at the Command Prompt


As we will learn in this and the other remaining lessons of this site, you use the SQL by writing statements. To do this, you can open the Command Prompt and write your code.

Programmatic SQL Code


When working in a Windows application, you can write the exact same code you would at the Command Prompt. Once your code is ready, you can pass it to a MySqlCommand object you would have created as we saw earlier. This would be done as follows: private void cmdLoad_Click(object sender, System.EventArgs e) { MySqlConnection conDatabase = new MySqlConnection("Data Source=localhost;Persist Security Info=yes;"); MySqlCommand cmdDatabase = new MySqlCommand(SQL Code, conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close(); } In this example, the SQL Code factor represents a SQL statement you would write and pass it as a string.

11 | P a g e

P a g e | 12

SQL and Databases


Database Creation
Introduction
Probably before using a database, you must first have one. In the previous lesson, we saw that there were different ways to connect to a server. The SQL is very flexible when it comes to names. In fact, it is very less restrictive than C#. Still, there are rules you must follow when naming the objects in your databases: A name can start with either a letter (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, or Z), a digit (0, 1, 2, 3, 4, 5, 6, 7, 8, or 9), an underscore (_) or a non-readable character. Examples are _n, act, %783, Second After the first character (letter, digit, underscore, or symbol), the name can have combinations of underscores, letters, digits, or symbols. Examples are _n24, act_52_t A name cannot include space, that is, empty characters. If you want to use a name that is made of various words, start the name with an opening square bracket and end it with a closing square bracket. Example are [Full Name] or [Date of Birth]

Because of the flexibility of SQL, it can be difficult to maintain names in a database. Based on this, there are conventions we will use for our objects. In fact, we will adopt the rules used in C/C++, C#, Pascal, Java, and Visual Basic, etc. In our databases: A name will start with either a letter (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, or Z) or an underscore After the first character, we can use any combination of letters, digits, or underscores A name will not start with two underscores A name will not include one or more empty spaces. That is, a name will be made in one word If the name is a combination of words, at least the second word will start in uppercase. Examples are dateHired, _RealSport, FullName, or DriversLicenseNumber

Creating a Database
The command to create a database in SQL uses the following formula: CREATE DATABASE DatabaseName The CREATE DATABASE (remember that SQL is not case-sensitive, even when you include it in a C# statement) expression is required. The DatabaseName factor is the name that the new database will carry. Although SQL is not case-sensitive, as a C# programmer, you should make it a habit to be aware of the cases you use to name your objects. As done in C#, every statement in SQL can be terminated with a semi-colon. Based on this, the above formula would be:

13 | P a g e

CREATE DATABASE DatabaseName; To create a database with code, simply pass a CREATE DATABASE statement (including the name of the database) to a MySqlCommand object.

Practical Learning: Creating a Database


1. Start SharpDevelop 2. To create a new application, on the Start Page, click the New Combine button 3. In the Categories tree of the New Project dialog box, make sure that C# is selected; otherwise, select C#. In the Templates list, click Windows Application

4. Set the Name to BCR1


5. Change the Location to a directory of your choice

6. Click Create 7. In the Projects section of the left frame, expand the Combine and the BCR1 nodes 8. Right-click References and click Add Reference 9. In the Add Reference dialog box, click the .NET Assembly Browser tab and click the Browse button 10. In the Open dialog box, locate the folder where your MySQL Connector Net is installed and display it in the Look In combo box 11. Double-click Bin followed by your version of the .NET Framework

P a g e | 14

12. Click MySql.Data.dll

13. Click Open

15 | P a g e

14. After making sure that the assembly has been selected, in the Add Reference dialog box, click OK 15. In the lower section of the main window, click Design to access the design section of the form

16. Add a Button to the form and change its properties as follows:
(Name): btnCreateDB Text: Create Database

17. Double-click the Create Database button

18. In the top section of the file, include the MySql.Data.MySqlClient namespace 19. Implement the Click event of the button as follows:
/* * Created by SharpDevelop. * User: Administrator * Date: 6/26/2005 * Time: 3:50 PM * * To change this template use Tools | Options | Coding | Edit Standard Headers. */

P a g e | 16

using using using using

System; System.Drawing; System.Windows.Forms; MySql.Data.MySqlClient;

namespace BCR1 { /// <summary> /// Description of MainForm. /// </summary> public class MainForm : System.Windows.Forms.Form { . . . No Change void BtnCreateDBClick(object sender, System.EventArgs e) { MySqlConnection conDatabase = new MySqlConnection("Data Source=localhost;" + "Persist Security Info=yes;" + "UserId=root; PWD=Whatever;"); MySqlCommand cmdDatabase = new MySqlCommand("CREATE DATABASE BCR1;", conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close(); } } }

20. Execute the application 21. Click the Create Database button 22. Close the form and return to your programming environment

23. To allow the user to specify the name of the database, change the design of the form as
follows:

Control Label TextBox Button

Name txtNewDatabase btnCreateDB

Text New Database: Create

24. Double-click the Create button and change its code as follows:
void BtnCreateDBClick(object sender, System.EventArgs e) { string strNewDatabase = this.txtNewDatabase.Text; if( strNewDatabase == "" ) return;

17 | P a g e

MySqlConnection conDatabase = new MySqlConnection("Data Source=localhost;" + "Persist Security Info=yes;" + "UserId=root; PWD=Whatever;"); MySqlCommand cmdDatabase = new MySqlCommand("CREATE DATABASE " + strNewDatabase + ";", conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close(); this.txtNewDatabase.Text = ""; this.txtNewDatabase.Focus(); } 25. Execute the application 26. Enter a string in the text box and click Create 27. Close the form and return to your programming environment

Database Maintenance
Deleting a Database
If you have created a database but don't need it anymore, you can delete it. To delete a database, you use the DROP DATABASE instruction followed by the name of the database. The formula used is: DROP DATABASE DatabaseName Before deleting a database in SQL, you must make sure the database is not being used or accessed by some one else or by another object.

Practical Learning: Deleting a Database


1. To allow the user to delete a database, change the design of the form as follows:

Control Label TextBox Button Label TextBox Button txtDeleteDB btnDeleteDB

Name

Text New Database:

txtNewDatabase btnCreateDB Create Database Delete

P a g e | 18

Button

btnClose

Close

2. Double-click the Delete button and implement its code as follows: void BtnDeleteDBClick(object sender, System.EventArgs e) { string strDatabase = txtDeleteDB.Text; if( strDatabase == "" ) return; string strDROP = "DROP DATABASE " + strDatabase + ";"; MySqlConnection conDatabase = new MySqlConnection("Data Source=localhost;" + "Persist Security Info=yes;" + "UserId=root; PWD=Whatever;"); MySqlCommand cmdDatabase = new MySqlCommand(strDROP, conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close(); txtDeleteDB.Text; txtDeleteDB.Focus(); } 3. Return to the form and double-click the Close button 4. Implement its event as follows: void BtnCloseClick(object sender, System.EventArgs e) { Close(); } 5. Execute the application 6. In the Database text box, type BCR1 and click Delete 7. After using it, to close the form, click the Close button

19 | P a g e

P a g e | 20

The Tables of a Database


Database Tables
Introduction
Tables are the foundation of organizing lists of items. This concept is valid regardless of the type of list. As a database application is primarily a list of things, the SQL uses the same approach at organizing information. Before creating a table, you must specify what database it would belong to.

Practical Learning: Introducing Tables


1. Start SharpDevelop 2. To create a new application, on the main menu, click File -> New -> Combine

3. In the Categories tree of the New Project dialog box, make sure that C# is selected;
otherwise, select C#. In the Templates list, click Windows Application

4. Set the Name to Countries1


5. Change the Location to a directory of your choice such as Drive:\Programs\MySQLApps and click Create 6. In the Projects section of the left frame, expand the Combine and the Countries1 nodes if necessary. Right-click References and click Add Reference 7. In the Add Reference dialog box, click the .NET Assembly Browser tab and click the Browse button

8. In the Open dialog box, locate the folder where your MySQL Connector Net is installed
and display it in the Look In combo box

9. Double-click Bin followed by your version of the .NET Framework 10. Click MySql.Data.dll and click Open
11. After making sure that the assembly has been selected, in the Add Reference dialog box, click OK

12. In the top section of the file, under the other using lines, type:
using MySql.Data.MySqlClient; 13. In the lower section of the MainForm.cs tab, click Design

14. Add a new button to the form and change its properties as follows:
(Name): btnCreateDB Text: Create Statistics Database 15. Double-click the Create Statistics Database button

16. To create a database for this lesson, implement the code as follows:
private void btnCreateDB_Click(object sender, System.EventArgs e) { string strConnection = "CREATE DATABASE CountriesStats;";

21 | P a g e

MySqlConnection conDatabase = new MySqlConnection("Data Source=localhost;Persist Security Info=yes"); MySqlCommand cmdDatabase = new MySqlCommand(strConnection, conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close();

17. Execute the application and click the Create button 18. Close the form and return to your programming environment

Table Creation
The statement used to create a new table uses the following formula CREATE TABLE TableName The CREATE and TABLE keywords must be used to let SQL know that you want to create a table. The TableName factor specifies the name of the new table. The TableName can use the rules and suggestions we reviewed for the database objects. After specifying the name of the table, you must list the columns of the table. The list of columns starts with an opening parenthesis "(". The list ends with a closing parenthesis ")". Each column must be separated from the next with a comma, except for the last column. You can include all columns on the same line if possible as follows: CREATE TABLE Country(Column1, Column2, Column3) There are two primary pieces of information you must specify for each column: its name and its type. Therefore, the syntax of creating a column is: ColumnName DataType Options To programmatically create a table, you can follow the same formula rules of creating a table using SQL code. Once the statement is ready, you can pass it to a MySqlCommand object. To execute the statement, you can call the SqlCommand.ExecuteNonQuery() method.

The Name of a Table


While creating a table, you must name it. If you are creating a table using SQL code, you must name your table using the above formula of CREATE TABLE TableName. The name of a table: Can be made of digits only. For example you can have a table called 148 Can start with a digit, a letter, or an underscore Can be made of letters, digits, and spaces

Besides these rules, you can make up yours. In our lessons, the name of a table Will start with a letter, in uppercase or lowercase. Examples are Employees, Accounts If made of a combination of words, it will have each part start in uppercase. Examples are BookCategories, CustomersBankAccounts.

As implied above, to create a table, you must include at least one column. In the next lesson, we will have more details on how to create and manage columns.

Practical Learning: Creating Tables


P a g e | 22

1. Change the design of the form as follows:

Control Button Button Button

Name btnCreateDB btnCreateContinents btnCreateCountries

Text Create Statistics Database Create Continents Create Countries

2. Double-click the Create Continents button and implement its code as follows:
private void btnCreateContinents_Click(object sender, System.EventArgs e) { string strCreate = "CREATE TABLE Continents(ContinentName char);"; MySqlConnection conDatabase = new MySqlConnection("Data Source=localhost;Database='CountriesStats';Persist Security Info=yes"); MySqlCommand cmdDatabase = new MySqlCommand(strCreate, conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close(); } 3. Execute the application and click the Create Continents button 4. After a few seconds, click the Create Continents button and notice that you receive an error 5. Click Quit and return to the form 6. On the form, double-click the Create Countries button

7. To use code that checks the existence of a table, using sample code like the one
generated by the Create Table Basic Template option of the SQL Query Analyzer, implement both events as follows: private void btnCreateContinents_Click(object sender, System.EventArgs e) { string strCreate = "CREATE TABLE Continents (ContinentName char);"; MySqlConnection conDatabase = new MySqlConnection("Data Source=localhost;Database='CountriesStats';Persist Security Info=yes"); MySqlCommand cmdDatabase = new MySqlCommand(strCreate, conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close();

private void btnCreateCountries_Click(object sender, System.EventArgs e) { string strCreate = "CREATE TABLE Countries (CountryName char);"; MySqlConnection conDatabase = new

23 | P a g e

MySqlConnection("Data Source=localhost;Database='CountriesStats';Persist Security Info=yes"); MySqlCommand cmdDatabase = new MySqlCommand(strCreate, conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close();

8. Execute the application 9. Click the different buttons to create the tables. You can also test renaming a table now 10. Close the form

Table Maintenance
Renaming a Table
If you have a table whose is not appropriate, you can change its name. Before renaming a table, make sure this is what you want to do and make sure you can take care of it in your code. If you rename a table, Microsoft SQL Server would take care of updating it in Microsoft SQL Server. If you had used the name in your Windows Forms Application code, of course, the new name would not be updated in your code. You made need to take care of it yourself. If you are working in SQL Server Enterprise Manager, to rename a table, first locate its database in the left frame and click the Tables node. In the right-click frame, right-click the name of the table and click Rename. You would proceed the same way you do in Windows Explorer or My Computer: the name would be put into edit mode so you can type the new one and press Enter. The SQL Server Enterprise Manager is the only utility that allows you to "visually" rename a table. If you are working in one of the other environments we have mentioned, you can only rename the table programmatically. To rename a table with code, Transact-SQL provides sp_rename. (Notice that the name starts with sp_. This is called a stored procedure. We will learn how to create them. For now, we can use them exactly as you have learned to use functions in C#: You don't need to know how they work but you can trust that they work and do what they are supposed to do. To rename a table, use the following call: EXEC sp_rename 'ExistingName', 'NewName' The EXEC sp_rename expression is required. The ExistingName factor is the name of the table you want to rename. The NewName factor is the name you want the table to have after renaming it. To rename a table in SQL Query Analyzer, make sure you are in the appropriate database first. Then use the above formula. Here is an example: USE CarRentalDB GO EXEC sp_rename 'CarsFrom1996To2000', 'CarsToRetire' GO To rename a table in a C# code, pass the sp_rename code as string to a MySqlCommand object and call the SqlCommand.ExecuteNonQuery() method.

Practical Learning: Renaming a Table


1. Change the design of the form as follows:

P a g e | 24

Control Button Button Button Label TextBox Label TextBox Button

Name btnCreateDB btnCreateCountries txtExistingTblName

Text Create Statistics Database Create Countries Table to Rename As

btnCreateContinents Create Continents

txtNewTblName btnRenameTable Rename

2. Double-click the Rename button and implement its code as follows: private void btnRenameTable_Click(object sender, System.EventArgs e) { string strExistingName = this.txtExistingTblName.Text; string strNewName = this.txtNewTblName.Text; if( strExistingName == "" ) { MessageBox.Show("To rename a table, you must provide a " + "valid name for an existing table"); return; } if( strNewName == "" ) { MessageBox.Show("To rename a table, you must provide the name " + table"); } string strConnection = "sp_rename '" + strExistingName + "', '" + strNewName + "';"; MySqlConnection conDatabase = new MySqlConnection("Data Source=localhost;Database='CountriesStats';Persist Security Info=yes"); MySqlCommand cmdDatabase = new MySqlCommand(strConnection, conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close(); this.txtExistingTblName.Text = ""; this.txtNewTblName.Text = ""; return; "that will replace the existing name of the

3. Execute the application and fill out the form as follows:

25 | P a g e

4. Click Rename

5. Close the form and return to your programming environment


6. In the Server Explorer, expand everything up to the name of the server and the Tables node of the CountriesStats database. If you don't see Pais, right-click the Tables node and click Refresh

Removing a Table
If you have a table you don't need in your database, you can remove it. Before performing this operation, you should make sure you are familiar with the role of the table. The SQL code used to delete a table uses the following formula: DROP TABLE TableName The DROP TABLE expression is required and it is followed by the name of the table as TableName. Here is an example: DROP TABLE FriendsOfMine GO If you are working from C# code, create a DROP TABLE TableName; expression and pass it to a MySqlCommand object before calling the SqlCommand.ExecuteNonQuery() method. It is extremely important to know that, when working with the DROP TABLE TableName statement, you would not receive any warning. If you are working in a Windows Forms Application, you should create your own warning in a message box to make sure that the user really want to delete the table.

P a g e | 26

The Columns of a Table


The Name of a Column
Although a table is used to hold information, its data is divided in columns and you must create each column following specific rules. The primary characteristic you must provide for a column is its name. If you are using the New Table window from SQL Server Enterprise, or the dbo.Table1 window from Microsoft Visual Studio .NET, you can type the name of each column under the Column Name section. If you are creating a SQL statement, you can type the name of the first column after the opening parenthesis. The name of a column should follow the same rules and suggestions we reviewed for the database objects.

The Types of Data a Column Can Carry


After specifying the name of a column, the interpret would need to know the kind of information the column will hold. You must specify the data type that is necessary for a particular column. If you are using the New Table window from SQL Server Enterprise, or the dbo.Table1 window from Microsoft Visual Studio .NET, you can click the box under Data Type that corresponds to the column. This would convert the text box into a combo box. You can then select from the list of available types:

27 | P a g e

You can select the data type of each column under the Data Type section. If you are creating a SQL statement, after typing the name of the column, you must type the appropriate name of the desired data type. Remember that SQL is not case-sensitive but while you can write the data type in any case, you should not overlook the case you use for the names of columns. The data types used on a table are are mostly equivalent to those we reviewed for DataColumns of a DataSet:

To support the data types used in a database, the .NET Framework provides the System.Data.SqlTypes namespace that provides a class for each SQL Server data type. The names of SQL data types are: bit: The bit is the smallest data type. It is used for a field that would validate a piece of information as being true or false, On or Off, Yes or No, 1 or 0. This is also the data type you should select if a check box would be used to validate the value of this column. This means that it can be used where the C#' bool or the .NET Framework's System.Boolean data types would be applied. The .NET Framework database equivalent to this data type is the SqlBoolean class. int: This is the same data type as the C#' int. It is a natural number that would be used if a column would hold numbers in the range of -2,147,483,648 to 2,147,483,647. This is also the same as the System.Int32 we reviewed for the DataTable objects when we studies DataSet tables. The .NET Framework database equivalent to this data type is the SqlInt32 class. tinyint: This data type can be used for a column that would hold (very) small numbers that range from 0 to 255. It is equivalent to the .NET Framework's System.Byte database. Because C++ doesn't have a byte data type, the tinyint type can be used where a short or rather an unsigned short would be used. You should use this data type only when you know for sure that the values used on this column will be small. When in doubt, you should use int. The .NET Framework database equivalent to this data type is the SqlByte class.

P a g e | 28

smallint: The smallint data type follows the same rules and principles as the int data type except that it is used to store smaller numbers that would range between -32,768 and 32,767. This means it is equivalent to the C#' short integer or the .NET Framework's System.Int16 type. The .NET Framework database equivalent to this data type is the SqlInt16 class. bigint: The bigint data type follows the same rules and principles as the int data type except that its field can hold numbers from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807. It is somehow equivalent to the C++' long integer but more accurately equivalent to the .NET Framework's System.Int64 data type. As such, you can apply this data type for a column that would hold (very) large numbers. The .NET Framework database equivalent to this data type is the SqlInt64 class. binary: This data type is used for a column that would hold hexadecimal numbers. Examples of hexadecimal numbers are 0x7238, 0xFA36, or 0xAA48D. Use the binary data type if all entries under the column would have the exact same length (or quantity). If you anticipate that some entries would be different than others, then use the alternative varbinary data type. The varbinary also is used for hexadecimal numbers but allows dissimilar entries, as long as all entries are hexadecimals. The .NET Framework database equivalent to this data type is the SqlBinary class. numeric and decimal: This data type is used on a column that will hold (either whole or) real numbers, numbers that include a decimal separator (the character used as the decimal separator as set in the Control Panel) between the digits. An example would be 12.125 or 44.80. If you anticipate such a number for a field, specify its data type as numeric or decimal (either decimal or numeric would produce the same effect in SQL Server). This data type is mostly equivalent to the C#' double or the .NET Framework's System.Double data type. The .NET Framework database equivalent to this data type is the SqlDecimal class. float and real: A floating-point number is a fractional number, like the decimal and numeric types. Floating-point numbers can be used if you would allow the database engine to apply an approximation to the actual number that a field is supposed to carry. This is mostly equivalent to the C#' float or the .NET Framework's System.Single data type. As you may be aware when using float, this data type doesn't offer good precision. The .NET Framework database equivalent to this data type is the SqlDouble class. money: As its name announces it, the money data type can be used on a column whose data would consist of currency values. A field with a money data type can hold positive or negative values from -922,337,203,685,477.5808 to +922,337,203,685,477.5807 The .NET Framework database equivalent to this data type is the SqlMoney class. smallmoney: While the money data type can be used for a field that would hold large quantities of currency values, the smallmoney data type can be applied for a column whose value cannot be lower than -214,748.3648 nor higher than 214,748.3647 The .NET Framework database equivalent to this data type is the SqlMoney class. char: A field of characters can consist of any kinds of alphabetical symbols in any combination, readable or not. If you want a column to hold a fixed number of characters, such as the book shelf numbers of a library, apply the char data type for such a column. This is equivalent to the C++' char and __wchar_t types of the .NET Framework's System.Char data type except that the SQL's char type is suitable if all fields of a column would have the same length. The .NET Framework database equivalent to this data type is the SqlString class. varchar: Like the string is in C# and most other languages, the varchar data type is the most common data type of SQL. It represents a string. This means that it can be used on any column whose values you cannot predict. In fact, it is the default data type of any column created in the New Table window of SQL Server Enterprise Manager or the dbo.Table1 window of Visual Studio .NET. Use this data type wherever you would use a String value. The maximum length of text that a field of varchar type can hold is equivalent to 8 kilobytes. The .NET Framework database equivalent to this data type is the SqlString class.

29 | P a g e

text: The text data type can be applied to a field whose data would consist of ASCII characters. As opposed to a varchar type of field, a text type of field can hold text that is longer than 8 kilobytes. The .NET Framework database equivalent to this data type is the SqlString class. nchar, nvarchar, and ntext: These three types follow the same rules as the char, varchar, and text respectively, except that they can be applied to columns that would hold international characters, that is, characters of languages other than US English. This is done following the rules of Unicode formats. The .NET Framework database equivalent to these data types is the SqlString class. datetime: As its name suggests, a datetime data type is used for a column whose data would consist of date and/or time values. The entries must be valid date or time values but SQL Server allows a lot of flexibility, even to display a date in a non-traditional format. The date value of a datetime field can be comprised between January 1st, 1753 and December 31, 9999. This data type is equivalent to the .NET Framework's DateTime data type. The .NET Framework database equivalent to this data type is the SqlDateTime class. smalldatetime: The smalldatetime is an alternative to the datetime data type. It follows the same rules and principles as the datetime data type except that a date value must be comprised between January 1st, 1900 and June 6, 2079. This data type is equivalent to the .NET Framework's DateTime data type except that this one's date ranges are smaller. Whenever in doubt, use the datetime type (or the varchar). The .NET Framework database equivalent to this data type is the SqlDateTime class.

The Length of Data


One way you can tune your database is to control the amount of text entered in a column's field. As various columns can hold different types of data, so can the same data type control its own mechanism of internal data entry. The length of data means different things to different fields. Columns that carry the same data type can have different lengths. Most columns use a default length. The only type you should think of changing the length of data is if the column is character (char) or string-based (varchar): You should not touch the others. To specify the length of a column, if you are using the New Table window from SQL Server Enterprise, or the dbo.Table1 window from Microsoft Visual Studio .NET, you can enter the desired number in the Length box that corresponds to the column. If you are creating a SQL statement, after typing the name of the type, type the opening parenthesis, followed by the desired number, followed by the closing parenthesis. The rules of Length columns are: Bit Fields: We saw already that a bit column type is meant for one of two answers. The user is supposed to simply let the database know that the answer is yes or no, true or false, on or off, 1 or 0. Therefore, the only length of this field is 1. Integers: The length of an integer is the number of bytes its field can hold. For an int type, that would be 4 bytes. Decimal and Floating-Point Numbers: The Length specifies how many bytes the field can store. Strings: The Length of a character or string column specifies the maximum number of characters that the field can hold. In some circumstances, you will need to change or specify the length as it applies to a particular field. For example, since you should use the varchar data type for a string field whose content will change from one record to another, not all varchar columns need to have the same length. Although a First Name and a Book Title columns should use the varchar

P a g e | 30

type, both columns would not have the same length of entries. As it happens, people hardly have a first name that is beyond 20 characters and many book titles go beyond 32 characters. In this case, both fields would use the same data type but different lengths. On the other hand, for columns of datetime and money data types, you should accept the default length suggested by the database.

Practical Learning: Creating a Table


1. Change the design of the form as follows:

Control Button Button Button

Name btnCreateDB btnCreateCountries

Text Create Statistics Database Create Countries

btnCreateContinents Create Continents

2. Double-click the Create Continents button and implement its code as follows: private void btnCreateContinents_Click(object sender, System.EventArgs e) { string strCreate = "CREATE TABLE Continents(" + "ContinentName varchar(100)," + "Area bigint," + "Population bigint);"; MySqlConnection conDatabase = new MySqlConnection("Data Source=localhost;Database='CountriesStats';Persist Security Info=yes"); MySqlCommand cmdDatabase = new MySqlCommand(strCreate, conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close(); } 3. Execute the application and click the Create Continents button 4. After a few seconds, click the Create Continents button and notice that you receive an error 5. Click Quit and return to the form 6. On the form, double-click the Create Countries button

7. To use code that checks the existence of a table, using sample code like the one

generated by the Create Table Basic Template option of the SQL Query Analyzer, implement both events as follows:

private void btnCreateContinents_Click(object sender, System.EventArgs e) {

31 | P a g e

string strCreate = "IF EXISTS(SELECT name FROM sysobjects " + "WHERE name = N'Continents' AND type = 'U')" + "DROP TABLE Continents;" + "CREATE TABLE Continents (" + "ContinentName varchar(100), " + "Area bigint, Population bigint);"; MySqlConnection conDatabase = new MySqlConnection("Data Source=localhost;Database='CountriesStats';Persist Security Info=yes"); MySqlCommand cmdDatabase = new MySqlCommand(strCreate, conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close(); } private void btnCreateCountries_Click(object sender, System.EventArgs e) { string strCreate = "IF EXISTS(SELECT name FROM sysobjects " + "WHERE name = N'Countries' AND type = 'U')" + "DROP TABLE Countries;" + "CREATE TABLE Countries (" + "CountryName varchar(120)," + "Continent int," + "Area bigint," + "Population bigint," + "Capital varchar(80)," + "Code char(2));"; MySqlConnection conDatabase = new MySqlConnection("Data Source=localhost;Database='CountriesStats';Persist Security Info=yes"); MySqlCommand cmdDatabase = new MySqlCommand(strCreate, conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close();

8. Execute the application 9. Click the different buttons to create the tables. You can also test renaming a table now 10. Close the form

Removing a Table
If you have a table you don't need in your database, you can remove it. Before performing this operation, you should make sure you are familiar with the role of the table. For example, when you create a database in Microsoft SQL Server, the database system creates some tables necessary for internal use. You should not make any attempt to delete any of these tables. In fact, you should try to delete only a table you know you have created and you don't need anymore. If you work in a team environment and you find a table that may have been created by someone else, you should enquire before deleting it.

P a g e | 32

To delete a table, first locate the database it belongs to. If you are working in the SQL Server Enterprise Manager, to delete a table, in the left frame, expand the database that contains the table and click the Tables node. Then, in the right frame, right-click the undesired table and click Delete. A Drop Objects warning dialog box would display, asking you to confirm your intention:

If you want to change your mind, click Cancel. If you still want to delete the table, select it in the dialog box and click Drop All. When in doubt, click Help. If you are working in the Server Explorer, to delete a table, locate it in the Tables category of its database. Then right-click the name of the undesired table and click Delete. A warning message box would display:

This allows you to change your mind or to confirm your intention. If you are working in the SQL Query Analyzer, the code used to delete a table uses the following formula: DROP TABLE TableName The DROP TABLE expression is required and it is followed by the name of the table as TableName. Here is an example: DROP TABLE FriendsOfMine GO If you are working from C# code, create a DROP TABLE TableName; expression and pass it to a MySqlCommand object before calling the SqlCommand.ExecuteNonQuery() method. It is extremely important to know that, when working with the DROP TABLE TableName statement, you would not receive any warning. If you are working in a Windows Forms Application, you should create your own warning in a message box to make sure that the user really want to delete the table.

33 | P a g e

Columns Maintenance
Columns Statistics
So far, we have seen various ways to create a table. This means that you may be aware of the information about about the columns you would have created. In you are working on a table created by someone else or you have forgotten what your old table looks like, you can enquire about the names of columns, their data types and other pieces of information related to the columns. If you are working from SQL Server Enterprise Manager, to access the design of a table, first locate it from its database. Then right-click the table and click Design Table. This would display the Design Table window that is the same used to design a table. To view the structure of a table, you can right-click it, you can right-click it and click Properties or you can double-click it:

After viewing the table, you can click Cancel. If you are working from the Server Explorer, to review the columns of a table, you can rightclick it and click and click Design Table. If you are working in SQL Query Analyzer, to get a list of the columns of a table, first specify the database, then type sp_help. Here is an example:

P a g e | 34

If you need more information about the columns, on the right side of sp_help, enter the name of the table in single-quotes (when we study functions and stored procedures, and based on your knowledge of C++, this technique is referred to as passing the name of the table as argument). Here is an example:

35 | P a g e

Adding a Column
After creating a table or when using any existing table, you may find out that a column is missing. You can add a new column to a table if necessary. If you are working in SQL Server Enterprise Manager or the Server Explorer, you can first display the table in the Design Table window (right-click the table and click Design Table). To add a new column at the end of the existing columns, in the first empty text box under the Column Name section, enter the name of the new column. To create a new column and make it the first column, right-click the first column and click Insert Column. To insert a new column anywhere in the table, right-click the column that would be under the new one and click Insert Column. If you are working with SQL code, to create a new column, the formula to use is: ALTER TABLE TableName ADD NewColumnName DataType Options When using this statement, the ALTER TABLE expression and the ADD keyword are required. You must specify the name of the table that the new column will belong to. This is done using the TableName factor in our formula. Specify the name of the new column in the NewColumnName placeholder of our formula. On the right side of the NewColumnName placeholder, specify the options in the same way we described for columns. If you are working from a Windows Forms Application code, create an ALTER TABLE expression and pass it to a MySqlCommand object before executing it. Here is an example: private void btnAddColumn_Click(object sender, System.EventArgs e) { MySqlConnection conDatabase = new MySqlConnection("Data Source=localhost;Database='CountriesStats';Persist Security Info=yes"); MySqlCommand cmdDatabase = new MySqlCommand("ALTER TABLE Countries ADD TypeOfGovernment varchar(100);", conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close();

Renaming a Column
If you find out that the name of a column is not appropriate in a table, you can change that name. If you are working from SQL Server Enterprise Manager or Server Explorer, first display the table in the Design Table window (right-click the table and click Design Table):

P a g e | 36

To rename a column, double-click its name to put it into edit mode and then edit its name. If you are working with SQL code, the code to rename a column uses the following formula: EXEC sp_rename 'ExistingName', 'NewName', 'COLUMN' The EXEC sp_rename expression and 'COLUMN' are required. The ExistingName factor is the name of the column you want to rename. The NewName factor is the name that will replace the existing name. To rename a column in SQL Query Analyzer, you must qualify the existing name of the column by typing the name of its table, followed by a period, and followed by the name of the column. Here is an example: USE CarRentalDB GO EXEC sp_rename 'CarsToRetire.AC', 'HasAirCondition' GO To rename a table in a C++ code, pass the sp_rename code as string to a MySqlCommand object and call the SqlCommand.ExecuteNonQuery() method. Here is an example: private void btnRenameCode_Click(object sender, System.EventArgs e) { string strConnection = "sp_rename 'Countries.Code', 'InternetCode', 'COLUMN';"; MySqlConnection conDatabase = new MySqlConnection("Data Source=localhost;Database='CountriesStats';Persist Security Info=yes");

37 | P a g e

MySqlCommand cmdDatabase = new MySqlCommand(strConnection, conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close();

Deleting a Column
If you have a column you don't need, you can remove that column from the table. To remove a column in the Design Table displayed from the SQL Server Enterprise or from the Server Explorer, you can first click that column, then right-click anywhere in the top section of the window and click Delete Column:

If you are working in the SQL Query Analyzer, the formula to delete a column is: ALTER TABLE TableName DROP COLUMN ColumnName In this formula, the ALTER TABLE and the DROP COLUMN expressions are required. The TableName factor is the name of the table that owns the column. The ColumnName factor is the name of the column to be deleted. To programmatically remove a column, create an ALTER TABLE statement using the above formula, pass the statement as string to a MySqlCommand object before executing it. There is no warning when deleting a column. In the Design Table window, if you delete a column by mistake, you can close the table and refuse to save it. This is almost the only chance you have at keeping the column. If you are programmatically deleting a column, you can provide your own warning through a message box to make the user decide to continue or keep the column.

P a g e | 38

Data Entry
Fundamentals of Table Data Entry
Introduction
Data entry consists of populating a table with the necessary values it is supposed to hold. In the previous lessons, we saw that, to organize its data, a table is divided in sections called columns. The values common to an entry under each column constitute a row or record and a row is made of cells: as you may realize, everything we reviewed about the organization of a table, when studying data sets, is also valid here. Data entry consists of filling the cells under the columns of a table.

Practical Learning: Introducing Data Entry


1. Start a new Windows Forms Application named Countries3
2. Right click the form and click View Code

3. In the top section of the file, under the other using lines, type:
using MySql.Data.MySqlClient;

4. Design the form as follows:

Control TabPage Button Button Button TabPage TabPage

Name pgeMaintenance btnCreateDB btnCreateCountries pgeContinents pgeCountries

Text Maintenance Create Statistics Database Create Countries Continents Countries

TabControl tabCountries

btnCreateContinents Create Continents

39 | P a g e

Button

btnClose

Close

5. Double-click the Create Statistics Database button and implement its code as follows:
private void btnCreateDB_Click(object sender, System.EventArgs e) { string strConnection = "IF EXISTS (SELECT * " + "FROM master..sysdatabases " + "WHERE name = N'CountriesStats')" + "DROP DATABASE CountriesStats;" + "CREATE DATABASE CountriesStats;"; MySqlConnection conDatabase = new MySqlConnection("Data Source=localhost;Persist Security Info=sspi"); MySqlCommand cmdDatabase = new MySqlCommand(strConnection, conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close(); } 6. Return to the form and double-click the Create Continents button

7. Implement its Click event as follows:


private void btnCreateContinents_Click(object sender, System.EventArgs e) { string strCreate = "IF EXISTS(SELECT name FROM sysobjects " + "WHERE name = N'Continents' AND type = 'U')" + "DROP TABLE Continents;" + "CREATE TABLE Continents (" + "ContinentName varchar(100)," + "Area varchar(30), " + "Population varchar(30));"; MySqlConnection conDatabase = new MySqlConnection( "Data Source=localhost;Database='CountriesStats';Persist Security Info=yes"); MySqlCommand cmdDatabase = new MySqlCommand(strCreate, conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close();

8. Return to the form and double-click the Create Countries button

9. Implement its Click event as follows:


private void btnCreateCountries_Click(object sender, System.EventArgs e) { string strCreate = "IF EXISTS(SELECT name FROM sysobjects " + "WHERE name = N'Countries' AND type = 'U')" + "DROP TABLE Countries;" + "CREATE TABLE Countries (" + "CountryName varchar(120)," + "Area varchar(30)," +

P a g e | 40

"Population varchar(30)," + "Capital varchar(80)," + "Code char(2));"; MySqlConnection conDatabase = new MySqlConnection( "Data Source=localhost;Database='CountriesStats';Persist Security Info=yes"); MySqlCommand cmdDatabase = new MySqlCommand(strCreate, conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close(); } 10. Return to the form and double-click the Close button

11. Implement its event as follows:


private void btnClose_Click(object sender, System.EventArgs e) { Close(); } 12. Execute the application 13. Click the top button and wait a few seconds 14. Click the middle button and wait a few seconds 15. Click the bottom button and wait a few seconds

16. Close the form and return to your programming environment

Displaying the Table For Data Entry


Before performing data entry from the SQL Server Enterprise Manager, you must first open it in a view that display its records. To do this, you can locate the database it belongs to and click the Tables node. In the right frame, click the table's name to select it. Then, on the main menu, click Action . Open Table . Return all rows. Alternatively, you can right-click the table in the right frame, position the mouse on Open Table, and click Return all rows. If you are working in Server Explorer, expand the name of the server under the Servers node, then expand SQL Servers, followed by the name of the server, followed by the database, and followed by the Tables node. Finally, double-click the desired table. If this is the first time you open the table for data entry, it would display the label of each column on top and empty cells under it:

If the table already contains some records, they would display under the column headers.

41 | P a g e

Techniques of Performing Data Entry


Data Entry Using the Enterprise Manager or Server Explorer
After displaying the table in the SQL Server Enterprise Manager or the Server Explorer, to enter new data, click an empty cell and type the necessary value. After finishing with one cell, you can press Enter, Tab or click another cell. You can start this operation on the most left cell and continue with the cells on its right. When you finish with a row of cells and move to another row, the interpreter creates (or updates) a record. Therefore, entering data also self-creates a record. This also means that, when using the table in the SQL Server Enterprise Manager or the Server Explorer, you will not have to formally create a record of a table: it is automatically created when you enter data. While performing data entry, the user may skip some fields if the information is not available. The user can skip only columns that allow NULL values. If a column was configured as NOT accepting NULL values, the user must enter something in the field, otherwise he would receive an error and the table would not allow going further.

Data Entry Using the SQL Query Analyzer


In the SQL, data entry is performed using the INSERT combined with the VALUES keywords. The primary statement uses the following formula: INSERT TableName VALUES(Column1, Column2, Column_n) Alternatively, or to be more precise, you can specify that you are entering data in the table using the INTO keyword between the INSERT keyword and the TableName factor. This is done with the following syntax: INSERT INTO TableName VALUES(Column1, Column2, Column_n) The TableName factor must be a valid name of an existing table in the database you are using. If the name is wrong, the SQL would simply consider that the table you are referring to doesn't exist. Consequently, you would receive an error. The VALUES keyword indicates that you are ready to list the of the columns must be included in parentheses. The most data entry requires that you know the sequence of columns enter data. With this subsequent list in mind, enter the value the parentheses of the above formula. values of the columns. The values common technique of performing of the table in which you want to of each field in its correct order in

If the column is a BIT data type, you must specify one of its values as 0 or 1. If the column is a numeric type, you should pay attention to the number you type. If the column was configured to receive an integer (int, bigint, smallint), you should provide a valid natural number without the decimal separator. If the column is for a decimal number (float, real, decimal, numeric), you can type the value with its character separator (the period for US English). If the column was created for a date data type, make sure you provide a valid date. If the data type of a column is a string type, you should include its entry between single quotes. For example, a shelf number can be specified as 'HHR-604' and a middle initial can be given as 'D'. Here is an example INSERT Countries VALUES('Sweden',449964,8875053,'Stockholm','se') GO

P a g e | 42

The list of values doesn't have to be typed on the same line. You can use one for each value. Here is example: INSERT Country VALUES ( 'Angola', 1246700, 10593171, 'Luanda', 'ao' ) GO In the same way, the parentheses can be written on their own lines: INSERT INTO Country VALUES ( 'Mongolia', 1565000, 2694432, 'Ulaanbaator','mn' ) GO The adjacent data entry we have used above requires that you know the order of columns of the table. If you don't know or don't want to follow the exact order of the columns, you can perform data entry with an order of your choice. This allows you to provide the values of fields in any order of your choice. We have just seen a few examples where the values of some of the fields are not available during data entry. Instead of remembering to type 0 or NULL for such fields or leaving empty quotes for a field you can use their names to specify the fields whose data you want to provide. To perform data entry at random, you must provide a list of the fields of the table in the order of your choice. You can either use all columns or provide a list of the same columns but in your own order. In the same way, you don't have to provide data for all columns, just those you want, in the order you want. Here is an example: INSERT Country(CountryName, Capital,InternetCode,Population,Area) VALUES('Taiwan', 'Taipei', 'tw', 22548009, 35980) GO Here is another example: INSERT Country(InternetCode, CountryName, Capital, Area) VALUES( 'mx', 'Mexico', 'Mexico', 1972550) GO Instead of first creating a table and then performing data entry, you can create a table and add records at once as long as you separate the statements with GO. To proceed, in your code, you must first create the table, which would save it, use GO to end the statement that creates the table, start the statement or each statement used to add a record, and it or each with GO. Consider the following example: ----IF ============================================= Database: VideoCollection Table: Videos ============================================= EXISTS(SELECT name FROM sysobjects WHERE name = N'Videos' AND type = 'U') DROP TABLE Videos GO USE VideoCollection

43 | P a g e

GO CREATE TABLE Videos ( VideoTitle varchar(100), Director varchar(80), YearReleased int, VideoLength varchar(30), Rating varchar(20)) GO INSERT INTO Videos VALUES('A Few Good Men', 'Rob Reiner', 1992, '138 Minutes', 'R') GO INSERT INTO Videos(Director, VideoLength, VideoTitle, YearReleased) VALUES('Jonathan Dame', '118 Minutes', 'The Silence of the Lambs', 1991) GO INSERT INTO Videos(VideoLength, Rating, Director, VideoTitle) VALUES('112 Minutes', 'R', 'Jonathan Line', 'The Distinguished Gentleman') GO INSERT INTO Videos(Rating, VideoTitle, Director, VideoLength) VALUES('R', 'The Lady Killers', 'Joel Coen & Ethan Coen', '104 Minutes') GO INSERT INTO Videos VALUES('Ghosts of Mississipi', 'Rob Reiner', 1996, '130 Minutes', '') GO

Data Entry On Command


To programmatically perform data entry using a SQL statement, create an INSERT statement exactly following the descriptions made for SQL Query Analyzer. Once the statement is ready, pass it as string to a MySqlCommand object and execute it with a call to SqlCommand.ExecuteNonQuery().

Practical Learning: Performing Data Entry With a MySqlCommand Object


1. Change the design of the form as follows:

Control GroupBox

Name

Text New Continent

P a g e | 44

Label TextBox Label TextBox Label TextBox Button txtContinentPopulation btnNewContinent txtContinentArea txtContinentName

Name: Area: Population Create New Continent

2. Double-click the Create New Continent button and implement its code as follows:
private void btnNewContinent_Click(object sender, System.EventArgs e) { string strContinentName = this.txtContinentName.Text; if( strContinentName == "" ) { MessageBox.Show("You must provide a name for the continent"); return; } string strInsert = "INSERT INTO Continents VALUES('" + strContinentName + "', '" + this.txtContinentArea.Text + "', '" + this.txtContinentPopulation.Text + "');"; MySqlConnection conDatabase = new MySqlConnection("Data Source=localhost;Database='CountriesStats';Persist Security Info=yes"); MySqlCommand cmdDatabase = new MySqlCommand(strInsert, conDatabase); conDatabase.Open(); cmdDatabase.ExecuteNonQuery(); conDatabase.Close(); this.txtContinentName.Text = ""; this.txtContinentArea.Text = ""; this.txtContinentPopulation.Text = ""; this.txtContinentName.Focus();

3. Execute the application and fill out the form as follows:

45 | P a g e

4. Click Create New Continent 5. Close the form and return to your programming environment

Data Maintenance: Deleting Records


Introduction
Like databases, tables, and columns, records need maintenance too. Some of the operations you can perform include deleting a whole record, changing the value of a record under a particular column (which is equivalent to editing a record), etc. Just as done for a column, before changing anything on a record, you must locate it first. This operation is somehow different than the maintenance performed on databases, tables, and columns. The reason is that, although you always know the name of a database, the name of a table, or the name of a column, when it comes to records, you cannot know in advance the information it holds. For this reason, you must use additional operators to help you locate a record. Fortunately, as always, you have various options.

Deleting Records: the Server Explorer or the Enterprise Manager


Deleting a record consists of removing it from a table, this includes all entries, if any, under each column for a particular row. If you are working from SQL Server Enterprise Manager, before removing a record, first display the table in a view that shows its record. You can do this by right-click the table, positioning the mouse on Open Table, and clicking Return All Rows. If you are working in the Server Explorer, to display the table and show all records, double-click the table. In both cases, once in the Data window, to remove a record, right-click the gray box on the left side of the record and click Delete:

P a g e | 46

After clicking Delete, you would receive a warning message box:

If you still want to continue, you can click Yes and that record would disappear. If you want to change your mind, click No. To remove a range of records from a table, you can click and drag from one gray box at one end of the range to the gray box at the other end of the range. As an alternative, you can click a gray box at one end of the range, press and hold Shift, then click the gray box at the other other end of the desired range. Once the selection is made, right-click anywhere in the selection and click Delete:

47 | P a g e

If you click Delete, you would receive a warning that lets you know the number of records that would be deleted. If you still want to delete them, you can click Yes. To change your mind, click No. To remove all records from a table, you must first select all of them. To do this, you can click the gray box on the left of the first (or the last) record, press and hold Shift, then click the gray box of the last (or first) record:

Once the selection is made, right-click anywhere in the table and click Delete. You would receive the same type of warning for a range of records and you can proceed the same way.

Deleting Records in SQL Query Analyzer


The SQL code that deletes all records from a table uses the following formula: DELETE TableName

P a g e | 48

When you create this statement, provide the name of the table as TableName. When you execute this statement, all records of the table would be removed. To remove one particular record from a table, use the following formula: DELETE TableName WHERE CriteriaToFindTheRecord The DELETE and the WHERE keywords are required. The TableName factor allows you to specify the name of the table that the record belongs to. In order to delete the record, you must provide a way to locate it. Consider the following table named Videos from a database named VideoCollection:

Imagine that you want to remove the record whose video title is "The Silence of the Lambs". In this case, the TableName is Videos. The criterion to find the correct record is that the VideoTitle value of that record = The Silence of the Lambs. To remove it, you would use code as follows: USE VideoCollection GO /* Code used to remove the video titled The Silence of the Lambs */ DELETE Videos WHERE VideoTitle = 'The Silence of the Lambs' GO If you use the DELETE formula to remove a record, notice that, as always in SQL Query Analyzer, you would not be warned.

Deleting a Record on Command


To programmatically delete a record, create a DELETE statement using the same rules we reviewed for SQL Query Analyzer, pass it to a MySqlCommand object, and execute the statement by calling the SqlCommand.ExecuteNonQuery() method.

Data Maintenance: Updating Records


Updating a Record in the Enterprise Manager
To change a record in SQL Server Enterprise Manager, first open the table with the view that displays records (Right-click the table . Open Table . Return All Rows). In the Data window, locate the value you want to change, click it, edit it, and then click somewhere else:

49 | P a g e

Once the cell loses focus, the new value is automatically saved:

Updating a Record in the SQL Query Analyzer


The SQL statement used to change the value of a record uses the following formula: UPDATE TableName SET ColumnName = NewValue WHERE CriteriaToLocateRecord The UPDATE keyword allows you to specify the name of the table whose record you want to change. The table is identified with the TableName factor of our formula. The SET keyword allows you to identify the column under which exists the value you want to change. The column is identified as ColumnName in our formula. On the right side of the column name, type the assignment operator, followed by the value you want the cell to hold. If the update is successful, the value stored under that column would be replaced. The WHERE clause allows you to specify the criterion used to locate the particular record that the existing value belongs to. Consider you have the above table, imagine that, on the video titled "The Distinguished Gentleman", you want to change the name of the director from "Jonathan Line" to "Jonathan Lynn. The table name is Videos. The column that owns the value is named Director. The criterion to use is to identify the record whose VideoTitle is "The Distinguished Gentleman". The code to perform this update would be: USE VideoCollection GO -- Code used to change the name of a director UPDATE Videos SET Director = 'Jonathan Lynn' WHERE VideoTitle = 'The Distinguished Gentleman' GO

P a g e | 50

Once again, remember that where performing an operation in the SQL Query Analyzer, you would not be warned.

Updating a Record on Command


To update a record in a Windows Forms Application, create an UPDATE statement using the same rules we reviewed for SQL Query Analyzer, pass it to a MySqlCommand object before executing the statement with a call to the SqlCommand.ExecuteNonQuery() method.

Assistance With Data Entry


Introduction
Microsoft SQL Server and the SQL provide various ways to assist you with data entry. For example, if you have a table in a Microsoft SQL Server database, a Microsoft Access database, or another system, such as a text file, you can import the values of that table. Another type of assistance you can get with data entry is to copy records from one table to another.

Data Import
Another technique used to perform data entry consists of importing already existing data from another database or from any other recognizable data file. Microsoft SQL Server provides various techniques and means of importing data into Microsoft SQL Server. The easiest type of data that can be imported into SQL Server, and which is available on almost all database environments is the text file. Almost any database application you can think of can be imported as a text file but data from that file must be formatted in an acceptable format. For example, the information stored in the file must define the columns as distinguishable by a character that serves as a separator. This separator can be the single-quote, the double-quote, or any valid character. SQL Server is able to recognize the double-quote as a valid separator of columns. Data between the quotes is considered as belonging to a distinct field. Besides this information, the database would need to separate information from two different columns. Again, a valid character must be used. Most databases, including SQL Server, recognize the comma as such a character. The last piece of information the file must provide is to distinguish each record from another. This is easily taken car of by the end of line of a record. This is also recognized as the carriage return. These directives can help you manually create a text file that can be imported into SQL Server. In practicality, if you want to import data that resides on another database, you can ask that application to create the source of data. Most applications can do that and format it so another application can easily use such data. That is the case for the data we will use in the next exercise: it is data that resided on a Microsoft Access database and was prepared to be imported in SQL Server. After importing data, you should verify and possibly format it to customize its fields.

51 | P a g e

Practical Learning: Importing Data From an External Source


1. Download the Students text file and save it to your hard drive
2. In the SQL Server Enterprise Manager, right-click the Databases node and click New Database...

3. Type ROSH and press Enter 4. In the left frame, right-click ROSH, position the mouse on All Tasks and click Import Data
5. On the first page of the wizard, click Next

6. On the second page, click the arrow of the Data Source combo box and select Text File:

7. Click the button on the right side of the File Name edit box 8. Locate the folder where you saved the Students text file. Select the file and press Enter:

P a g e | 52

9. Click Next

10. On the third page, make sure the file is type ANSI and the Row Delimiter is the Carriage
Return-Line Feed ({CR}{LF}) and accept all other defaults. Click Next

53 | P a g e

11. On the fourth page, accept all defaults and click Next. 12. On the fifth page, make sure that the Destination is SQL Server and the destination Database is HighSchool. Then click Next 13. Accept all defaults from the sixth and the seventh pages. Then click Next.

14. On the eighth page, click Finish

15. When you receive a confirmation of "Successfully Copied, click OK 16. On the Executing Package page, click Close 17. Position the mouse on Server Explorer to display it. In the Server Explorer, expand the

P a g e | 54

server, followed by the SQL Servers node, followed by the name of the server 18. In the Server Explorer, right-click the name of the server and click Refresh. Expand the Tables node under the ROSH database

19. Right-click Students and click Design Table

20. As the first field is selected, type StudentNbr and change its Length to 10 21. Change the other columns as follows:

55 | P a g e

22. To save the table, click the Save button on the toolbar:

P a g e | 56

23. When a Validation Warnings dialog box presents a few warnings, click Yes 24. Close the table 25. To view data stored on the table, in the Server Explorer, double-click Students 26. Close the table

The Default Value


When performing data entry, the records under a certain column usually have the same value. For example, for a local database with a table that includes an address, most employees would live in the same state and the same country. When creating a column with a value that occur regularly, you can specify that value as default. To specify the default value in the SQL Server Enterprise Manager or the Server Explorer, display the table is design view. To proceed, first click the column in the top section of the table. Then, in the lower section, click Default Value and type the desired value in singlequotes. Here is an example:

57 | P a g e

To specify the default value in a SQL statement, when creating the column, before the semicolon or the closing parenthesis of the last column, assign the desired value to the DEFAULT keyword. Here are examples: ----IF ============================================= Database: Sydney University Table: StaffMembers ============================================= EXISTS(SELECT name FROM sysobjects WHERE name = N'StaffMembers' AND type = 'U') DROP TABLE StaffMembers GO CREATE TABLE StaffMembers ( FullName VARCHAR(50), Address VARCHAR(80), City VARCHAR(40), State VARCHAR(40) DEFAULT = 'NSW', PostalCode VARCHAR(4) DEFAULT = '2000', Country VARCHAR(20) DEFAULT = 'Australia') GO If you are creating the table in a Windows Forms Application, use the same rules of the SQL statement and create the table as we have done already. After creating the table, the user doesn't have to provide a value for a column that has a default. If the user doesn't provide the value, the default would be used when the record is saved. If the user provides a value for a column that has a default value and then deletes the

P a g e | 58

value, the default value rule would not apply anymore: The field would simply become empty If you create a Windows Forms Application and provide a form that allows the user to perform data entry for a table using a form, the default values for columns would not display in the Windows control. When writing your code, you can omit passing the values for the columns that have default values. In this case, the SQL interpreter, not the C++ compiler would use the default values for the columns you omit.

Practical Learning: Setting Default Values


1. In the design view of the table and in the top section, click Gender

2. In the lower section, click Default Value and type 'Unknown'


3. In the top section, click State

4. In the lower section, click Default Value and type 'MD'


5. Save the table

Constraints in Data Entry


Introduction
A constraint in a database is a rule used to apply restrictions on what is allowed and what is not allowed in the application. To assist you in creating an effective database, the SQL provides various types of constraints you can apply to your table(s).

The Nullity of a Field


During data entry, users of your database will face fields that expect data. Sometimes, for one reason or another, data will not be available for a particular field. An example would be an MI (middle initial) field: some people have a middle initial, some others either don't have it or would not provide it to the user. This aspect can occur for any field of your table. Therefore, you should think of a way to deal with it. A field is referred to as null when no data entry has been made to it: Saying that a field is null doesn't mean that it contains 0 because 0 is a value. Saying that a field is null doesn't mean that it is empty. A field being empty could mean that the user had deleted its content or that the field itself would not accept what the user was trying to enter into that field, but an empty field can have a value.

A field is referred to as null if there is no way of determining its value or its value is simply unknown. As you can see, it is not a good idea to have a null field in your table. As a database developer, it is your responsibility to always know with certainty the value held by each field of your table. Remember that even if a field is empty, you should know what value it is holding because being empty could certainly mean that the field has a value. To solve the problem of null values, the SQL proposes one of two options: allow or not allow null values on a field. For a typical table, there are pieces of information that the user should make sure to enter; otherwise, her data entry would not be validated. To make sure the user always fills out a certain field before moving to the next field, you must make sure the field doesn't allow null values; this will ensure that you know that the field is holding a value and, eventually, you can find out what that value is. To apply nullity rules in SQL Server Enterprise Manager or Server Explorer, first display the table in the design view. To get it, in the SQL Server Enterprise Manager, you can right-click the table and click Design Table. In the Server Explorer of Microsoft Visual Studio .NET, you can right-click the table and click Design Table.

59 | P a g e

Once in the Design Table window, you can click or clear the Allow Nulls check box that corresponds to the column. On the other hand, if the value of a field is not particularly important, for example if you don't intend to involve that value in an algebraic operation, you can allow the user to leave it null. This is done by checking the Allow Nulls check box for the field. Here is an example of a table in which the CategoryID and the Picture columns would not Allow Nulls but the the CategoryName and the Description columns would:

To control the nullity of a column with a SQL statement, you can use NULL, NOT NULL, or omit it.

Practical Learning: Controlling Nullity


1. In the Server Explorer, right-click Students and click Design Table 2. Under the Allow Nulls column, remove the check boxes the correspond to the StudentNbr and the LastName columns 3. Save the table

Am I my Record's Keeper?
When updating a record and changing a value, just like the user can make a mistake and change the wrong value, you too can. Consider the following table:

Imagine you ask the user to open this table and, for the video that is rated R, to change the name of the director to Jonathan Lynn. The user would be confused because there is more than one video that is rated R. This means that you should use the most restrictive criterion to locate the record. In future lessons, when we study data analysis, we will review other operators you can use, such as asking the user to locate the video whose title is "The Distinguished Gentleman" AND whose director is Jonathan Lynn. To be able to uniquely identify each record, you can create a special column and make sure that each value under that column is unique. You have two main options. You can put the responsibility on the user to always provide a unique value. For example, if the table includes records of students of a school, since each student must have a student number and that number must be unique from one student to another, you can ask the user to make sure of this during data entry. What if the user forgets? What if the user cannot get that number at the

P a g e | 60

time of data entry? What if that number can only be generated by the administration but only after the student has been registered? Based on this, an alternative is to ask the SQL interpreter to automatically generate a new and unique number for each record. A column whose values are automatically generated by the database engine is referred to as an identity column. An identity column can have only a numeric-based data type: bigint, decimal, int, numeric, smallint, or tinyint. To create an identity column, if you are working the SQL Server Enterprise Manager or the Server Explorer, in the Design Table window, in the top section of the table, create the column by specifying its name and data type as one of the above. Then, in the lower section, set the Identify field to Yes from its default No. Here is an example:

If you are working from a SQL statement, to create an identity column, when creating the table, after the name of the column and before the semi-colon or the closing parenthesis of the last column, enter IDENTITY(),. After setting the Identity to Yes, you must then specify where the numeric counting would start. By default, this number is set to 1, meaning the first record would have a number of 1, the second would have a number of 2, and so on. If you want, you can ask the interpreter to start with a different number. To specify the starting value of the identity column, if you are working in the Design Table window, in the lower section of the table, enter the desired value in the Identity Seed field. Here is an example:

61 | P a g e

If you are working with a SQL statement, to specify the starting value of the identity column, enter the desired number in the parentheses of the IDENTITY keyword. After the starting value of the identity column has been set, you can specify how much value would be added to the values of the column with each new record. By default, each previous number would be incremented by 1. If you want a different value, you can change it from 1. To specify the incrementing value of an identity column, if you are working a Design Table window, in the lower portion of the table, enter the desired value in the Identity Increment field. If you are working with a SQL statement, to specify the incrementing value, enter it as the second argument of the IDENTITY keyword. Here is an example: ----IF ============================================= Database: Sydney University Table: StaffMembers ============================================= EXISTS(SELECT name FROM sysobjects WHERE name = N'StaffMembers' AND type = 'U') DROP TABLE StaffMembers GO CREATE TABLE StaffMembers ( StaffNumber int IDENTITY(1,1), FullName VARCHAR(50) NOT NULL, Address VARCHAR(80), City VARCHAR(40), State VARCHAR(40) NULL DEFAULT = 'NSW', PostalCode VARCHAR(4) DEFAULT = '2000', Country VARCHAR(20) DEFAULT = 'Australia') GO

P a g e | 62

Practical Learning: Adding an Auto-Incrementing Column


1. Right-click anywhere in the StudentNbr line and click Insert Column

2. In the new empty column, set the name to StudentNumber 3. Set the Data Type to int
4. In the lower section of the table, double-click the No value of Identifier to change it to Yes. Notice that the Identity Seed and the Identity Increment have been set to 1 5. Close the table 6. When asked whether you want to save, click Yes

The Primary Key


We have seen that an identity column is used to make sure that a table has a certain column that holds a unique value for each record. In some cases, you can more than one column to uniquely identify each record. For example, on a table that holds the list of employees of a company, you can use both the employee number and the social security number to uniquely identity each record. In our description of the identity column, we saw that it applied only to one column; but we also mentioned that a more that one column could be used to uniquely identity each record. The column or the combination of columns used to uniquely identity each column is called a primary key. If you are creating a table in the Design Table window of the SQL Server Enterprise Manager or from the Server Explorer of Microsoft Visual Studio .NET, to indicate the column that would be used as the primary key, first click the name of the column. Then, on the toolbar, click the Primary Key button . You can also right-click the desired column and click Primary Key. The button on the left side of the name of the column would become equipped with a key icon. By tradition, which is not a rule, the name of the column used as the primary key of a table ends with ID. For example, instead of the column being named StaffNumber, it would be named StaffMemberID or something like that. To specify that more than one column would be used as the primary key, first select them. To do this, you can click the left gray button of one of the column, press Ctrl, and click the left gray button of each of the other columns that would be involved. After selecting the column, on the toolbar, click the Primary button and click Primary Key. . You can also right-click one of the selected columns

Practical Learning: Indicating the Primary Key of a Table


1. Change the name of the first column from StudentNumber to StudentID 2. Right-click it and click Primary Key 3. Save and close the table

CHECK
When performing data entry, in some columns, even after indicating the types of values you expect the user to provide for a certain column, you may want to restrict a range of values that are allowed. This is done using the CHECK constraint.

63 | P a g e

P a g e | 64

Adapting Data to Windows Controls


The SQL Data Adapter
Introduction
If you are familiar with it, you probably know already that the DataSet class was developed to help you create and manage any type of list-based application. The high level of flexibility that this class offers also allows it to directly integrate with a data-based application, such as one created with Microsoft SQL Server. The elements of a DataSet object directly relate to those of a database application. As mentioned already, a DataSet object is primarily used to create a list, not a formal database in the strict sense of Microsoft SQL Server, Microsoft Access, or Corel Paradox, etc. This means that a list-based application lead by a DataSet is primarily a list. In order to read information of a formal database and use it in a DataSet list, you must "convert" or adapt it. A data adapter is an object that takes data from a database, reads that data, and "fills" a DataSet object with that data. In reverse, a data adapter can get the data stored in, or manipulated by, a DataSet object and fill or update a database with that data. To be able to apply these scenarios to any database, the .NET Framework provides various data adapters, each adapted for a particular category of database.

Practical Learning: Introducing Data Adapters


1. Start Microsoft Visual Studio .NET or Visual C#
2. Display the Server Explorer. Expand the Servers node, followed by the name of the computer, followed by SQL Servers, followed by the name of the server

3. Right-click the server and click New Database 4. Set the New Database Name to GCS and accept to use Windows NT Persist Security Info
5. Click OK

6. Under the name of the server in Server Explorer, expand the GCS node
7. Right-click the Tables node and click New Table

8. Create the table with the following columns (change only the indicated information;
anything that is not mentioned should be ignored and use the default): Column Name EmployeeID EmployeeNbr DateHired FirstName LastName HourlySalary IsMarried Data Type int char smalldatetime varchar varchar smallmoney bit 20 20 Unchecked 6 Length Allow Nulls Other Properties Primary Key Identity: Yes

9. Save the table as Employees and close it 10. Create a new Windows Application named GCS1 11. Design the form as follows: 65 | P a g e

Control DataGrid Button 12. Save all

Name

Text/CaptionText Employees Records

Additional Properties Anchor: Top, Bottom, Left, Right AutoFormat: Colorful 2 Anchor: Bottom, Right

btnClose Close

Data Selection
The most regularly performed operation of a data adapter is to read the values stored in a table of a database. This reading operation is commonly referred to as selection. To proceed, you use the following SQL formula: SELECT What FROM TableName In this formula, the SELECT and the FROM keywords are required. The keyword SELECT in this case means "read". In other words, you would be asking the data adapter to read something. The TableName placeholder of our formula allows you to specify the name of the table that holds the data you want to read. You must make sure the table exists and is part of the connection established in the current application. The What factor of our formula allows you to specify one or more columns of the table. If you want to use the values of only one column, specify its name in the What placeholder of our formula. An example would be: SELECT VideoTitle FROM Videos In this case, you are asking the data adapter to read all values stored under the column named VideoTitle from the table named Videos. If you want to read data from more than one column, specify their list in the What placeholder of our formula and separate the names of columns with a comma. Here is an example: SELECT VideoTitle, Director, Rating FROM Videos If you want to select all columns of the table, you can list them in the same way. As an alternative, to represent all columns of a table, you can use the * in the What placeholder of our formula. Here is an example: SELECT * FROM Videos

P a g e | 66

This means that the data adapter would be asked to read all values under all columns of the table named Videos. As done in the previous lessons, remember that you must first establish a connection to the server and to the database. This is an example that creates a connection to a database named VideoCollection in the local server and creates a SELECT statement to read all values of a table named Videos: private void Form1_Load(object sender, System.EventArgs e) { MySqlConnection cnnVideos = new MySqlConnection( "Data Source=localhost;Database='VideoCollection';Persist Security Info=yes"); } string strVideos = "SELECT * FROM Videos;";

Creating a SQL Data Adapter


In order to read information from a Microsoft SQL Server database and make it available to a DataSet object, you can use an object created from the SqlDataAdapter class. This class is defined in the MySql.Data.MySqlClient namespace of the System.Data.dll library. The SqlDataAdapter class is derived from the DbDataAdapter class, itself derived from the DataAdapter class. The DbDataAdapter and the DataAdapter classes are defined in the System.Data.Common namespaces of the System.Data.dll library. To use the SqlDataAdapter class, you can declare a pointer to SqlDataAdapter using one of its constructors. If you don't want to manually declare the variable, in the Data section of the Toolbox, you can click the SqlDataAdapter button Data Adapter Configuration Wizard: and click the form. This would launch the

67 | P a g e

If you want to continue with the wizard, you can click Next. If you plan to "manually" configure the data adapter as we will describe in the next few sections, you can click Cancel. A SqlDataAdapter object would be added to your application. You can then use the Properties window to configure it:

As another alternative, if you already know the table you want to use from a database, in the Server Explorer, locate the table under the Tables node of its database, drag the table to the form. A data adapter and its connection would automatically be created and configured. You can also drag more than one table if your data adapter would need to read from many tables.

Selecting Data for a Data Adapter


To allow the data adapter to use values produced from reading in a table, the SqlDataAdapter class is equipped with a property named SelectCommand of type SqlCommand. To use it, you can first declare a pointer to SqlDataAdapter using its default constructor. SqlDataAdapter dadVideoCollection = new SqlDataAdapter(); To specify how data would be read, you can first create a MySqlCommand object that would carry a SQL SELECT statement: MySqlConnection cnnVideos = new MySqlConnection( "Data Source=localhost;Database='VideoCollection';Persist Security Info=yes"); string strVideos = "SELECT VideoTitle FROM Videos;"; MySqlCommand cmdVideos = new MySqlCommand(strVideos, cnnVideos); Equipped with a MySqlCommand object that holds a SELECT statement, you can assign it to the SqlDataAdapter.SelectCommand property of your data adapter. This would be done as follows:

P a g e | 68

private void Form1_Load(object sender, System.EventArgs e) { MySqlConnection cnnVideos = new MySqlConnection( "Data Source=localhost;Database='VideoCollection';Persist Security Info=yes"); string strVideos = "SELECT * FROM Videos;"; MySqlCommand cmdVideos = new MySqlCommand(strVideos, cnnVideos); SqlDataAdapter dadVideoCollection = new SqlDataAdapter(); dadVideoCollection.SelectCommand = cmdVideos; cnnVideos.Open(); cnnVideos.Close(); If you don't want to use the default constructor and the SelectCommand property separately, you can use the second constructor of the SqlDataAdapter class. Its syntax is: public SqlDataAdapter(MySqlCommand selectCommand); This constructor takes as argument a MySqlCommand object. This time, instead of assign the command to the SelectCommand property, you can pass that MySqlCommand object to the SqlDataAdapter variable when declaring it. This would be done as follows: private void Form1_Load(object sender, System.EventArgs e) { MySqlConnection cnnVideos = new MySqlConnection( "Data Source=localhost;Database='VideoCollection';Persist Security Info=yes"); string strVideos = "SELECT VideoID, VideoTitle, Director, YearReleased, VideoLength, Rating FROM Videos;"; MySqlCommand cmdVideos = new MySqlCommand(strVideos, cnnVideos); SqlDataAdapter dadVideoCollection = new SqlDataAdapter(cmdVideos); cnnVideos.Open(); cnnVideos.Close(); } Notice that with both constructors reviewed above, you must pass the connection to a MySqlCommand object. As an alternative, you can create a connection but pass it directly to the data adapter when declaring its variable. To do this, you can use the third constructor of the SqlDataAdapter class. Its syntax is: public SqlDataAdapter(String selectCommandText, MySqlConnection selectConnection); The first argument of this constructor expects the statement, passed as string, that specifies how the data would be read. The second argument is a MySqlConnection object that specifies how the connection to database would be handled. Here is an example: private void Form1_Load(object sender, System.EventArgs e) { MySqlConnection cnnVideos = new MySqlConnection( "Data Source=localhost;Database='VideoCollection';Persist Security Info=yes"); string strVideos = "SELECT * FROM Videos;"; SqlDataAdapter dadVideoCollection = new SqlDataAdapter(strVideos, cnnVideos); cnnVideos.Open();

69 | P a g e

cnnVideos.Close(); Instead of separately defining a MySqlConnection and a SqlDataAdapter objects, you can directly provide a connection string to the SqlDataAdapter object when declaring it. To do this, you can use the fourth constructor of the SqlDataAdapter class. Its syntax is:

public SqlDataAdapter(String selectCommandText, String selectConnectionString); The first argument to this constructor is the statement that specifies how data would be read. The second argument is a connection string. Here is an example of declaring a data adapter using this version of the SqlDataAdapter class: private void Form1_Load(object sender, System.EventArgs e) { string strSelVideos = "SELECT * FROM Videos;"; string strConVideos = "Data Source=localhost;Database='VideoCollection';Persist Security Info=yes"; SqlDataAdapter dadVideoCollection = new SqlDataAdapter(strSelVideos, strConVideos); }

Practical Learning: Creating a Data Adapter


1. In the Toolbox, click Data, then click the SqlDataAdapter button
2. In the first page of the wizard, read the text and click Next 3. In the second page of the wizard, click the New Connection button 4. In the Connection property page of the Data Link Properties sheet, in the 1 section, select the name of your computer and click the form

5. In the 2 section, click the Use Windows NT Persist Security Info radio button
6. In the 3 section, select GCS in the combo box

7. Click Test Connection

8. Click OK twice P a g e | 70

9. In the second page of the wizard, click Next

10. In the third page, accept the Use SQL Statements radio button and click Next

11. In the fourth page of the wizard, click the Query Builder button 71 | P a g e

12. In the Add Table dialog box, click Employees, click Add, and click Close

13. In the Query Builder dialog box, click the check box on the left side of each field in the list
except *(AllColumns):

14. Click OK

P a g e | 72

15. In the fourth page of the wizard, click Next

16. In the fifth page of the wizard, read the messages and click Finish 17. To have an idea of what the SELECT statement looks like, while the sqlDataAdapter1 control is selected under the form, in the Properties window, click the + button of the SelectCommand field and position the mouse on its CommandText field

How the DataSet Fits Into This


Creating a DataSet for a Data Reader
Before using a data set if your application, you would need a DataSet object. You have two main options. You can declare a DataSet variable. Here is an example: private void Form1_Load(object sender, System.EventArgs e) { MySqlConnection cnnVideos = new MySqlConnection( "Data Source=localhost;Database='VideoCollection';Persist Security Info=yes"); string strVideos = "SELECT VideoID, VideoTitle, Director, YearReleased, " + "VideoLength, Rating FROM Videos;"; MySqlCommand cmdVideos = new MySqlCommand(strVideos, cnnVideos); SqlDataAdapter dadVideoCollection = new SqlDataAdapter(cmdVideos); DataSet setVideos = new DataSet("VideoCollection"); cnnVideos.Open(); cnnVideos.Close();

73 | P a g e

If you declare your own DataSet variable, you would also eventually have to take care of some detailed operations such as reading from XML, writing to XML, or serializing. The alternative to declaring your own DataSet class is to ask Microsoft Visual Studio .NET to create a DataSet object for you. To do this, after adding a SqlDataAdapter to your project, you can right-click it and click Generate Dataset... Or, on the main menu, you can click Data . Generate Dataset... This would display the Generate Dataset dialog box. If there was no prior DataSet object in your project, you can click the New radio button and type the desired name for the new DataSet object. The default suggested name is DataSet1:

If there was already at least one DataSet object in your project, the Existing radio button would be selected and the existing name would be suggested. You still have the option of accepting the existing DataSet or creating a new one. After making your choice, you can click OK.

Practical Learning: Generating a DataSet From a Data Adapter


1. To create a DataSet object for the current data adapter, under the form, right-click the sqlDataAdapter1 button and click Generate DataSet...

2. In the Generate Dataset dialog box, accept the New radio button and change the name
with dsGCS

3. Click OK

P a g e | 74

4. In the Solution Explorer, find the file named dsGCS.xsd and double-click it to examine it

Filling the DataSet With Data From a Data Reader


After reading data using a SqlDataAdapter object, you can used it to fill a DataSet object. To support this operation, the SqlDataAdapter class inherits the Fill() method from the DbDataAdapter class. This method is overloaded with 8 versions. The first version of this method uses the following syntax: public override int Fill(DataSet dataSet); This version takes as argument a pointer to DataSet. After this call, the dataset argument would be filled with the records of the table read by the data adapter. When calling this method, you can pass it a pointer to DataSet created as described above. Here is an example: private void Form1_Load(object sender, System.EventArgs e) { MySqlConnection cnnVideos = new MySqlConnection( "Data Source=localhost;Database='VideoCollection';Persist Security Info=yes"); string strVideos = "SELECT VideoID, VideoTitle, Director, YearReleased, " + "VideoLength, Rating FROM Videos;"; MySqlCommand cmdVideos = new MySqlCommand(strVideos, cnnVideos); SqlDataAdapter dadVideoCollection = new SqlDataAdapter(cmdVideos); DataSet setVideos = new DataSet("VideoCollection"); dadVideoCollection.Fill(setVideos); cnnVideos.Open(); cnnVideos.Close(); Once a DataSet contains records, you can use it as a data source for Windows controls. For example, you can use it to populate a DataGrid control. Here is an example: private void Form1_Load(object sender, System.EventArgs e) { MySqlConnection cnnVideos = new MySqlConnection( "Data Source=localhost;Database='VideoCollection';Persist Security Info=yes"); string strVideos = "SELECT VideoID, VideoTitle, Director, YearReleased, " + "VideoLength, Rating FROM Videos;"; MySqlCommand cmdVideos = new MySqlCommand(strVideos, cnnVideos); SqlDataAdapter dadVideoCollection = new SqlDataAdapter(cmdVideos); DataSet setVideos = new DataSet("VideoCollection"); dadVideoCollection.Fill(setVideos); this.dataGrid1.DataSource = setVideos; cnnVideos.Open(); cnnVideos.Close();

75 | P a g e

Once a DataSet has received data from a data adapter, it is made aware of the table(s), the column(s), and the record(s) that belong to the SELECT statement of the data adapter. Based on this, you can bind the Windows controls of your application's form to the columns of a DataSet.

Practical Learning: Filling the DataSet With Data From a Data Reader
1. Display the form. Double-click an occupied area of the form and implement the event as
follows: private void Form1_Load(object sender, System.EventArgs e) { this.sqlDataAdapter1.Fill(this.dsGCS1); } 2. Save all

The Tables of a DataSet


The tables of a DataSet object are stored in the DataSet.Tables property that is of type DataTableCollection. After filling up a DataSet, if the selection statement of the data adapter includes only one table (in future lessons, we will see that a SELECT statement can include more than one table), as done in the above data adapter, the first table of the statement can be identified with the index of 0 as in DataTableCollection[0]. If the statement includes only one table, only a 0 index can be used. As the DataTableCollection[0] value allows you to identify a table, you can retrieve any table-related information with this information. For example, you can get the object name of the table and specify it as the DataMember property of a DataGrid control. Here is an example: private void Form1_Load(object sender, System.EventArgs e) { MySqlConnection cnnVideos = new MySqlConnection( "Data Source=localhost;Database='VideoCollection';Persist Security Info=yes"); " + string strVideos = "SELECT VideoID, VideoTitle, Director, YearReleased, "VideoLength, Rating FROM Videos;"; MySqlCommand cmdVideos = new MySqlCommand(strVideos, cnnVideos); cnnVideos.Open(); SqlDataAdapter dadVideoCollection = new SqlDataAdapter(cmdVideos); DataSet setVideos = new DataSet("VideoCollection"); dadVideoCollection.Fill(setVideos);

P a g e | 76

this.dataGrid1.DataSource = setVideos; this.dataGrid1.DataMember = setVideos.Tables[0].TableName; } cnnVideos.Close();

Remember that the DataSet.Tables[Index] value gives you access to a table as an object and you can use it as necessary.

Practical Learning: Binding a Table to Controls


1. Display the form and click its DataGrid control 2. In the Properties window, set its DataSource to dsGCS1.Employees 3. Save all

The Columns of a Table of a DataSet


Just as you can use the filled DataSet to locate a table by its index, inside of the identified table, you can also locate a particular column you need. As reviewed in lessons 8 and 9, the columns of a table are stored in the Columns property of a DataTable object and the Columns property is of type DataColumnCollection. Each column inside of the table can be identified by its index. The first column has an index of 0. The second has an index of 1, and so on. Once you have identified a column, you can manipulate it as you see fit. In the following example, since we (behave like we) don't know the name of the second column, a message box displays that information for us: private void Form1_Load(object sender, System.EventArgs e) { MySqlConnection cnnVideos = new MySqlConnection( "Data Source=localhost;Database='VideoCollection';Persist Security Info=yes"); string strVideos = "SELECT VideoID, VideoTitle, Director, YearReleased, " + "VideoLength, Rating FROM Videos;"; MySqlCommand cmdVideos = new MySqlCommand(strVideos, cnnVideos); cnnVideos.Open(); SqlDataAdapter dadVideoCollection = new SqlDataAdapter(cmdVideos); DataSet setVideos = new DataSet("VideoCollection"); dadVideoCollection.Fill(setVideos); this.dataGrid1.DataSource = setVideos; this.dataGrid1.DataMember = setVideos.Tables[0].TableName; DataColumn colSecond = setVideos.Tables[0].Columns[1]; MessageBox.Show("The name of the second column is " +

77 | P a g e

colSecond.ColumnName); cnnVideos.Close(); }

Updating a Record Using the Data Adapter


When visiting the records of a table using a form of your application, if you provide the means for the user to move from one record to another, if the user gets to a record and changes something in it, that record would not be automatically updated when the user moves to another record. To update a record using the data adapter, the SqlDataAdapter class inherits the Update() method from its parent the DbDataAdapter. The Update() method is overloaded with 5 versions. One of its versions uses the following syntax: public override int Update(DataSet dataSet); This version takes a DataSet object as argument. This means that the data adapter would read the information stored in the DataSet and update the database with it. This is probably one of the easiest or fastest means of updating data of a table.

Practical Learning: Updating a Record Using the Data Adapter


1. Display the form and click its DataGrid control

2. In the Properties window, click the Events button 3. Double-click the right field to CurrentCellChanged and implement its event as follows:
private void dataGrid1_CurrentCellChanged(object sender, System.EventArgs e) { this.sqlDataAdapter1.Update(this.dsGCS1); }

4. Execute the application and, omitting the EmployeeID column, create a few records:

5. Close the form and return to your programming environment

6. On the form, double-click the Close button and implement its event as follows:
private void btnClose_Click(object sender, System.EventArgs e)

P a g e | 78

{ } Close();

7. Execute the application again and notice that the previously created records were saved 8. Close the form and return to your programming environment

The Records of a Table of a DataSet


After filling out a DataSet with information from a data adapter, the records of the table(s) included in the selection statement become available from the DataSet object. As reviewed in Lesson 9, the records of a table are stored in the Rows property of the table. We have already seen how to locate a table and how to identify a column. To locate a record, you can use the techniques reviewed in Lesson 9. Data entry with a data adapter is performed just a few steps once you have properly bound the controls of your form to a DataSet object. To start, you can access the form's BindingContext property to get its BindingContext.Item property. The second version of this property allows you to specify the data source and the table name. After specifying the DataSet object that holds the records and the table that holds the data, you can first call the EndCurrentEdit() method to suspend any record editing that was going on. After this, call the AddNew() to get the table ready for a new record. This allows the user to enter values in the Windows control.

79 | P a g e

P a g e | 80

Data Analysis

Fundamentals of Data Analysis


Introduction
Data analysis consists of visiting the values stored in the tables of a database, for any reason judged necessary. It can be performed to check the accuracy of a series of values, to apply new changes to one or more records, to look for the existence or state of a record, or else. Microsoft SQL Server itself is equipped with all the tools, including visual tools, needed to perform data analysis. If you want to perform data analysis in a Windows Forms Application, you must know what the SQL offers so you can apply the SQL as a language to your programming language, in this case C#, and use these in your Windows controls. If you are working in the SQL Server Enterprise Manager, before performing data analysis, you should first open the table in a view that shows its records. To do this, after locating the desired table, you can right-click it, position the mouse on Open Table, and click Return All Rows. If you are working with the Server Explorer, after locating the table, you can double-click it or rightclick the table and click Retrieve Data From Table. In both cases, after displaying the table, to access the view that allows data analysis, click the Show SQL Pane button . If all cases, including the SQL Query Analyzer or a Windows Forms Application, to perform data analysis, you must write a SQL statement. After writing the statement, you must execute it. If you are working with a table from the SQL Server Enterprise Manager or one from the Server Explorer, to execute the statement, you can

81 | P a g e

click its Run button

If you are working in the SQL Query Analyzer, to execute a statement, you can click the Execute Query button or press F5.

If you are working in a Windows Forms Application, to perform data analysis, the .NET Framework provides the DataView class. The DataView class is defined in the System.Data namespace of the System.Data.dll library. To use a DataView object in your application, you can declare a pointer to DataView using one of its three constructors. The default constructor allows you to declare the variable without giving its details. As an alternative to declaring a DataView variable, Microsoft Visual Studio .NET provides the DataView button in the Data section of the Toolbox. You can click it and click your form. This is equivalent to declaring a DataView variable using the default constructor, except that this variable would be available at the class level.

Practical Learning: Introducing Data Analysis


Start Microsoft Visual Studio .NET or Microsoft Visual C# and create a Windows Forms Application named ROSH1

Data Selection
In order to perform any type of data analysis, you must specify the table and the columns that would be involved. This is done using the same type of SELECT statement we introduced for the data adapter in the previous lesson. The fundamental formula of selecting columns of a table is: SELECT What FROM TableName Based on this formula, you use the TableName to specify the name of the table that holds the records you want to retrieve. The table must exist in the database you specified when establishing your connection. If you want to use the records of only one column, you can specify its name as the What placeholder of our formula. Here is an example:

If you want to use more than one column, separate them with commas. Here is an example:

P a g e | 82

If you want to use all columns of the table, replace the What placeholder of our formula with *. Here is an example:

If you are working in a Windows Forms Application and plan to perform data analysis, after declaring a DataView variable, the first action you should take is to specify the table that holds

83 | P a g e

the records you want to examine. If you have declared the DataView variable using its default constructor, to specify the table, you can assign the name of the database table to the Table property of the DataView object. Alternatively, you can specify the table when declaring the DataView class. To do this, you can use the following constructor: public DataView(DataTable table); As you can see, this constructor expects a pointer to a DataTable as argument. After declaring the DataView variable, the records stored in the table argument would accessible for operations performed using the DataView object. The name of the table can also be specified in the Table field of the Properties window for the DataView object.

Practical Learning: Selecting Data


1. Make sure the form is displaying. In the Server Explorer, expand the name of the computer, followed by the SQL Servers node, followed by the name of the server, followed by the ROSH nodes, followed by the Tables node. 2. In the Tables node of the ROSH database, drag the Students node and drop it on the form 3. To create the associated DataSet object, on the main menu, click Data -> Generate Dataset...

4. In the Generate Dataset dialog box, accept the New radio button. Change the name to
dsROSH and click OK

5. In the Data section of the Toolbox, click the DataView button

and click the form

6. In the Properties, change the (Name) to dvwStudents and click the Table field
7. Click the arrow of the Table field. Click the + button of dsROSH1 and click Students 8. Save all

P a g e | 84

Data Analysis: Sorting Records

Ascending Order
If you create a table that includes an identity column and that column is the first (or the most left) column of the table, when the user performs data entry, the records are arranged in the incremental order of the numbers of that identity column. Here is an example:

If you want, you can allow the user to arrange the list of records based on another column. This other column would be used as reference. Rearrange the list of records is referred to as sorting and there are two options: ascending and descending.

85 | P a g e

When a list is sorted in ascending order: If the list is made or numeric values, the lowest value would become the first, followed by the second to lowest value, and the highest value would become the last. This is the case for the EmployeeID column of the above table If the list is made of strings (words), the alphabet would be used. The string whose first letter is the highest in the alphabet from a, b, c, etc would be the first. In this case, the ascending order is the same as the alphabetical order. For example, in a list made Paul, Walter, Anne, and John, in that order, when sorted in ascending order, the list would become Anne, John, Paul, Walter. If various strings in the list start with the same letter, as is the case for the above FirstName column, the strings with the same starting letter would be grouped first. Then among the strings with the same starting letter, the second letter would be considered and the same algorithm would be applied If the list is made of dates, the earliest date would become the first and the most recent date would become the last If the list is a combination of numbers and strings, the numbers would be arranged in incremental order firs, followed by the list of strings in alphabetical order If the list contains empty values, the empty values would be the first, the other values would be arranged in order depending on their type

All of the techniques used to sort records on a table can also be applied to a query that displays in Datasheet View. To create more advanced queries, the SQL allows you to sort a field on a query and use this arrangement as part of the query. To sort a column in ascending order, you can include the ORDER BY clause in your statement. The formula used is: SELECT What FROM TableName ORDER BY ColumnName; The What and the TableName factors are the same as described earlier. The ColumnName placeholder allows you to specify the column used as reference. When this operation is performed, the values under the ColumnName column would be sorted in ascending order. The value or the other columns would be used to correspond to those of this column. Consider the following example:

P a g e | 86

Notice that the records under the LastName column are sorted in alphabetical order, and the other values in the other columns simply follow this order. If you use the * operator to include all fields, you can order the list based on any of the table's column. By default, records are ordered in ascending order. Nevertheless, the ascending order is controlled using the ASC keyword specified after the column used as basis. Here is an example:

87 | P a g e

If you create a database application that contains a table and you want the users to be able to sort values of that table, probably the fastest means of supporting this operation is through the DataGrid control. Its columns are already configured to be sorted in ascending or descending order. If you are working in a Windows Forms Application and using a DataView object, to sort records, the DataView class is equipped with the Sort property that is of type String. To specify the sort order to apply to the records, assign a formatted string to this property.

Descending Order
Instead of sorting a list in ascending order, you can rearrange its values in reverse order. This is referred to as descending order. The algorithms used are the same as for ascending, except that they are applied in reverse. If you want to sort records in descending order, use the DESC keyword after the name of the column, in place of ASC. The DESC keyword produces the opposite result to the ASC effect. Here is an example:

P a g e | 88

Once again, if you are working in a Windows Forms Application and using a DataView object, to sort records, assign an appropriately built string to the DataView.Sort property.

Practical Learning: Sorting Records


1. Design the form as follows:

89 | P a g e

Control Label ComboBox Label ComboBox Label DataGrid Button

Name

Text/Capti Other Properties onText Sort: DropDownStyle: DropDownList in DropDownStyle: DropDownList order Students Records Auto Format: Colorful 2 Anchor: Top, Bottom, Left, Right DataSource: dvwStudents

cboColumns cboSortOrder

btnClose

Close

2. Access the Items property of the right combo box and create two strings as Ascending
and Descending 3. In the Windows Forms section of the Toolbox, click ContextMenu and click the form

4. Create the menu items as follows:


Text Filter By Selection Sort Ascending Sort Descending Remove Filter/Sort mnuRemFiltSort mnuSortAsc mnuSortDesc (Name) mnuFiltBySel

Filter Excluding Selection mnuFiltExclSel

5.

P a g e | 90

6. On the form, click the DataGrid control and, in the Properties window, set its ContextMenu property to contextMenu1 7. Double-click an occupied area of the form to access its Load event

8. In the class, declare a DataColumn variable named colSelected


public class Form1 : System.Windows.Forms.Form { private DataColumn colSelected;

9. Implement the Load event of the form as follows:


private void Form1_Load(object sender, System.EventArgs e) { DataTable tblStudents = this.dsROSH1.Tables["Students"]; DataColumnCollection colStudents = tblStudents.Columns; for(int i = 0; i < colStudents.Count; i++) this.cboColumns.Items.Add(colStudents[i].ColumnName); this.cboColumns.SelectedIndex = 0; this.cboSortOrder.SelectedIndex = 0; this.sqlDataAdapter1.Fill(this.dsROSH1); } colSelected = new DataColumn();

10. Return to the form and click the DataGrid control. In the Events section of the Properties
window, generate the MouseDown event and implement it as follows:

private void dataGrid1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) { DataGrid.HitTestInfo hti = this.dataGrid1.HitTest(e.X, e.Y); DataGridCell curCell = new DataGridCell(); curCell.RowNumber = hti.Row;

91 | P a g e

curCell.ColumnNumber = hti.Column; this.dataGrid1.CurrentCell = curCell; colSelected = this.dsROSH1.Tables["Students"].Columns[hti.Column]; }

11. Return to the form. Double-click the combo box on the right side of the Sort label and
implement its SelectedIndexChanged event as follows: private void cboColumns_SelectedIndexChanged(object sender, System.EventArgs e) { string strAscDesc = "ASC"; if( this.cboSortOrder.Text == "Descending" ) strAscDesc = "DESC"; this.dvwStudents.Sort = this.cboColumns.Text + " " + strAscDesc; } 12. Return to the form and double-click the combo box on the right side of the in label

13. As done for the first combo box, implement the SelectedIndexChanged event as follows:
private void cboSortOrder_SelectedIndexChanged(object sender, System.EventArgs e) { string strAscDesc = "ASC"; if( this.cboColumns.SelectedIndex == -1 ) return; if( this.cboSortOrder.Text == "Descending" ) strAscDesc = "DESC"; this.dvwStudents.Sort = this.cboColumns.Text + " " + strAscDesc; } 14. Return to the form and click contextMenu1

15. In the menu, double-click Sort Ascending and implement its event as follows:
private void mnuSortAsc_Click(object sender, System.EventArgs e) { this.dvwStudents.Sort = colSelected.ColumnName + " ASC"; }

16. Return to the form. In the menu, double-click Sort Descending and implement its Click
event as follows: private void mnuSortDesc_Click(object sender, System.EventArgs e) { this.dvwStudents.Sort = colSelected.ColumnName + " DESC"; }

17. Return to the form. In the menu, double-click Remove Filter/Sort and implement its Click
event as follows:

private void mnuRemFiltSort_Click(object sender, System.EventArgs e) {

P a g e | 92

this.dvwStudents.RowFilter = 0; this.dvwStudents.Sort = "StudentID ASC";

18. Return to the form and double-click the Close button

19. Implement its Click event as follows:


private void btnClose_Click(object sender, System.EventArgs e) { Close(); } 20. Execute the application 21. Test the top combo boxes and test the context menu

93 | P a g e

P a g e | 94

Criteria For Data Analysis

Introduction
Besides selecting and sorting records, data analysis also consists of restricting the list of records to examine at one time. To do this, you would include a clause in your SQL statement to create a particular. The interpreter would select only records that abide by the rule of your choice. The rule used to restrict the list of available records is called a criterion. The plural is criteria but it can also be used in singular.

WHERE is Data
To set a criterion in your SQL statement, you use the WHERE keyword in the following formula: SELECT What FROM TableName WHERE Condition The What and the TableName factors follow the same rules we have applied so far. The Condition factor is used to specify the rule applied to restrict the list of records. A condition is formulated as a logical expression that produces a Boolean result. To create an expression, you use comparison operators supported by the SQL. You are already familiar with some of the operators. Some others are not used in C# but may be familiar to Visual Basic or Pascal programmers.

Comparison Operators
95 | P a g e

Introduction
A comparison operator is used to compare one value to another. Normally, from your knowledge of C#, you should already be familiar with all the routine comparisons performed on values and variables. Most operators used in SQL for comparison are the same as those used in C# except the inequality <>. Based on this, you can perform your comparisons on column names and constant values. If you are using .NET Framework classes of the System.Data.SqlTypes namespace in your code, each one of its classes has an overloaded method that corresponds to each comparison operator we will review.

Equal =
The equality operator is used to compare one value to another. For a WHERE condition, this operator can be used to compare the values of a column to a particular value for a match. The condition would have the following formula: ColumnName = 'Value' In this case, you can specify a name for the column that holds the type of value you want to use as a criterion. Once you have identified the column, you can assign it the particular value of its records that would excluding non-abiding columns. For example, imagine you have a list of business customers in different countries, to get a list of only the customers who live in Mexico, you would set the criterion as Country = 'Mexico'. Here is an example of such a statement:

If you are using a class from the System.Data.SqlTypes namespace, each class is equipped with an Equals() method overloaded with two versions. The first corresponds to the routine Equals() method that all .NET Framework class inherit from the Object class. The second version allows you to compare, for equality, two columns created with the same data type.

Comparison Operators: Not Equal <>


To find out if two fields hold different values, you can use the inequality operator which is represented by <>. Its syntax is: Value1 <> Value2 This comparison is performed between Value1 and Value2. If they hold different values, then the comparison produces a TRUE value. If they hold the same value, the comparison produces FALSE. This shows that the equality (=) and the inequality (<>) operators are opposite each

P a g e | 96

other. Here is an example: SELECT FirstName, LastName, Gender FROM Students WHERE Gender <> 'Female'; If you are using a class from the System.Data.SqlTypes namespace, each class is equipped with an NotEquals() method used to compare, for inequality, two columns created with the same data type.

Comparison Operators: Less Than <


The "Less Than" operator uses the following formula: Value1 < Value2 If Value1 holds a value that is lower than that of Value2, the comparison produces TRUE. If Value1 holds a value that is greater than or similar to that of Value2, the comparison renders FALSE. You can formulate the condition as follows: SELECT FirstName, LastName, Gender, DateOfBirth FROM Students WHERE DateOfBirth < '1988-06-01' Here is an example:

If you are using a class from the System.Data.SqlTypes namespace, each class is equipped with an LessThan() method used to compare two columns created with the same data type. The value of the first argument to this method is compared with the value of the second argument. If the first value is lower than the second, this method returns true. Otherwise, it

97 | P a g e

returns false.

Comparison Operators: Less Than or Equal <=


When comparing two values, you may want to know whether two fields hold the same value or if one is lower than the other. This comparison can be performed with the "Less Than Or Equal To" operator. It is represented by <= and its formula is: Value1 <= Value2 If both operands (Value1 and Value2) hold the same value, then the comparison produces a TRUE result. If Value1 holds a value that is lower than that of Value2, the comparison still produces a TRUE result. By contrast, if the value of Value1 is higher than that of Value2, the comparison renders a FALSE result. Notice that the > and the <= operators are opposite each other. Here is an example: SELECT FirstName, LastName, DateOfBirth, EmailAddress FROM Students WHERE DateOfBirth <= '1990-01-01'; If you are using a class from the System.Data.SqlTypes namespace, each class is equipped with an LessThanOrEqual() method used to compare two columns created with the same data type. The value of the first argument to this method is compared with the value of the second argument. If the first value is lower than the second or both are equal, this method returns true. If the value of the first argument is strictly less than that of the second, this method returns false.

Comparison Operators: Greater Than >


The > operator is used to find out whether one value is "Greater Than" another. Its syntax is: Value1 > Value2 The operation is performed on the values of Value1 and Value2. If Value1 holds a value greater than that of Value2, then the comparison produces TRUE. Otherwise, the comparison produces FALSE. That is, if the value of Value2 is greater than or equal to that of Value1, then the comparison produces FALSE. If you are using a class from the System.Data.SqlTypes namespace, each class is equipped with an GreaterThan() method used to compare two columns created with the same data type. The value of the first argument to this method is compared with the value of the second argument. If the first value is higher than the second, this method returns true. Otherwise, it returns false.

Comparison Operators: Greater Than or Equal >=


If you have two values and want to find out whether they hold similar values or the first is greater than the second, you can use the >= operator whose syntax is: Value1 >= Value2 If both Value1 and Value2 hold the same value, then the comparison renders a TRUE result. Similarly, if the left operand, Value1, holds a value greater than that of the right operand, Value2, the comparison still produces TRUE. If the value of Value1 is less than the value of Value2, the comparison produces a FALSE result. Therefore, < and >= are opposite.

P a g e | 98

If you are using a class from the System.Data.SqlTypes namespace, each class is equipped with an LessThanOrEqual() method used to compare two columns created with the same data type. The value of the first argument to this method is compared with the value of the second argument. If the first value is higher than the second or both are equal, this method returns true. If the value of the first argument is strictly higher than that of the second, this method returns false.

Practical Learning: Filtering Records


1. In the bottom section of the form, add the following controls:

Control Label

Name

Text Filter For:

Items

Other Properties Anchor: Bottom, Left Anchor: Bottom, Left DropDownStyle: DropDownList

ComboBox cboFilterFor = Equals <> Not Equal < Less Than <= Less Than or Equal To > Greater Than >= Greater Than or Equal To

ComboBox cboOperator

Anchor: Bottom, Left DropDownStyle: DropDownList Anchor: Bottom, Left DropDownStyle: DropDownList

ComboBox cboRecValue

2. Double-click an unoccupied area of the form and change the Load event as follows:
private void Form1_Load(object sender, System.EventArgs e) { DataTable tblStudents = this.dsROSH1.Tables["Students"]; DataColumnCollection colStudents = tblStudents.Columns; for(int i = 0; i < colStudents.Count; i++)

99 | P a g e

this.cboColumns.Items.Add(colStudents[i].ColumnName); this.cboColumns.SelectedIndex = 0; this.cboSortOrder.SelectedIndex = 0; this.sqlDataAdapter1.Fill(this.dsROSH1); colSelected = new DataColumn(); for(int i = 0; i < colStudents.Count; i++) this.cboFilterFor.Items.Add(colStudents[i].ColumnName);

3. Return to the form and click contextMenu1

4. In the menu, double-click Filter By Selection and implement its event as follows:
private void mnuFiltBySel_Click(object sender, System.EventArgs e) { DataGridCell curCell = this.dataGrid1.CurrentCell; this.dvwStudents.RowFilter = colSelected.ColumnName + " = '" + dataGrid1[curCell].ToString() + "'";

5. Return to the form. In the menu, double-click Filter Excluding Selection and implement its
event as follows:

private void mnuFiltExclSel_Click(object sender, System.EventArgs e) { DataGridCell curCell = this.dataGrid1.CurrentCell; this.dvwStudents.RowFilter = colSelected.ColumnName + " <> '" + dataGrid1[curCell].ToString() + "'";

6. Below the form, double-click the most left combo box and implement its
SelectedIndexChanged event as follows:

private void cboFilterFor_SelectedIndexChanged(object sender, System.EventArgs e) { string strColSelected = this.cboFilterFor.Text; DataRowCollection colRows = this.dsROSH1.Tables["Students"].Rows; this.cboRecValue.Items.Clear(); this.cboRecValue.Items.Add("NULL"); for(int i = 0; i < colRows.Count; i++) { string strRecValue = (colRows[i]) [strColSelected].ToString(); if( strRecValue == "" ) continue; if( this.cboRecValue.Items.Contains(strRecValue) ) continue; this.cboRecValue.Items.Add(strRecValue);

P a g e | 100

this.cboOperator.SelectedIndex = 0;

7. Return to the form. Below the form, double-click the most right combo box and implement
its SelectedIndexChanged event as follows:

private void cboRecValue_SelectedIndexChanged(object sender, System.EventArgs e) { string strColSelected = this.cboFilterFor.Text; string strOperSelected = this.cboOperator.Text; string strRecValue = this.cboRecValue.Text; if( strColSelected == "" ) return; string strOperator = "="; if( strOperSelected == "<> Not Equal" ) strOperator = "<>"; else if( strOperSelected == "< Less Than" ) strOperator = "<"; else if( strOperSelected == "<= Less Than or Equal To" ) strOperator = "<="; else if( strOperSelected == "> Greater Than" ) strOperator = ">"; else if( strOperSelected == ">= Greater Than or Equal To" ) strOperator = ">="; if( strRecValue == "NULL" ) this.dvwStudents.RowFilter = "IsNull(" + strColSelected + ", 'Null Column') = 'Null Column'"; else this.dvwStudents.RowFilter = String.Concat(strColSelected, " ", strOperator, " '", strRecValue, "'"); Text = String.Concat("ROSH - Student Analysis: ", this.dvwStudents.Count.ToString(), " Records Found"); }

8. Return to the form. Below the form, double-click the middle combo box and implement its
SelectedIndexChanged event as follows: private void cboOperator_SelectedIndexChanged(object sender, System.EventArgs e) { // This event should work only if the used has already selected // a column in the most right combo box if( this.cboRecValue.Text == "" ) return; cboRecValue_SelectedIndexChanged(sender, e); } 9. Execute the application

101 | P a g e

P a g e | 102

Reading Data Using a Data Reader

103 | P a g e

A Data Reader

Introduction
P a g e | 104

Practical Learning: Reading Data


1. Display the form. On the form, double-click the Open button and implement its Click event
as follows: private void btnOpen_Click(object sender, System.EventArgs e) { string strReceiptNumber = this.txtReceiptNumber.Text; if( strReceiptNumber == "" ) { MessageBox.Show("You must provide a receipt number to look for the repair"); return; } string strFindRepair = "SELECT * FROM RepairOrders WHERE RepairOrderID = '" + strReceiptNumber + "'"; MySql.Data.MySqlClient.MySqlConnection conDatabase = new MySql.Data.MySqlClient.MySqlConnection("Data Source=localhost;Database='CPAS';Persist Security Info=yes"); MySql.Data.MySqlClient.MyMySqlCommand cmdDatabase = new MySql.Data.MySqlClient.MySqlCommand(strFindRepair, conDatabase); conDatabase.Open(); MySql.Data.MySqlClient.MySqlDataReader rdrRepairOrder; rdrRepairOrder = cmdDatabase.ExecuteReader(); while( rdrRepairOrder.Read() ) { this.dtpOrderDate.Value = rdrRepairOrder.GetDateTime(1); this.dtpOrderTime.Value = rdrRepairOrder.GetDateTime(2); this.txtCustomerName.Text = rdrRepairOrder.GetString(3); this.txtAddress.Text = rdrRepairOrder.GetString(4); this.txtCity.Text = rdrRepairOrder.GetString(5); this.txtState.Text = rdrRepairOrder.GetString(6); this.txtZIPCode.Text = rdrRepairOrder.GetString(7); this.txtMake.Text = rdrRepairOrder.GetString(8); this.txtModel.Text = rdrRepairOrder.GetString(9); this.txtCarYear.Text = rdrRepairOrder.GetSqlInt16(10).ToString(); this.txtProblem.Text = rdrRepairOrder.GetString(11); this.txtPartName1.Text = rdrRepairOrder.GetString(12); this.txtUnitPrice1.Text = rdrRepairOrder.GetSqlDecimal(13).ToString(); this.txtQuantity1.Text = rdrRepairOrder.GetSqlByte(14).ToString(); this.txtSubTotal1.Text = rdrRepairOrder.GetSqlDecimal(15).ToString(); this.txtPartName2.Text = rdrRepairOrder.GetString(16); this.txtUnitPrice2.Text = rdrRepairOrder.GetSqlDecimal(17).ToString(); this.txtQuantity2.Text = rdrRepairOrder.GetSqlByte(18).ToString(); this.txtSubTotal2.Text = rdrRepairOrder.GetSqlDecimal(19).ToString(); this.txtPartName3.Text = rdrRepairOrder.GetString(20); this.txtUnitPrice3.Text =

105 | P a g e

rdrRepairOrder.GetSqlDecimal(21).ToString(); this.txtQuantity3.Text = rdrRepairOrder.GetSqlByte(22).ToString(); this.txtSubTotal3.Text = rdrRepairOrder.GetSqlDecimal(23).ToString(); this.txtPartName4.Text = rdrRepairOrder.GetString(24); this.txtUnitPrice4.Text = rdrRepairOrder.GetSqlDecimal(25).ToString(); this.txtQuantity4.Text = rdrRepairOrder.GetSqlByte(26).ToString(); this.txtSubTotal4.Text = rdrRepairOrder.GetSqlDecimal(27).ToString(); this.txtPartName5.Text = rdrRepairOrder.GetString(28); this.txtUnitPrice5.Text = rdrRepairOrder.GetSqlDecimal(29).ToString(); this.txtQuantity5.Text = rdrRepairOrder.GetSqlByte(30).ToString(); this.txtSubTotal5.Text = rdrRepairOrder.GetSqlDecimal(31).ToString(); this.txtJobPerformed1.Text = rdrRepairOrder.GetString(32); this.txtJobPrice1.Text = rdrRepairOrder.GetSqlDecimal(33).ToString(); this.txtJobPerformed2.Text = rdrRepairOrder.GetString(34); this.txtJobPrice2.Text = rdrRepairOrder.GetSqlDecimal(35).ToString(); this.txtJobPerformed3.Text = rdrRepairOrder.GetString(36); this.txtJobPrice3.Text = rdrRepairOrder.GetSqlDecimal(37).ToString(); this.txtJobPerformed4.Text = rdrRepairOrder.GetString(38); this.txtJobPrice4.Text = rdrRepairOrder.GetSqlDecimal(39).ToString(); this.txtJobPerformed5.Text = rdrRepairOrder.GetString(40); this.txtJobPrice5.Text = rdrRepairOrder.GetSqlDecimal(41).ToString(); this.txtTotalParts.Text = rdrRepairOrder.GetSqlDecimal(42).ToString(); this.txtTotalLabor.Text = rdrRepairOrder.GetSqlDecimal(43).ToString(); this.txtTaxRate.Text = rdrRepairOrder.GetSqlDecimal(44).ToString(); this.txtTaxAmount.Text = rdrRepairOrder.GetSqlDecimal(45).ToString(); this.txtTotalOrder.Text = rdrRepairOrder.GetSqlDecimal(46).ToString(); this.txtRecommendations.Text = rdrRepairOrder.GetString(47); } rdrRepairOrder.Close(); conDatabase.Close(); } 2. Execute the application 3. In the bottom receipt number text box, type 1 and click Open 4. Close the form and return to your programming environment

P a g e | 106

107 | P a g e

SQL

Operators and Operands

Expressions
Introduction
An expression is value combined with a symbol to produce a new value. To make this possible, an expression may involve at least one value, the name of a column or else with one of the operators we have used in the previous lesson or one of those we will review here. There is no specific formula to follow: The formulation of an expression depends on the operator(s) and the operand(s) involved. To use an expression in your Windows Forms Application, you can write one of the expressions we will studying, pass it to a MySqlCommand object, and execute it.

PRINT Something
If you are working in the SQL Query Analyzer and you want to display something in plain text as a result of a statement, type PRINT followed by what to display. Therefore, PRINT uses the following formula: PRINT WhatToPrint The item to display can be anything that is allowed and it is provided on the right side of PRINT. If it is a normal (called a constant) number, simply type it on the right side of PRINT. Here is an example:

The item to display can also be an operation or the result of an operation as we will learn in this lesson. If you want to display a character, a word, or a sentence, include it between singlequotes. You can also display an expression as a combination of number(s) and sentences as we will learn later.

P a g e | 108

Here is another example:

Unary Operators
The Positive Operator +
Algebra uses a type of ruler to classify numbers. This ruler has a middle position of zero. The numbers on the left side of the 0 are referred to as negative while the numbers on the right side of the rulers are considered positive: - -6 -6 -5 -5 -4 -4 -3 -3 -2 -2 -1 0 -1 1 2 3 4 5 6 + 1 2 3 4 5 6 +

A value on the right side of 0 is considered positive. To express that a number is positive, you can write a + sign on its left. Examples are +4, +228, +90335. In this case the + symbol is called a unary operator because it acts on only one operand. The positive unary operator, when used, must be positioned on the left side of its operand, never on the right side. As a mathematical convention, when a value is positive, you do not need to express it with the + operator. Just writing the number without any symbol signifies that the number is positive. Therefore, the numbers +4, +228, and +90335 can be, and are better, expressed as 4, 228, 90335. Because the value does not display a sign, it is referred as unsigned as we learned in the previous lesson. To express a variable as positive or unsigned, you can just type it. here is an example: SELECT +1250

The Negative Operator As you can see on the above ruler, in order to express any number on the left side of 0, it must be appended with a sign, namely the - symbol. Examples are -12, -448, -32706. A value

109 | P a g e

accompanied by - is referred to as negative. The - sign must be typed on the left side of the number it is used to negate. Remember that if a number does not have a sign, it is considered positive. Therefore, whenever a number is negative, it MUST have a - sign. In the same way, if you want to change a value from positive to negative, you can just add a sign to its left. Here is an example that uses two variables. One has a positive value while the other has a negative value: SELECT -1250

Arithmetic Operators

Introduction
We have seen that the SELECT keyword can be used to create a list of isolated columns. These columns are rendered separate of each other. Instead of having separate columns, you can combine them to create a string or a value that is in fact an expression. For example, you can combine a first name and a last name to create a full name. An expression that combines columns can be performed on text-based columns. such as a first name being added to a last name to get a full name. Another expression can use a date on the table, add a number to it to get a date on another day. An expression can also be used to perform a calculation on two or more columns such as employees weekly hours multiplied by their hourly salary to get their weekly salary.

The Addition +
The addition can be used to add one value to another or to add a constant to the values of a column. Imagine you have create a table that allows employees to enter their daily hours as a time sheet as follows:

P a g e | 110

Imagine that, at the end of a certain week, some employees submitted their times as follows:

To calculate the total time for each employee, you can add the values of the weekdays using the addition operator. Here is an example:

111 | P a g e

The order you use to add two or more values doesn't matter. This means Value1 + Value2 is the same as Value2 + Value1. In the same way a + b + c is the same as a + c + b the same as b + a + c and the same as c + b + a. This means that the addition is associative.

The Subtraction
The subtraction operation, sometimes called the difference, is used to take out or subtract one value from another value. It is essentially the opposite of the addition. The subtraction is performed with the - sign. Here is an example: SELECT 1240 - 608 Unlike the addition, the subtraction operation is not associative. This means that a - b - c is not necessarily equal to c - b - a. This is illustrated in the following statements: SELECT 128 - 42 - 5 SELECT 5 - 42 - 128 Notice that both operations of the addition convey the same result. In the subtraction section, the numbers follow the same order but a different operation; and the last two operations render different results.

The Multiplication *
The multiplication can be used to multiply each value of a column to a constant number. You can also use it to multiply the value of one column to the corresponding value of another column. Imagine you have created a table used to hold payroll information for employees as follows:

P a g e | 112

Imagine a few employees have submitted their times as follows:

To get the weekly salary of each employee, you can multiply the WeeklyHours column by the HourlySalary and get the result. Here is an example:

113 | P a g e

The Division
The division operation is similar to cutting an item in pieces or fractions of a set value. Therefore, the division is used to get the fraction of one number in terms of another. The division is performed with the forward slash /. Here is an example: SELECT 128 / 42 This would produce 3 When performing the division, be aware of its many rules. Never divide by zero (0). Make sure that you know the relationship(s) between the numbers involved in the operation.

The Modulo
In the above division, 128/42, the result is 3. When you multiply 42 by 3, as in 42*3, you get 126. In some cases, you may be interested in knowing the amount that was left out after the operation. The modulo operation is used to get the remainder of a division as a natural number. The remainder operation is performed with the percent sign (%). Here is an example: PRINT 128 % 42 This would produce 2

Parentheses
Like most computer languages, Transact-SQL uses parentheses to isolate a group of items that must be considered as belonging to one entity. For example, as we will learn soon, parentheses allow a function to delimit the list of its arguments. Parentheses can also be used to isolate an operation or an expression with regards to another operation or expression. For example, when studying the algebraic operations, we saw that the subtraction is not associative and can lead to unpredictable results. In the same way, if your operation involves various operators such as a mix of addition(s) and subtraction(s), you can use parentheses to specify how to proceed with the operations, that is, what operation should (must) be performed first. Here is an example: PRINT (154 - 12) + 8 PRINT 154 - (12 + 8) This would produce: 150 134 As you can see, using the parentheses controls how the whole operation would proceed. This difference can be even more accentuated if your operation includes 3 or more operators and 4 or more operands.

Bit Manipulations
Introduction
When you use a value in your database or application, the value must be stored somewhere in the computer memory using a certain amount of space. As we review in our study of bytes and words, a value occupies space that resembles a group of small boxes. In our human

P a g e | 114

understanding, it is not always easy to figure out how a letter such as as B is stored in 7 seven small boxes when we know that B is only one letter. Bit manipulation or a bit related operation allows you to control how values are stored in bits. This is not an operation you will need to perform very often, especially not in the early stages of your database. Nevertheless, bit operations (and related overloaded operators) are present in all or most programming environments, so much that you should be aware of what they do or what they offer.

Bits Operators: The Bitwise NOT Operator ~


One of the operations you can perform on a bit consists of reversing its value. That is, if a bit holds a value of 1, you may want to change it to 0 and vice-versa. This operation can be taken care of by the bitwise NOT operator that is represented with the tilde symbol ~ The bitwise NOT is a unary operator that must be placed on the left side of its operand as in ~Value Here is an example: PRINT ~158 To perform this operation, the Transact-SQL interpreter considers each bit that is part of the operand and inverts the value of each bit from 1 to 0 or from 0 to 1 depending on the value the bit is holding. This operation can be resumed in the following table:

Bit 1 0

~Bit 0 1

Consider a number with a byte value such as 248. In our study of numeric systems, we define how to convert numbers from one system to another. Based on this, the binary value of decimal 248 is 1111 1000 (and its hexadecimal value is 0xF8). If you apply the bitwise NOT operator on it to reverse the values of its bits, you would get the following result:

Value 1 ~Value 0

1 0

1 0

1 0

1 0

0 1

0 1

0 1

Bits Comparison: The Bitwise AND Operator &


The bitwise & is a binary operator that uses the following syntax Operand1 & Operand2 This operator considers two values and compares the bit of each with the corresponding bit of the other value. If both corresponding bits are 1, the comparison produces 1. Otherwise, that is, if either bit is 0, the comparison produces 0. This comparison is resumed as follows:

Bit1 0 1 0 1

Bit2 0 0 1 1

Bit1 & Bit2 0 0 0 1

Imagine you have two byte values represented as 187 and 242. Based on our study of numeric systems, the binary value of decimal 187 is 1011 1011 (and its hexadecimal value is

115 | P a g e

0xBB). The binary value of decimal 242 is 1111 0010 (and its hexadecimal value is 0xF2). Lets compare these two values bit by bit, using the bitwise AND operator:

N1 N2 N1 & N2

1 1 1

0 1 0

1 1 1

Binary 1 1 1 0 1 0

0 0 0

1 1 1

1 0 0

Decimal 187 242 178

Most of the times, you will want the interpreter to perform this operation and use the result in your program. This means that you can get the result of this operation and possibly display it to the user. The above operation can be performed by the following program: PRINT 187 & 242 This would produce 178

Bits Comparison: The Bitwise OR Operator |


You can perform another type of comparison on bits using the bitwise OR operator that is represented by |. Its syntax is: Value1 | Value2 Once again, the interpreter compares the corresponding bits of each operand. If at least one of the equivalent bits is 1, the comparison produces 1. The comparison produces 0 only if both bits are 0. This operation is resumed as follows:

Bit1 0 1 0 1

Bit2 0 0 1 1

Bit1 | Bit2 0 1 1 1

Once again, lets consider decimals 187 and 242. Their bitwise OR comparison would render the following result:

N1 N2 N1 | N2

1 1 1

0 1 1

1 1 1

Binary 1 1 1 0 1 1

0 0 0

1 1 1

1 0 1

Decimal 187 242 251

You can also let the compiler perform the operation and produce a result. Here is an example: PRINT 187 | 242 This would produce 251

Bits Comparison: The Bitwise-Exclusive XOR Operator ^


Like the previous two operators, the bitwise-exclusive OR operator performs a bit comparison of two values. It syntax is: Value1 ^ Value2 The compiler compares the bit of one value to the corresponding bit of the other value. If one of the bits is 0 and the other is 1, the comparison produces 1. In the other two cases, that is, if

P a g e | 116

both bits have the same value, the comparison produces 0. This operation is resumed as follows:

Bit1 0 1 0 1

Bit2 0 0 1 1

Bit1 ^ Bit2 0 1 1 0

We will again consider decimals 187 and 242. Their bitwise-exclusive XOR comparison would render the following result:

N1 N2 N1 ^ N2

1 1 0

0 1 1

1 1 0

Binary 1 1 1 0 0 1

0 0 0

1 1 0

1 0 1

Decimal 187 242 73

If the interpreter performs this operation, it can produce a result as in the following example: PRINT 187 ^ 242; This would produce 73

Logical Operators
Negation Operator: NOT
In reverse, you may want to use a rule that exclude your criterion and produces only those records that don't follow the rule. For example, you may want to see the list of your customers but excluding those who live in Mexico. To negate a condition, you can start it with the NOT operator. The condition in this case would become NOT (Country = 'Mexico'). Here is an example:

117 | P a g e

Pattern Operator: LIKE


The comparison and the negation operators we reviewed above usually expect exact matches during their comparisons. For example, when a WHERE condition is formulated as Country = 'Mexico', the interpreter would look for a string under the Country column that exactly display Mexico and Mexico only. In some cases, you know know only the starting characters of a string, only the middle characters of a string, or only the ending characters of a string. The SQL allows you to look for a string that begins, contains, or ends with a few characters. The character or group of characters you provide is referred to as a pattern. To use a pattern as criterion to look for in the values of a column, you can use the LIKE operator in your WHERE condition. The formula used by this operator is: ExpressionToMatch LIKE Pattern The ExpressionToMatch placeholder of this formula can be the name of a column whose values would be examined. The Pattern placeholder is an expression that would be looked for. To create a pattern, the LIKE operator uses wildcards. A wildcard is a placeholder in which you provide one or more characters. One of the wildcards used to create a pattern is %. This is used as a placeholder for any character. For example, imagine that you want to find a list of your customers who live in a city whose name starts with M. In this case, any (number of) characters on the right side of M can be represented with the % placeholder. The condition would be formulated as follows: SELECT * FROM Customers WHERE City LIKE 'M%'

P a g e | 118

In the same way, you can use the % wildcard to specify the starting or the middle characters of a string. Another wildcard used is the underscore _. Like the % wildcard, the underscore character is used as a placeholder but for only one character. Here is an example:

119 | P a g e

Instead of the underscore, you can use a combination of the opening and the closing square brackets [] as a placeholder for a single character. While the underscore placeholder is used for any character, the difference with the square brackets is that, this time, you can specify the particular alphabetic-based ranged of characters you want to use. To specify the range or characters, between the square brackets, type both ending letters of the range separated by a dash character as in [a-e]. Another variance of the single character placeholder is the ^ used between the square brackets. It is used to exclude characters of the specified range. An example would be [^a-e]. This would produce a list of strings that don't start with either a, b, c, d, or e. You can use combinations of these wildcards to create more precise patterns. To negate a condition resulting from a LIKE pattern, you can use the NOT operator on the left side of LIKE as in NOT LIKE.

Logical Conjunction: The AND Operator


Imagine that you are reviewing the students records of a school and you want to make sure that you know whom to contact in case of emergency for each student. For example, imagine that you are trying to make sure the record of each student provides an emergency telephone number. The statement to evaluate would be: This student's record provides an emergency phone number

If the record of the student referred to contains an emergency phone number, the statement is true. If the record does not provide this information, our goal is not met and the statement is false. Imagine that, on the other hand, we want to find out if the record of each student

P a g e | 120

displays the name to contact in case of emergency. The statement considered would be: This student's record provides an emergency name

If the record considered displays an emergency name, the statement is true. Imagine that a student's record indicates an emergency telephone number but does not provide an emergency name. What if a student's record indicates an emergency name but no emergency telephone number? It appears that in the absence of one of these pieces of information, it would be hard to perform an effective contact. To make a record complete or to accomplish our goal, we want each record to have both an emergency name and an emergency telephone number. We can combine both of the above statements as follows: "This student's record provides an emergency phone number" AND "This student's record provides an emergency name"

Evaluating the combined statement would produce the following results: If the record of the student referred to does not provide an emergency phone number, the record of the student is not complete and our goal is not met, regardless of the second statement. Therefore, the combined statement is false. If the record of the student referred to provides an emergency phone number, then we would consider the second statement. If the record does not provide a name in case of emergency, the record is not complete and our goal is not met. Therefore, the combined statement is false. If the record of the student being considered provides neither an emergency phone number nor an emergency name, the record is still not complete and our goal is not met. Therefore, the combined statement is false. If the record of the student being considered provides both an emergency telephone number and an emergency name, we consider that the record is complete and our goal is met. Therefore, the combined statement is true.

To resume, our goal is met only if BOTH the first and the second statement are TRUE. This is done using the AND operator.

Logical Disjunction: The OR Operator


Imagine that our main goal is to make sure that we have a number we can use to contact somebody for the student. In this case, either the home phone number or the emergency number would be fine. We already have the following two statements: 1. This student's record indicates a home phone number 2. This student's record provides an emergency phone number To get either number, we can concatenate these two statements and evaluate the truthfulness of either one of them. We create a new statement as follows: "This student's record indicates a home phone number" OR "This student's record provides an emergency phone number" The comparative evaluation produces the following results: If the student's record indicates a home phone number, our goal is met and we do not need to evaluate the second statement. Therefore, the combined statement is true. If the student's record does not indicate a home phone number, we can then consider the second statement. If the student's record provides an emergency phone number, we have a number we can use. This means that the result of the first statement is not important. Therefore, the combined statement is true.

121 | P a g e

If the student's record indicates a home phone number and the student's record provides an emergency phone number, our goal is still met; we can use either number. Therefore, the combined statement is true. If the student's record does not indicate a home phone number, then we consider the second statement. If the student's record does not provide an emergency phone number, our goal is not met: we do not have any number to contact somebody for the student in case of emergency. Therefore, the combined statement is false.

The logical disjunction shows us that a combined statement is true if EITHER of its two statements IS TRUE. The logical disjunction produces a false result if BOTH of its two statements are FALSE. To perform a logical disjunction, you can use the OR operator.

Range Test: BETWEEN


If you have a logical range of values and you want to know if a certain exact value is contained in that range, you use the BETWEEN operator. The BETWEEN operator is usually combined with the AND operator to get a list of records between two values. The basic formula of this operator is: Expression BETWEEN Start AND End The Expression placeholder of our formula is usually the name of the column whose values you want to examine. The Start factor is the starting value of the range to consider. The End factor is the highest value to consider in the range. After this condition is executed, it produces the list of values between Start and End. As an example, if you are creating some groups of students for activities, imagine that one group would have students from ID 54 to 72. You would write the WHERE condition as follows: SELECT StudentID, StudentNbr, Gender, LastName, FirstName, DateOfBirth FROM Students WHERE StudentID BETWEEN 54 AND 72

The IS Operator
To validate something as being possible, you can use the IS operator. For example, to

P a g e | 122

acknowledge that something is NULL, you can use the IS NULL expression. In the same way, to validate that something is not null, you can use the expression IS NOT NULL. Here is an example that displays the list of students whose records don't show the emergency name:

Comparison Operators: IN
If you have a series of records and want to find a record or a group of records among them, you can use the IN operator. SQL provides many and many other operators that we have not reviewed here.

123 | P a g e

Relationships and Data Integrity

The Keys to a Good Relationship


Relational Databases
Imagine you are asked to create an application that allows a company to rent cars to potential customers. You may start by creating a list of cars that would be made available to customers. The list may include the type (make, model, and year) and of the car and other pieces of information such as options (CD, AC, DVD, etc) that would be of interest to some of the customers. Here is an example of such a list: Car Make Model Year HasCDPlayer Dodge Neon 2004 Yes

HasDVDPlayer No

P a g e | 124

When a new customer comes to the store to rent a car, the company clerk would need some of the customer's personal information to keep track of who has the car. The information about the customer may include her name, address, driver's license number, etc. The list of information about the customer may appear as follows: Customer Name Address HomePhone Once this information is collected, the clerk can present the available cars and their rental rates to the customer so she can select the type of car she wants. The clerk would also be interested to know how long the customer intends to keep the car. After using the car, the customer would bring it back to the store so the car can be made available to other customers. When creating this application, you may be tempted to enter information about the car in the same list that includes the customer's information: Customer Name Address HomePhone Car Rented Make Model Year HasCDPlayer HasDVDPlayer Dodge Neon 2004 Yes No Janice Lalas 1402 Lamer Lane Driver's License Number L-793-475-904 Janice Lalas 1402 Lamer Lane Driver's License Number L-793-475-904

The problem here is that, when a different customer comes to rent the same car, the clerk would have to enter the same pieces of information. Experience shows that when the same information is manually entered over and over again, it could be different from one list to another as human being are capable of making mistakes. The solution is to create separate lists: one list for the customers, another list for the cars. When a customer comes to rent a car, the clerk can select the customer's information from one list, select the information about the car from another list, and then process a rental order. This technique tremendously reduces the likelihood of making mistakes because information about each item, whether a customer or a car, is created only once and then made available to other lists that would need that information: this is the foundation of relational databases: A relational database is an application in which information flows from one list to another. Microsoft SQL Server, like most database environments, is a relational database system: It allows you to create tables and link them so they can exchange information among themselves.

Practical Learning: Starting a Relational Database Application


1. Start Microsoft Visual Studio .NET or Visual C# 2. Display the Server Explorer. Expand the Servers node, followed by the name of the computer, followed by SQL Servers, followed by the name of the server

125 | P a g e

3. Right-click the server and click New Database 4. Set the New Data Name to BCR (BCR stands for Bethesda Car Rental) and accept to use
Windows NT Persist Security Info 5. Click OK

The Primary Key


The transactions among various objects of a database should make sure information of one object is accessible to another object. The objects that hold information, as we have mentioned already, are the tables. To manage the flow of information from one table (A) to another table (B), the table that holds the information, A, must make it available to other tables, such as B. There are two issues that must be dealt with:

1. Each record that a table (A) holds should/must be unique among all the other records of
the same table (A). For example, if a clerk creates a list of cars on a table, you should make sure that, even when two cars are the exact same type (a car rental company can purchase two to four of the same car at the same time), each car must be uniquely identified so that, when one of them has been rented, the company should know with certainty what car is out and what car is available. 2. A table (A) that holds information must make it available to other tables (such as B). Two tables must not serve the same purpose. For example, you should not have two lists of cars that hold information about the cars that can be rented (you can have different lists of cars; for example, one list may contain the cars that have just been purchased but are not yet registered to be rented, and another list that contains the cars made available for renting but the cars that are available to be rented should be in only one list: this reduces confusion). To solve the first problem of uniquely identifying records inside of a table, in Lesson 15, we saw that you could create one column or a group of columns used as the primary key. In a relational database, which is the case for most of the databases you will be creating in SQL Server, each table should have at least one primary key. To specify a primary key on a table, as we have already done in the past, you create one column as the PRIMARY KEY constraint and there can be only one PRIMARY KEY constraint on a table. To do this in Enterprise Manager, create a column and specify its data type. Then, on the toolbar, click the Set Primary Key button .

To create a primary column using SQL, on the right side of the column definition, type PRIMARY KEY (remember, SQL is case-insensitive). Here is an example: CREATE TABLE Departments ( DepartmentID INT PRIMARY KEY IDENTITY(1,1) NOT NULL, Department VARCHAR(50)) GO

Practical Learning: Creating Tables and their Primary Keys

P a g e | 126

1. In the Server Explorer, expand the BCR node. Right-click the Tables node and click New
Table

2. Specify the first Column Name as RentalRateID, set its Data Type to int 3. To make it the Primary Key constraint, while the field is still selected, on the toolbar, click
the Set Primary Key button

4. While the field is still selected, in the bottom section of the Design Table, set the Identity
field to Yes and accept the Identity Seed and the Identity Increment to 1 each

5. Create the rest of the table as follows:


Column Name RentalRateID Category DailyRate WeeklyRate MonthlyRate WeekendRate Data Type int varchar varchar varchar varchar varchar Length 4 10 10 10 10 Allow Nulls Unchecked

6. Save the table as RentalRates and close it 7. In the Server Explorer, expand the Tables node under BCR and double-click RentalRates

8. Fill it up as follows:
Category Economy Compact Standard Full Size Mini Van SUV Truck Van DailyRate 32.95 39.95 45.95 49.95 55.95 55.95 42.95 69.95 WeeklyRate 29.75 34.75 39.75 42.75 50.95 50.95 35.75 59.75 MonthlyRate 22.95 24.95 35.95 35.95 45.95 45.95 30.95 50.75 WeekendRate 19.95 29.95 34.95 38.95 42.95 42.95 30.95 49.95

9. Close the RentalRates table 10. In the Server Explorer and under BCR, right-click the Tables node and click New Table...

11. Fill the new table as follows:


Column Name EmployeeID (Primary Key) EmployeeNumber FirstName LastName FullName Title Username WorkPhone Extension Data Type int char varchar varchar varchar varchar varchar varchar char 6 32 32 Length Allow Nulls Identity: Yes Properties

Unchecked Formula: LastName + ', ' + FirstName

20 2

127 | P a g e

HourlySalary 12. Close the table

varchar

10

13. When asked whether you want to save it, click Yes

14. Type Employees and press Enter 15. In the Tables node of BCR in the Server Explorer, double-click Employees and create a few
employees as follows:

EmployeeNumber FirstName 22-082 46-288 27-196 66-286 27-284 16. Close the table Daniel Joseph Paula Ellen

LastName Title Ferguson Regional Manager Catalane Brooks Assistant Manager

HourlySalary 28.82 22.64

Pearlman Sales Representative 14.58

Barthelemy Lundquist Sales Representative 12.88 Sales Representative 15.75

17. In the Server Explorer and under BCR, right-click the Tables node and click New Table...

18. Fill the new table as follows:


Column Name CustomerID (Primary Key) DrvLicNbr DrvLicClass DateIssued DateExpired FullName Address City State ZIPCode Country HomePhone OrganDonor Data Type int varchar varchar datetime datetime varchar varchar varchar varchar varchar varchar varchar bit Unchecked Length Allow Nulls Properties Identity: Yes

20 Default Value: 'USA' 20

19. Save the table as Customers and close it 20. In the Tables node of BCR in the Server Explorer, double-click Customers and create a few
customers as follows:

DrvLicNbr 646-856-734P 793-405-719D 294-80-2759 731-249-759S 308-45-7642

DrvLicClass DateIssued DateExpired C C C M C 1/5/2002 1/5/2007

FullName Amy Larsson Anne DeCarlo Chrissie Yuen Scott Salomons Mary Herness

OrganDonor 0 1 0 0 0

4/27/2004 4/27/2009 11/4/2004 11/4/2009 7/24/2003 7/24/2008 4/10/2003 4/10/2008

P a g e | 128

21. Close the table

Foreign Keys
In our introduction to relationships, we illustrated a table that could be used to enter a customer's information and the car he wants to rent: Customer Name Address HomePhone Car Rented Make Model Year HasCDPlayer HasDVDPlayer Dodge Neon 2004 Yes No Janice Lalas 1402 Lamer Lane Driver's License Number L-793-475-904

We also mentioned that it was not effective to put these two categories of information, namely the customer and the car in the same list. The reason is that the same customer may come at different times to rent different types of cars and the same car is regularly rented by different customers. To reduce the likelihood of mistakes, you should separate these two categories, each in its own list: Customers Name Driver's License Number Address Home Phone Cars Make Model Year HasCDPlayer HasDVDPlayer This time, if you keep these two lists separate, when it is time to rent a car to a customer, you can use another list that allows the clerk to select the name of the customer, followed by the car she wants to rent: Customers Name Driver's License Number Address Home Phone Rental Orders Customer Car Rental Rental Rate Cars Make Model Year HasCDPlayer HasDVDPlayer To make this scenario work, there must be a column in the Rental Order list that represents the customers: this would be the Customer column in our illustration. The column that belongs to the Rental Order list but is used to represent the customers is called a foreign key. This column behaves like an ambassador who is not a citizen of the country where he works but instead represents his native country.

129 | P a g e

Because a foreign key is used to represent a table other than the one where it resides, the table that the foreign key represents must have a primary key that would insure the uniqueness of records in the original table. The table that holds the necessary values and that has the primary key can be referred to as the parent table. In our above illustration, the Customers table is the parent. The table that holds the foreign key is referred to as the child table, which is the case for the Rental Orders list of our illustration. To create a foreign key, you can start by adding the necessary column in the table that will need or use it. There are rules and suggestions you should or must follow. As a suggestion, the name of the column used a foreign key should be the same as the primary key of the table it represents. As a rule, the data type of the primary key of the parent table must be the same as the data type of the foreign key. If you are working with SQL code, to create a foreign key, when creating the table, before the closing comma of the name of a column (if the column is not the last in the table) or the closing parenthesis of the table (if the column is the last), you can type REFERENCES followed by the name of the parent table with parentheses. In the parentheses of the name of the parent table, enter the name of the primary key column. Here is an example: CREATE TABLE Departments ( DepartmentID INT PRIMARY KEY IDENTITY(1,1) NOT NULL, Department VARCHAR(50)) GO CREATE TABLE StaffMembers ( EmployeeID INT PRIMARY KEY IDENTITY(1,1) NOT NULL, FullName VARCHAR(50), DepartmentID INT REFERENCES Departments(DepartmentID)) GO When you create a table like this, the interpreter would know that, in the StaffMembers table, the DepartmentID column is a foreign key. If you want to explicitly indicate that the column is a foreign key, you can type FOREIGN KEY before specifying it with REFERENCES. Here is an example: CREATE TABLE StaffMembers ( EmployeeID INT PRIMARY KEY IDENTITY(1,1) NOT NULL, FullName VARCHAR(50), DepartmentID INT FOREIGN KEY REFERENCES Departments(DepartmentID)) GO You can also specify the name of the primary key of the parent table in parentheses you would include following FOREIGN KEY. This can be done as follows: CREATE TABLE StaffMembers ( EmployeeID INT PRIMARY KEY IDENTITY(1,1) NOT NULL, FullName VARCHAR(50), DepartmentID INT FOREIGN KEY(DepartmentID) REFERENCES Departments(DepartmentID)) GO If you are planning to reference the foreign key as an object somewhere in your code, you can give it an explicit name. To do this, when creating a table, type CONSTRAINT followed by the name of the foreign key constraint. Here is an example: CREATE TABLE StaffMembers ( EmployeeID INT PRIMARY KEY IDENTITY(1,1) NOT NULL, FullName VARCHAR(50), DepartmentID INT CONSTRAINT FK_Department FOREIGN KEY(DepartmentID) REFERENCES Departments(DepartmentID)) GO If you are working from the SQL Server Enterprise Manager or from the Server Explorer, to specify that a column is used as a foreign key, you can start by creating a column that has the

P a g e | 130

same name and the same data type as the primary key of the parent table. Then, you can right-click anywhere in the table and click Relationships... This would open the Properties dialog box. To actually create a foreign key, in the Properties dialog box, you can click New. You would be asked to select the primary key from the parent table and the foreign from the child table. A name would be generated by the relationship. Once you are satisfied, you can click Close.

Practical Learning: Creating Foreign Keys


1. In the Server Explorer, under the BCR node, right-click Tables and click New Table

2. Create the columns of the table as follows:


Column Name CarID (Primary Key) TagNumber Make Model CarYear RentalRateID HasK7Player HasCDPlayer HasDVDPlayer Picture Available Notes Data Type int varchar varchar varchar smallint int bit bit bit varchar bit text Length Allow Nulls Properties Identity: Yes

120

Default Value: 'C:\Programs\Unknown.bmp'

3. Save the table as Cars and close it 4. Double-click Cars and create a few cars as follows:
Rental HasK7 HasCD HasDVD Available RateID Player Player Player 4 6 2 1 1 0 0 0 0 1 1 0 0 1 0 0 1 1 0 0

TagNumber Make 294-759 M294668 962-048 348759 Mercury Lincoln

Model Grand Marquis Navigator

CarYear 2002 2004 2002 2003

Hyundai Elantra Hyundai Accent

5. To create a new table, right-click the Tables node of BCR and click New Table

6. Fill it up as follows:
Column Name EmployeeID CustomerID CarID CarCondition TankLevel Mileage Data Type int int int varchar varchar int Length Allow Nulls Properties Identity: Yes Unchecked Unchecked Unchecked

RentalOrderID (Primary Key) int

131 | P a g e

StartDate EndDate NumberOfDays RateApplied SubTotal TaxRate TaxAmount RentTotal Notes

datetime datetime smallint decimal decimal decimal decimal decimal text Default Value: 0 Default Value: 20.00 Scale: 4 Default Value: 0.00 Scale: 4 Scale: 2 Default Value: 5.75 Default Value: 0.00 Scale: 4 Default Value: 20.00 Scale: 4

7. Save the table as RentalOrders and close it 8. Make sure the Cars table displays in design.
Right-click somewhere in the table and click Relationships...

9. In the Relationships property page, click the New button 10. In the Primary Key Table combo box, select RentalRates 11. In the first combo box of the grid under RentalRates, select RentalRateID

12. In the Foreign Key Table combo box, select Cars (it should be selected already)

Click the grid under Cars to reveal a combo box. In the combo box, select RentalRateID

13. Click Close 14. Close the table. When asked to save, click Yes and Yes

P a g e | 132

Diagrams
If you have created the relationships of your tables using SQL code, you only have a vague idea of the flow of information among them. A diagram is a window that visually displays the relationships among tables of a database. A diagram also allows you to troubleshoot a relation when necessary. The Diagram window provides all the tools you need to create, view, change, delete or maintain relationships. To create a diagram, if you are working from the SQL Server Enterprise Manager, in the node of the database, you can right-click the Diagrams node and click New Database Diagram. This would launch the Create Database Diagram Wizard that you can follow to select the necessary tables. Once in the Diagram window, each table displays as a rectangle with dividing lines like a spreadsheet:

To effectively work on the tables, you should make sure you can identify each. If the view makes it difficult, you can zoom it. To do this, you can right-click a white area of the window, position the mouse on Zoom, and select a percentage. You can also click the Zoom button on the toolbar. Each table is equipped with a title bar on top that displays its name. If you forgot to add a table, you can right-click a white area in the window and click Add Table... This would display the list of tables of the same database, allowing you to select the desired table(s) before clicking Add and then Close. If you had added a table by mistake or you don't want to include an existing table in the diagram, to remove a table, you can right-click the table and click Remove Table From Diagram. To move a table, you drag its title bar. To create a relationship between two tables, you can right-click anywhere in the diagram and click Relationships... You would then proceed as we did in the section on Foreign Keys. To create or indicate a foreign key, you can drag the necessary column from a parent table to a child table. Once a relationship between two tables exists, there is a line that joins them. You can then manage the relationship. To identify a relationship, you can position the mouse on the line that joins the table:

133 | P a g e

To delete a relationship, you can right-click it and click Delete Relationship From Database.

Practical Learning: Creating Foreign Keys


1. In the Server Explorer, under the BCR node, right-click Database Diagrams and click New Diagram...

2. In the Add Table dialog box, click each table and click Add

3. When all tables have been added, click Close on the Add Table dialog box

4. Position the tables as follows:

P a g e | 134

5. Click the gray box on the left of the EmployeeID field in the Employees table.

Click and drag that box then drop it on the EmployeeID field of the RentalOrders table:

6. On the Create Relationship dialog box, make sure EmployeeID is selected for the

Employees Primary Key Table and that EmployeeID is selected for the RentalOrders Foreign Key Table

135 | P a g e

7. Click OK 8. To save the diagram, on the toolbar, click the Save button 9. Type BCRMap as the name of the diagram and press Enter 10. When notified that some tables need to be saved, click Yes

Relationships and Data Integrity


As mentioned in previous sections, relationships allow information to flow from one list, the parent table, to another list, the child table. When maintaining records, sometimes a piece of information may becomes obsolete. An employee may decide to change or to delete it from the parent table. This would cause the relation information in the child table to become orphan. When this happens, you need to take appropriate action. Referential integrity is the ability to take care of necessary details when data from a table gets changed or deleted. When a piece of information is changed in a parent table, you need to make sure that the change is replicated to the related child table. If you are creating or troubleshooting a table using the Design Table from the SQL Server Enterprise Manager or from Server Explorer, after displaying the Create Relationship or the Property Pages, you can click the Cascade Update Related Fields check box. If a piece of information is deleted in a parent, the records of the child table(s) that depended on it should be notified. If you are working from a table in the Design Table from the SQL Server Enterprise Manager or from Server Explorer, after displaying the Create Relationship or the Property Pages, you can click the Cascade Delete Related Records check box.

Practical Learning: Insuring Referential Integrity


1. The Diagram window should still be displaying Right-click the line between RentalRates and Cars and click Properties (SQL Server) or Property Pages (Visual Studio .NET)

P a g e | 136

2. In the Relationship tab of the Property Pages, make sure the FK_Cars_RentalRates item is
selected in the Selected Relationship combo box. In the bottom section, click the Cascade Update Relation Fields and the Cascade Delete Related Records check boxes

3. Click Close 4. In the same way, right-click the line between the Employees and the RentalOrders tables and click Properties. Click both bottom check boxes and click Close 5. Drag CarID from the Cars table and drop it on CarID from the RentalOrders table

137 | P a g e

6. In the Create Relationship dialog box, click both bottom check boxes

7. Click OK 8. Drag CustomerID from the Customers table and drop on CustomerID from the RentalOrders table

9. In the Create Relationship dialog box, click both bottom check boxes

10. Click OK

P a g e | 138

11. To save the diagram, on the toolbar, click the save button

12. After reading the message box, click Yes

13. Close the Diagram window and any table that is opened

Windows Applications and Database Relationships


When creating an application that uses a database with related tables, to allow the user to select information from parent tables when using forms from child tables, you would configure list-based controls to get their data from the parent tables.

Practical Learning: Creating the Windows Application


1. Open Windows Explorer or My Computer and create a folder named Programs on the C: drive

2. Open Paint (Start . Programs . Accessories . Paint) and paste the following picture:

3. Save it as Unknown.bmp in the C:\Programs folder 4. Return to Microsoft Visual C++ .NET and create a new Windows Forms Application named
BCR4 5. To create a new form, on the main menu, click Project . Add New File...

6. In the New File dialog box, click Windows Form and set its Name to Employees
7. In Server Explorer, under the BCR database, expand the Tables node. Drag Employees and drop it on the form 8. To create a data set, on the main menu, click Data . Generate Dataset...

9. Accept the New radio button. Change the name to dsBCR and click OK 139 | P a g e

10. Design the form as follows:

Control DataGrid Button

Name

Text/CaptionText

Other Properties

Anchor:Top, Bottom, Left, Right Employees Records Auto Format: Colorful 2 DataSource: dsBCR1 btnClose Close Anchor:Bottom, Right

11. Double-click an unoccupied area of the form and implement the event as follows:
private: System.Void Employees_Load(System.Object * sender, System.EventArgs * e) { this.sqlDataAdapter1.Fill(this.dsBCR1); } 12. Return to the form and click the DataGrid 13. In the Properties window, click the Events button and double-click the right field to CurrentCellChanged

14. Implement the event as follows:


private: System.Void dataGrid1_CurrentCellChanged(System.Object * sender, System.EventArgs * e) { this.sqlDataAdapter1.Update(this.dsBCR1); } 15. Return to the form and double-click the Close button

16. Implement its event as follows:


private: System.Void btnClose_Click(System.Object * sender, System.EventArgs * e) { Close(); } 17. Save all 18. To create a new form, on the main menu, click Project . Add New File...

19. In the New File dialog box, click Windows Form and set its Name to Customers P a g e | 140

20. Design the form as follows:

Control TabPage Label TextBox Label TextBox Label TextBox Label

Name pgeCustomers txtCustomerID

Text Customers Customer ID: Drv License #:

Other Properties

txtDrvLicNbr Class: txtDLClass Date Issued: Format: Short Exp. Date: Format: Short Full Name: txtFullName Address: txtAddress City: txtCity State: txtState ZIP Code: txtZIPCode

DateTimePicker dtpDateIssued Label DateTimePicker dtpExpDate Label TextBox Label TextBox Label TextBox Label TextBox Label TextBox

141 | P a g e

Label TextBox Label TextBox CheckBox Button Button Button Button Button Button txtHomePhone txtCountry

Country: Home Phone: chkOrganDonor Organ Donor? btnFirst btnPrevious btnNext btnLast btnLoad btnClose First Previous Next Last Load Close CheckAlign: MiddleRight

Control TabControl TabPage Label TextBox Label TextBox Label

Name tabCustomers pgeCustomers txtNCDrvLicNbr

Text Customers Drv License #: Class:

Other Properties

txtNCDLClass Date Issued: Format: Short Exp. Date: Format: Short Full Name: txtNCFullName Address:

DateTimePicker dtpNCDateIssued Label DateTimePicker dtpNCExpDate Label TextBox Label

P a g e | 142

TextBox Label TextBox Label TextBox Label TextBox Label TextBox Label TextBox CheckBox Button Button

txtNCAddress City: txtNCCity State: txtNCState ZIP Code: txtNCZIPCode Country: txtNCCountry Home Phone: txtNCHomePhone chkNCOrganDonor Organ Donor? btnReset btnCreate Reset Create CheckAlign: MiddleRight

21. On the form click the Customers tab and click an empty area of its box. For example, click the area just below the Notes label 22. In Server Explorer, from the Tables node of the BCR database, drag Customers and drop it inside the Customers tab page. For example, drop it just below the Notes label 23. To create a data set, on the main menu, click Data . Generate Dataset...

24. Accept the Existing radio button with the dsBCR name and click OK 25. Bind the controls using the following table:
DataBinding Control Type Value: dsBCR1 Customers. CustomerID DrvLicNbr DrvLicClass DateIssued DateExpired FullName Address City State ZIPCode Country HomePhone

txtCustomerID Text txtDrvLicNbr txtDLClass dtpDateIssued dtpExpDate txtFullName txtAddress txtCity txtState txtZIPCode txtCountry txtHomePhone Text Text Value Value Text Text Text Text Text Text Text

chkOrganDonor Checked OrganDonor

26. Double-click the Load button of the form and implement the event as follows:
System.Void btnLoad_Click(System.Object * sender, System.EventArgs * e) { this.sqlDataAdapter1.Fill(this.dsBCR1); }

143 | P a g e

27. Return to the form. Double-click the First button and implement its Click event as follows:
System.Void btnFirst_Click(System.Object * sender, System.EventArgs * e) { this.pgeCustomers.BindingContext.get_Item(this.dsBCR1, "Customers").Position = 0; this.sqlDataAdapter1.Update(this.dsBCR1); }

28. Return to the form. Double-click the Previous button and implement its Click event as
follows:

private: System.Void btnPrevious_Click(System.Object * sender, System.EventArgs * e) { this.pgeCustomers.BindingContext.get_Item(this.dsBCR1, "Customers").Position = this.pgeCustomers.BindingContext.get_Item(this.dsBCR1, "Customers").Position - 1; this.sqlDataAdapter1.Update(this.dsBCR1); }

29. Return to the form. Double-click the Next button and implement its Click event as follows:
private: System.Void btnNext_Click(System.Object * sender, System.EventArgs * e) { this.pgeCustomers.BindingContext.get_Item(this.dsBCR1, "Customers").Position = this.pgeCustomers.BindingContext.get_Item(this.dsBCR1, "Customers").Position + 1; this.sqlDataAdapter1.Update(this.dsBCR1); }

30. Return to the form. Double-click the Last button and implement its Click event as follows:
private: System.Void btnLast_Click(System.Object * sender, System.EventArgs * e) { this.pgeCustomers.BindingContext.get_Item(this.dsBCR1, "Customers").Position = this.pgeCustomers.BindingContext.get_Item(this.dsBCR1, "Customers").Count - 1; this.sqlDataAdapter1.Update(this.dsBCR1); } 31. Return to the form and double-click the Close button

32. Implement its event as follows:


private: System.Void btnClose_Click(System.Object * sender, System.EventArgs * e) { Close(); } 33. Save all 34. Return to the form and click the New Customer tab

35. In the New Customer page, double-click the Reset button and implement its Click event as
follows:

private: System.Void btnReset_Click(System.Object * sender, System.EventArgs * e)

P a g e | 144

this.txtNCDrvLicNbr.Text = ""; this.txtNCDLClass.Text = "C"; this.dtpNCDateIssued.Value = DateTime.Today; this.dtpNCExpDate.Value = DateTime.Today; this.txtNCFullName.Text = ""; this.chkNCOrganDonor.Checked = false; this.txtNCAddress.Text = ""; this.txtNCCity.Text = ""; this.txtNCState.Text = "MD"; this.txtNCZIPCode.Text = ""; this.txtNCCountry.Text = "USA"; this.txtNCHomePhone.Text = "(000) 000-0000"; this.txtNCDrvLicNbr.Focus();

36. Return to the form and double-click the Create button

37. Implement its Click event as follows:


System.Void btnCreate_Click(System.Object * sender, System.EventArgs * e) { string strDrvLicNbr = this.txtNCDrvLicNbr.Text; string strFullName = this.txtNCFullName.Text; if( strDrvLicNbr= "" ) { MessageBox.Show("You must provide the customer's driver's license number"); return; } if( strFullName= "" ) { MessageBox.Show("You must provide the customer's name"); return; } string strInsert = String.Concat("INSERT INTO Customers(DrvLicNbr, DrvLicClass, " "DateIssued, DateExpired, FullName, Address, " "City, State, ZIPCode, Country, HomePhone, " "OrganDonor) VALUES('", this.txtNCDrvLicNbr.Text, "', '", txtNCDLClass.Text, "', '", dtpNCDateIssued.Value, "', '", dtpNCExpDate.Value, "', '", txtNCFullName.Text, "', '", txtNCAddress.Text, "', '", txtNCCity.Text, "', '", txtNCState.Text, "', '", txtNCZIPCode.Text, "', '", txtNCCountry.Text, "', '", txtNCHomePhone.Text, "', '", this.chkNCOrganDonor.Checked, "');"); MySql.Data.MySqlClient.MySqlCommand cmdNewCustomer = new MySql.Data.MySqlClient.MySqlCommand(strInsert, this.MySqlConnection1); MySqlConnection1.Open(); cmdNewCustomer.ExecuteNonQuery(); MySqlConnection1.Close();

145 | P a g e

this.btnReset_Click(sender, e); } 38. Save all 39. To create a new form, on the main menu, click Project . Add New File...

40. In the New File dialog box, click Windows Form and set its Name to RentalRates
41. In Server Explorer, in the Tables node of the BCR database, drag RentalRates and drop it on the form 42. To create a data set, on the main menu, click Data . Generate Dataset...

43. Accept the Existing radio button with the dsBCR name and click OK 44. Design the form as follows:

Control

Text/CaptionText

Other Properties Auto Format: Colorful 2 DataSource: dsBCR1 Dock: Fill FormBorderStyle: SizableToolWindow ShowInTaskbar: False StartPosition: Manual TopMost: True

DataGrid Employees Records

Form

Bethesda Car Rental

45. In the combo box above the Properties window, select RentalRates. In the Events section
of the Properties window, double-click to the right of Load and implement the event as follows:

private: System.Void RentalRates_Load(System.Object * sender, System.EventArgs * e) { this.sqlDataAdapter1.Fill(this.dsBCR1); } 46. Save all 47. To create a new form, on the main menu, click Project . Add New File...

48. In the New File dialog box, click Windows Form and set its Name to Cars 49. Design the form as follows:

P a g e | 146

Control TabControl TabPage Label TextBox Label TextBox Label TextBox Label TextBox Label TextBox Label ComboBox CheckBox CheckBox CheckBox CheckBox PictureBox Button TextBox Label

Name tabCars pgeCars txtTagNumber

Text Cars Details Tag #: Car ID:

Other Properties

txtCarID Make: txtMake Model: txtModel Year txtYear: Category: cboRentalRateID chkK7Player chkDVDPlayer chkCDPlayer chkAvailable pctCar btnPicture txtPicture Picture C:\Programs\Unknown.bmp Notes: Cassette Player DVD Player CD Player Available DropDownStyle: DropDownList CheckAlign: MiddleRight CheckAlign: MiddleRight CheckAlign: MiddleRight CheckAlign: MiddleRight

147 | P a g e

TextBox Button Button Button Button Button Button

txtNotes btnFirst btnPrevious btnNext btnLast btnLoad btnClose First Previous Next Last Load Close

Multiline: True ScrollBars: Vertical

Control TabPage Label TextBox Label TextBox Label TextBox Label TextBox Label ComboBox CheckBox CheckBox

Name pgeNewCar txtNCTagNumber

Text New Car Tag #: Make:

Other Properties

txtNCMake Model: txtNCModel Year txtNCYear: Category: cboNCRentalRateID chkNCK7Player chkNCDVDPlayer Cassette Player DVD Player DropDownStyle: DropDownList CheckAlign: MiddleRight CheckAlign: MiddleRight

P a g e | 148

CheckBox CheckBox PictureBox Button TextBox Label TextBox Button Button

chkNCCDPlayer chkNCAvailable pctNCar btnNCPicture txtNCPicture

CD Player Available Picture Notes:

CheckAlign: MiddleRight CheckAlign: MiddleRight

txtNCNotes btnReset btnCreate Reset Create

Multiline: True ScrollBars: Vertical

50. On the form click the Cars Details tab and click an empty area of its box. For example, click the area just below the Notes label 51. In Server Explorer, from the Tables node of the BCR database, click Cars to select it. Press and hold Ctrl, then click RentalRates to select both and release Ctrl 52. Drag the selected tables and drop them inside the Cars Details tab page. For example, drop them just below the Notes label 53. To create a data set, on the main menu, click Data . Generate Dataset...

54. Accept the Existing radio button with the dsBCR name. Click the Cars check box and make
sure both check boxes are selected:

55. Click OK

56. Bind the controls using the following table:

Control txtTagNumber txtCarID txtMake txtModel

DataBindings Type Text Text Text Text

Selection: dsBCR1-Cars. TagNumber CarID Make Model

Others

149 | P a g e

txtYear cboRentalRateID chkK7Player chkDVDPlayer chkCDPlayer chkAvailable txtPicture txtNotes

Text SelectedValue Checked Checked Checked Checked Text Text

CarYear RentalRateID HasK7Player HasDVDPlayer HasCDPlayer IsAvailable Picture Notes RentalRateID DataSource: dsBCR1.RentalRates DisplayMember: Category ValueMember: RentalRateID DataSource: dsBCR1.RentalRates DisplayMember: Category ValueMember: RentalRateID

cboNCRentalRateID SelectedValue

57. In the Windows Forms section of the Toolbox, click the OpenFileDialog button and click the form

58. Set its Filter as Picture Files (*.bmp;*.gif;*.jpeg;*jpg)|*.bmp;*.gif;*.jpeg;*jpg


59. On the form, click the Car Details tab and double-click the Picture button

60. Implement its event as follows:


private: System.Void btnPicture_Click(System.Object * sender, System.EventArgs * e) { if( openFileDialog1.ShowDialog() == DialogResult.OK ) { this.txtPicture.Text = openFileDialog1.FileName; this.pctCar.Image = Bitmap.FromFile(openFileDialog1.FileName); } } 61. Return to the form and click the New Car tab

62. In the New Car section, double-click the Picture button and implement its Click event as
follows: private: System.Void btnNCPicture_Click(System.Object * sender, System.EventArgs * e) { if( openFileDialog1.ShowDialog() == DialogResult.OK ) { this.txtNCPicture.Text = openFileDialog1.FileName; this.pctNCar.Image = Bitmap.FromFile(openFileDialog1.FileName); } }

63. Return to the form. Double-click the Load button and implement the event as follows:
System.Void btnLoad_Click(System.Object * sender, System.EventArgs * e) { this.sqlDataAdapter2.Fill(this.dsBCR1); this.sqlDataAdapter1.Fill(this.dsBCR1); this.pctCar.Image = Bitmap.FromFile(this.txtPicture.Text);

P a g e | 150

64. Return to the form and click the Car Details. Double-click the First button and implement
its Click event as follows: System.Void btnFirst_Click(System.Object * sender, System.EventArgs * e) { this.pgeCars.BindingContext.get_Item(this.dsBCR1, "Cars").Position = 0; this.pctCar.Image = Bitmap.FromFile(this.txtPicture.Text); this.sqlDataAdapter1.Update(this.dsBCR1); }

65. Return to the form. Double-click the Previous button and implement its Click event as
follows: System.Void btnPrevious_Click(System.Object * sender, System.EventArgs * e) { this.pgeCars.BindingContext.get_Item(this.dsBCR1, "Cars").Position = this.pgeCars.BindingContext.get_Item(this.dsBCR1, "Cars").Position - 1; this.pctCar.Image = Bitmap.FromFile(this.txtPicture.Text); this.sqlDataAdapter1.Update(this.dsBCR1); }

66. Return to the form. Double-click the Next button and implement its Click event as follows:
System.Void btnNext_Click(System.Object * sender, System.EventArgs * e) { this.pgeCars.BindingContext.get_Item(this.dsBCR1, "Cars").Position = this.pgeCars.BindingContext.get_Item(this.dsBCR1, "Cars").Position + 1; this.pctCar.Image = Bitmap.FromFile(this.txtPicture.Text); this.sqlDataAdapter1.Update(this.dsBCR1); }

67. Return to the form. Double-click the Last button and implement its Click event as follows:
System.Void btnLast_Click(System.Object * sender, System.EventArgs * e) { this.pgeCars.BindingContext.get_Item(this.dsBCR1, "Cars").Position = this.pgeCars.BindingContext.get_Item(this.dsBCR1, "Cars").Count - 1; this.pctCar.Image = Bitmap.FromFile(this.txtPicture.Text); this.sqlDataAdapter1.Update(this.dsBCR1); } 68. Return to the form and double-click the Close button

69. Implement its event as follows:


private: System.Void btnClose_Click(System.Object * sender, System.EventArgs * e) { Close(); } 70. Return to the form and click the New Car tab

71. In the New Car page, double-click the Reset button and implement its Click event as
follows:

151 | P a g e

System.Void btnReset_Click(System.Object * sender, System.EventArgs * e) { this.txtNCTagNumber.Text = ""; this.txtNCMake.Text = ""; this.txtNCModel.Text = ""; this.txtNCYear.Text = ""; this.cboNCCategoryID.SelectedIndex = -1; this.chkNCK7Player.Checked = false; this.chkNCDVDPlayer.Checked = false; this.chkNCCDPlayer.Checked = false; this.chkNCAvailable.Checked = false; this.txtNCPicture.Text = "C:\\Programs\\Unknown.bmp"; this.pctNCar.Image = Bitmap.FromFile(this.txtNCPicture.Text); this.txtNCNotes.Text = ""; } this.txtNCTagNumber.Focus();

72. Return to the form and double-click the Create button

73. Implement its Click event as follows:


System.Void btnCreate_Click(System.Object * sender, System.EventArgs * e) { string strInsert = String.Concat("INSERT INTO Cars(TagNumber, Make, Model, " "CarYear, RentalRateID, HasK7Player, " "HasCDPlayer, HasDVDPlayer, Picture, " "Available, Notes) VALUES('", this.txtNCTagNumber.Text, "', '", txtNCMake.Text, "', '", txtNCModel.Text, "', '", txtNCYear.Text, "', '", cboNCCategoryID.SelectedIndex, "', '", chkNCCDPlayer.Checked, "', '", chkNCDVDPlayer.Checked, "', '", chkNCDVDPlayer.Checked, "', '", txtNCPicture.Text, "', '", chkNCAvailable.Checked, "', '", txtNCNotes.Text, "');"); MySql.Data.MySqlClient.MySqlCommand cmdNewCar = new MySql.Data.MySqlClient.MySqlCommand(strInsert, this.MySqlConnection1); MySqlConnection1.Open(); cmdNewCar.ExecuteNonQuery(); MySqlConnection1.Close(); } 74. Save all 75. To create a new form, on the main menu, click Project . Add New File... this.btnReset_Click(sender, e);

76. In the New File dialog box, click Windows Form and set its Name to RentalOrders
77. In Server Explorer, in the Tables node of the BCR database, click Cars 78. Press and hold Ctrl 79. Click Customers, Employees, and RentalOrders 80. Release Ctrl

P a g e | 152

81. Drag the selected tables and drop them on the form

82. To create a data set, on the main menu, click Data . Generate Dataset...

83. Accept the Existing radio button with the dsBCR name and click OK 84. Design the form as follows:

153 | P a g e

Control GroupBox Label ComboBox Label TextBox Button GroupBox ComboBox Label TextBox Label TextBox Label TextBox Label ComboBox GroupBox ComboBox Label TextBox Label TextBox TextBox TextBox TextBox TextBox GroupBox Label

Name

Text/CaptionText Order Identification Processed By:

Items

Other Properties

cboEmployeeID Receipt #: txtRentalOrderID btnFindReceipt Find Car Selected cboCarID Make: txtMake Model: txtModel Year: txtCarYear Car Condition: cboCarCondition Customer cboCustomerID Name: txtCustName Address: txtCustAddress txtCustCity txtCustState txtCustZIPCode txtCustCountry USA Order Evaluation Tank Level: Full Tank 3/4 Full Half 1/4 Full Empty Rate Applied 24.95 Mileage: txtMileage txtSubTotal 0 Sub Total 0.00 Start Date: Format: Custom TextAlign: Right TextAlign: Right FlatStyle: Popup TextAlign: Right MD DropDownStyle: DropDownList Excellent Good Drivable Needs Repair DropDownStyle: DropDownList

ComboBox

cboTankLevel

Button TextBox Label TextBox Label TextBox Label

btnRateApplied txtRateApplied

DateTimePicker dtpStartDate

P a g e | 154

CustomFormat: ddd dd MMM yyyy Label TextBox Label Label DateTimePicker dtpEndDate Label TextBox Label TextBox Label TextBox GroupBox Button Button Button btnNewOrder btnReset btnClose txtOrderTotal txtTaxAmount Tax Amount: 0.00 Number of Days: txtNumberOfDays 0 Order Total: 0.00 Management New Rental Order Reset/Start New Close TextAlign: Right TextAlign: Right TextAlign: Right txtTaxRate Tax Rate: 5.75 % End Date: Format: Custom CustomFormat: ddd dd MMM yyyy TextAlign: Right

85. Bind the controls using the following table:


Selection: dsBCR1 -RentalOrders. EmployeeID

Control

DataBindings Type

Others DataSource: dsBCR1.Employees DisplayMember: FullName ValueMember: EmployeeID DataSource: dsBCR1.Cars DisplayMember: TagNumber ValueMember: CarID DataSource: dsBCR1.Customers DisplayMember: DrvLicNbr ValueMember: CustomerID

cboEmployeeID SelectedValue

cboCarID

SelectedValue

CarID

cboCustomerID SelectedValue

CustomerID

86. Generate the Load event of the form and implement it as follows:
private: System.Void RentalOrders_Load(System.Object * sender, System.EventArgs * e) { this.sqlDataAdapter4.Fill(this.dsBCR1); this.sqlDataAdapter3.Fill(this.dsBCR1); this.sqlDataAdapter2.Fill(this.dsBCR1); this.sqlDataAdapter1.Fill(this.dsBCR1); } 87. Return to the form and double-click the Car Selected combo box

88. Implement its SelectedIndexChanged event as follows:


System.Void cboCarID_SelectedIndexChanged(System.Object * sender, System.EventArgs * e) { string strTagNumber = "000000";

155 | P a g e

string strMake = "Not Found"; string strModel = "Not Found"; string strYear = "0"; // Get a reference to the records of the Cars table DataRowCollection *rows = this.dsBCR1.Tables.Item["Cars"].Rows; // Check each record one by one for(int i = 0; i < rows.Count; i++) { // Get the current tag number strTagNumber = dynamic_cast<string >(rows.Item[i].Item["TagNumber"]); the user... // If the current tag matches the one selected by if( strTagNumber= this.cboCarID.Text) ) { // Retrieve its corresponding make, model,

and year

strMake = dynamic_cast<string >(rows.Item[i].Item["Make"]); strModel = dynamic_cast<string >(rows.Item[i].Item["Model"]); strYear = dynamic_cast<string >(rows.Item[i].Item["CarYear"]); // Since you found a match, STOP!!! break; } } // Display the make, model, and year of the selected car this.txtMake.Text = strMake; this.txtModel.Text = strModel; this.txtCarYear.Text = strYear;

89. Return to the form and double-click the Customer combo box

90. Implement its SelectedIndexChanged event as follows:


System.Void cboCustomerID_SelectedIndexChanged(System.Object * sender, System.EventArgs * e) { string strDrvLicNbr = "000000"; string strCustName = "Not Found"; string strCustAddress = ""; string strCustCity = ""; string strCustState = ""; string strCustZIPCode = ""; string strCountry = ""; // Get a reference to the records of the Customers table DataRowCollection *rows = this.dsBCR1.Tables.Item["Customers"].Rows; // Check each record one by one for(int i = 0; i < rows.Count; i++) { // Get the current tag number strDrvLicNbr = dynamic_cast<string >(rows.Item[i].Item["DrvLicNbr"]); // If the current driver's license number matches the one selected by the user... if( strDrvLicNbr= this.cboCustomerID.Text) )

P a g e | 156

// Retrieve its corresponding information strCustName = dynamic_cast<string >(rows.Item[i].Item["FullName"]); strCustAddress = dynamic_cast<string >(rows.Item[i].Item["Address"]); strCustCity = dynamic_cast<string >(rows.Item[i].Item["City"]); strCustState = dynamic_cast<string >(rows.Item[i].Item["State"]); strCustZIPCode = dynamic_cast<string >(rows.Item[i].Item["ZIPCode"]); strCountry = dynamic_cast<string >(rows.Item[i].Item["Country"]); // Since you found a match, STOP!!! break; } } // Display the details of the customer this.txtCustName.Text = strCustName; this.txtCustAddress.Text = strCustAddress; this.txtCustCity.Text = strCustCity; this.txtCustState.Text = strCustState; this.txtCustZIPCode.Text = strCustZIPCode; this.txtCustCountry.Text = strCountry;

91. Return to the form. Double-click the Rate Applied button and, in the top section of the file,
just under the #pragma once line, type: #include "RentalRates.h"

92. Implement the event as follows:


System.Void btnRateApplied_Click(System.Object * sender, System.EventArgs * e) { RentalRates *frmRates = new RentalRates(); frmRates.Show(); }

93. Double-click the Reset/Start New button and implement its Click event as follows:
System.Void btnReset_Click(System.Object * sender, System.EventArgs * e) { this.cboEmployeeID.SelectedIndex = -1; this.txtRentalOrderID.Text = ""; this.cboCarID.SelectedIndex = -1; this.txtMake.Text = ""; this.txtModel.Text = ""; this.txtCarYear.Text = ""; this.cboCarCondition.SelectedIndex = 0; this.cboCustomerID.SelectedIndex = -1; this.txtCustName.Text = ""; this.txtCustAddress.Text = ""; this.txtCustCity.Text = ""; this.txtCustState.Text = ""; this.txtCustZIPCode.Text = ""; this.txtCustCountry.Text = "USA"; this.cboTankLevel.SelectedIndex = 0; this.txtRateApplied.Text = "24.95"; this.txtMileage.Text = "0"; this.txtSubTotal.Text = "0.00";

157 | P a g e

this.dtpStartDate.Value = DateTime.Today; this.txtTaxRate.Text = "7.75"; TimeSpan ts(1, 0, 0, 0); this.dtpEndDate.Value = DateTime.Today.Add(ts); this.txtTaxAmount.Text = "0.00"; this.txtNumberOfDays.Text = "1"; this.txtOrderTotal.Text = "0.00"; this.cboEmployeeID.Focus(); } 94. Return to the form and double-click the End Date control

95. Implement its ValueChanged event as follows:


private: System.Void dtpEndDate_ValueChanged(System.Object * sender, System.EventArgs * e) { DateTime startDate = this.dtpStartDate.Value; DateTime endDate = this.dtpEndDate.Value; TimeSpan diff = endDate.Subtract(startDate); this.txtNumberOfDays.Text = (diff.Days + 1).ToString(); } 96. Return to the form and click the Rate Applied text box (not the button)

97. In the Events section of the Properties window, double-click the right box to Leave and
implement its event as follows: System.Void txtRateApplied_Leave(System.Object * sender, System.EventArgs * e) { double rateApplied = this.txtRateApplied.Text.ToDouble(0); int numberOfDays = this.txtNumberOfDays.Text.ToInt16(0); double subTotal = rateApplied * numberOfDays; this.txtSubTotal.Text = subTotal.ToString("F"); double taxRate = this.txtTaxRate.Text.ToDouble(0); double taxAmount = subTotal * taxRate / 100; this.txtTaxAmount.Text = taxAmount.ToString("F"); double orderTotal = subTotal + taxAmount; this.txtOrderTotal.Text = orderTotal.ToString("F"); }

98. Return to the form. Double-click the New Rental Order button on the form and implement
its Click event as follows: System.Void btnNewOrder_Click(System.Object * sender, System.EventArgs * e) { if( this.btnNewOrder.Text= "New Rental Order") ) { this.btnNewOrder.Text = "Save"; this.btnReset_Click(sender, e); } else { string strInsert = String.Concat("INSERT INTO RentalOrders(" "EmployeeID, CustomerID, CarID, " "CarCondition, TankLevel, Mileage, " "StartDate, EndDate, NumberOfDays, " "RateApplied, SubTotal, TaxRate, TaxAmount, " "RentTotal, Notes) VALUES('", cboEmployeeID.SelectedIndex.ToString(), "', '", cboCustomerID.SelectedIndex.ToString(), "', '",

P a g e | 158

txtNumberOfDays.Text, '",

cboCarID.SelectedIndex.ToString(), "', '", cboCarCondition.Text, "', '", cboTankLevel.Text, "', '", txtMileage.Text, "', '", dtpStartDate.Value, "', '", dtpEndDate.Value, "', '", "', '", txtRateApplied.Text.ToDecimal(0), "', txtSubTotal.Text.ToDecimal(0), "', '", txtTaxRate.Text.ToDecimal(0), "', '", txtTaxAmount.Text.ToDecimal(0), "', '", txtOrderTotal.Text.ToDecimal(0), "', '", txtNotes.Text, "');");

MySql.Data.MySqlClient.MySqlCommand cmdNewOrder = new MySql.Data.MySqlClient.MySqlCommand(strInsert, this.MySqlConnection1); MySqlConnection1.Open(); cmdNewOrder.ExecuteNonQuery(); MySqlConnection1.Close(); this.btnReset_Click(sender, e); this.btnNewOrder.Text = "New Rental Order";

} }

99. Display the first form and change its design as follows:

Control Button Button Button Button Button 100.

Name btnCars btnCustomers btnEmployees btnClose

Text Cars Customers Employees Close

btnRentalOrders Rental Orders

Right-click the form and click View Code In the top section of the file, include the header file of each of the other forms:

101.

#pragma once #include "RentalOrders.h" #include "Cars.h"

159 | P a g e

#include "Customers.h" #include "Employees.h"

102.

Return to the form. Double-click the Rental Orders button and implement its Click event as follows:

System.Void btnRentalOrders_Click(System.Object * sender, System.EventArgs * e) { RentalOrders *frmOrders = new RentalOrders(); frmOrders.Show(); }

103.

Return to the form. Double-click the Cars button and implement its Click event as follows:

System.Void btnCars_Click(System.Object * sender, System.EventArgs * e) { Cars *frmCars = new Cars(); frmCars.ShowDialog(); }

104.

Return to the form. Double-click the Customers button and implement its Click event as follows:

System.Void btnCustomers_Click(System.Object * sender, System.EventArgs * e) { Customers *frmCust = new Customers(); frmCust.ShowDialog(); }

105.

Return to the form. Double-click the Employees button and implement its Click event as follows:

System.Void btnEmployees_Click(System.Object * sender, System.EventArgs * e) { Employees *frmEmpl = new Employees(); frmEmpl.Show(); }

106.

Return to the form. Double-click the Close button and implement its Click event as follows:

System.Void btnClose_Click(System.Object * sender, System.EventArgs * e) { Close(); } 107. Execute the application

P a g e | 160

108.

Create a few rental orders and save them

109.

Return to the form. Double-click the Find button on the form and implement its Click event as follows:

System.Void btnFind_Click(System.Object * sender, System.EventArgs * e) { string strReceiptNumber = this.txtRentalOrderID.Text; if( strReceiptNumber = "") ) { MessageBox.Show("You must provide a receipt number to look for a rental order"); return; } string strFindOrder = String.Concat("SELECT * FROM RentalOrders WHERE RentalOrderID = '", strReceiptNumber, "'"); MySql.Data.MySqlClient.MySqlConnection conDatabase = new MySql.Data.MySqlClient.MySqlConnection("Data Source=localhost;Database='BCR';Persist Security Info=yes"); MySql.Data.MySqlClient.MySqlCommand cmdDatabase = new MySql.Data.MySqlClient.MySqlCommand(strFindOrder, conDatabase); conDatabase.Open(); MySql.Data.MySqlClient.MySqlDataReader *rdrRentalOrder; rdrRentalOrder = cmdDatabase.ExecuteReader();

161 | P a g e

while(rdrRentalOrder.Read()) { this.cboEmployeeID.SelectedIndex = (rdrRentalOrder.GetSqlInt32(1) 1).ToString().ToInt32(0); this.cboCustomerID.SelectedIndex = (rdrRentalOrder.GetSqlInt32(2) 1).ToString().ToInt32(0); this.cboCarID.SelectedIndex = (rdrRentalOrder.GetSqlInt32(3) 1).ToString().ToInt32(0); this.cboCarCondition.Text = rdrRentalOrder.GetString(4); this.cboTankLevel.Text = rdrRentalOrder.GetString(5); this.txtMileage.Text = rdrRentalOrder.GetInt32(6).ToString(); this.dtpStartDate.Value = rdrRentalOrder.GetDateTime(7); this.dtpEndDate.Value = rdrRentalOrder.GetDateTime(8); this.txtNumberOfDays.Text = rdrRentalOrder.GetInt16(9).ToString(); this.txtRateApplied.Text = rdrRentalOrder.GetDecimal(10).ToString(); this.txtSubTotal.Text = rdrRentalOrder.GetDecimal(11).ToString(); this.txtTaxRate.Text = rdrRentalOrder.GetDecimal(12).ToString(); this.txtTaxAmount.Text = rdrRentalOrder.GetDecimal(13).ToString(); this.txtOrderTotal.Text = rdrRentalOrder.GetDecimal(14).ToString(); this.txtNotes.Text = rdrRentalOrder.GetString(15); } rdrRentalOrder.Close(); conDatabase.Close(); Execute the application Update the employees work phone and extensions as follows:

} 110.

111.

112.

Process a few rental orders

P a g e | 162

ADO.NET With MySQL and MSDE......................................................................................3 Requirements...............................................................................................................3 The .NET Framework .................................................................................................3 MySQL ......................................................................................................................3 MSDE.........................................................................................................................3 #develop...................................................................................................................3 Connection to the MySQL Server......................................................................................5 Using ADO.NET.............................................................................................................5 Introduction to ADO.NET...........................................................................................5 Using the MySQL Connector/Net................................................................................5 Connection to a MySQL Database..................................................................................5 Introduction..............................................................................................................5 The Source of Data....................................................................................................6 The Database............................................................................................................6 Security.....................................................................................................................7 The Username...........................................................................................................7 The Password............................................................................................................7 Additional Attributes.................................................................................................8 Operations on a MySQL Server Database Connection.....................................................8 Opening a Connection................................................................................................8 Closing a Connection.................................................................................................8 Actions on a MySQL Database.......................................................................................9 Introduction..............................................................................................................9 SQL on Command......................................................................................................9 Command Execution................................................................................................10 Well, the Command Timed Out.................................................................................10 The Type of Command.............................................................................................10 The Structured Query Language..................................................................................10 Introduction............................................................................................................10 SQL Code at the Command Prompt...........................................................................11 Programmatic SQL Code..........................................................................................11

163 | P a g e

SQL and Databases........................................................................................................13 Database Creation......................................................................................................13 Introduction............................................................................................................13 Creating a Database...............................................................................................13 Database Maintenance................................................................................................18 Deleting a Database.................................................................................................18 The Tables of a Database...............................................................................................21 Database Tables.........................................................................................................21 Introduction............................................................................................................21 Table Creation ........................................................................................................22 The Name of a Table................................................................................................22 Table Maintenance......................................................................................................24 Renaming a Table ...................................................................................................24 Removing a Table ...................................................................................................26 The Columns of a Table..................................................................................................27 The Name of a Column ............................................................................................27 The Types of Data a Column Can Carry.....................................................................27 The Length of Data..................................................................................................30 Removing a Table ...................................................................................................32 Columns Maintenance.................................................................................................34 Columns Statistics ..................................................................................................34 Adding a Column ....................................................................................................36 Renaming a Column ................................................................................................36 Deleting a Column ..................................................................................................38 Data Entry.....................................................................................................................39 Fundamentals of Table Data Entry..............................................................................39 Introduction............................................................................................................39 Displaying the Table For Data Entry.........................................................................41 Techniques of Performing Data Entry..........................................................................42 Data Entry Using the Enterprise Manager or Server Explorer....................................42 Data Entry Using the SQL Query Analyzer................................................................42

P a g e | 164

Data Entry On Command..........................................................................................44 Data Maintenance: Deleting Records...........................................................................46 Introduction............................................................................................................46 Deleting Records: the Server Explorer or the Enterprise Manager............................46 Adapting Data to Windows Controls...............................................................................65 Data Analysis.................................................................................................................81 Data Analysis: Sorting Records......................................................................................85 Criteria For Data Analysis..............................................................................................95 Reading Data Using a Data Reader...............................................................................103 SQL Operators and Operands.......................................................................................108 Relationships and Data Integrity..................................................................................124

165 | P a g e

You might also like