Professional Documents
Culture Documents
Page |2
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
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 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.
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
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.
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.
11 | P a g e
P a g e | 12
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.
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
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
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
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:
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.
Name
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
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
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.
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.
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.
P a g e | 24
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
25 | P a g e
4. Click Rename
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
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.
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.
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:
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
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.
3. In the top section of the file, under the other using lines, type:
using MySql.Data.MySqlClient;
TabControl tabCountries
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
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
If the table already contains some records, they would display under the column headers.
41 | P a g e
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
Control GroupBox
Name
P a g e | 44
Label TextBox Label TextBox Label TextBox Button txtContinentPopulation btnNewContinent txtContinentArea txtContinentName
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();
45 | P a g e
4. Click Create New Continent 5. Close the form and return to your programming environment
P a g e | 46
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.
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.
49 | P a g e
Once the cell loses focus, the new value is automatically saved:
P a g e | 50
Once again, remember that where performing an operation in the SQL Query Analyzer, you would not be warned.
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
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.
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
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
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.
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.
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
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
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
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
Name
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;";
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.
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); }
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
8. Click OK twice P a g e | 70
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
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
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.
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
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
P a g e | 76
Remember that the DataSet.Tables[Index] value gives you access to a table as an object and you can use it as necessary.
77 | P a g e
colSecond.ColumnName); cnnVideos.Close(); }
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:
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
79 | P a g e
P a g e | 80
Data Analysis
81 | P a g e
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.
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.
4. In the Generate Dataset dialog box, accept the New radio button. Change the name to
dsROSH and click OK
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
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.
89 | P a g e
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
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
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
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:
P a g e | 92
93 | P a g e
P a g e | 94
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.
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.
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.
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.
Control Label
Name
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);
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
103 | P a g e
A Data Reader
Introduction
P a g e | 104
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
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
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
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.
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
Bit1 0 1 0 1
Bit2 0 0 1 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
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
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
You can also let the compiler perform the operation and produce a result. Here is an example: PRINT 187 | 242 This would produce 251
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
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
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.
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.
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.
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
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.
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
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
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
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...
20 2
127 | P a g e
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
17. In the Server Explorer and under BCR, right-click the Tables node and click New Table...
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:
FullName Amy Larsson Anne DeCarlo Chrissie Yuen Scott Salomons Mary Herness
OrganDonor 0 1 0 0 0
P a g e | 128
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.
120
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
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
131 | P a g e
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.
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
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
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
13. Close the Diagram window and any table that is opened
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
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
19. In the New File dialog box, click Windows Form and set its Name to Customers P a g e | 140
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
Other Properties
txtNCDLClass Date Issued: Format: Short Exp. Date: Format: Short Full Name: txtNCFullName Address:
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
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
35. In the New Customer page, double-click the Reset button and implement its Click event as
follows:
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();
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
Form
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
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
txtNotes btnFirst btnPrevious btnNext btnLast btnLoad btnClose First Previous Next Last Load Close
Control TabPage Label TextBox Label TextBox Label TextBox Label TextBox Label ComboBox CheckBox CheckBox
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
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
Others
149 | P a g e
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
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
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();
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
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
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
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
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
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"
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
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:
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.
159 | P a g e
102.
Return to the form. Double-click the Rental Orders button and implement its Click event as follows:
103.
Return to the form. Double-click the Cars button and implement its Click event as follows:
104.
Return to the form. Double-click the Customers button and implement its Click event as follows:
105.
Return to the form. Double-click the Employees button and implement its Click event as follows:
106.
Return to the form. Double-click the Close button and implement its Click event as follows:
P a g e | 160
108.
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.
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