Sei sulla pagina 1di 11

1. Writing SQL commands in C# - Part 1 - INSERT into table Welcome all!

Hereby I would like to present you a little prototype of mine. This is a program showing that you can indeed write SQL commands using C#. Try out the code below, and if you are interested in reading further tutorials... please leave me a comment and some +rep. Connecting or creating a database For a start let's run Visual Studio 2008. I also installed SQL Express which runs locally. If you want to connect remotly using TCP/IP then we can work on that, too. But I do not do that in this tutorial, part 1.

Now, before touching any database you need to do three things. For one, you need to create a database. In the Database Explorer click-right and click Add Connection. There you select a database provider (SqlClient is default) and a database file. I selected a new database file, to create a new database. Go ahead and create your own database, I will wait.

For two, you need to create a table. Again in the Database Explorer select the database, then Tables folder, then right-click and click Add New Table. Now go ahead and put few columns there, along with their types. I used types int and ntext. Better avoid other types, like DateTime . Then save the table, pick your own name for it. Go ahead.

For three, you need to make a connection string. This time use the Data Sources panel and right-click, then click Add New Data Source. The wizard is pretty straightforward. Select a Database. It should propose you the database file, that you selected earlier. Warning: It will ask you do you want to copy the database into your project. If you click yes then it will restore the database at every run. I strongly suggest to click No. Otherwise you will loose your records all too often. Next page will ask to save a connection string. You are going to need it in the code. Last page will ask you to import tables. I suggest you just import them all and sort it out later.

Writing SQL command: INSERT into table Here we are. The precious moment of truth. Let us insert a nice record into our new table. Here is a simple piece of code that does that. Notice that you are going to include an import directive, use two classes, and that is about it. The namespace System.Data.SqlClient contains the two classes, SqlConnection and SqlCommand that will do the whole work. As for the SQL language itself, there is some nice MSDN documentation for that. Code:

using System.Data.SqlClient; Code: SqlConnection connection1 = new SqlConnection( Properties.Settings.Default.some_numbersConnectionString); SqlCommand insertCommand = new SqlCommand( "INSERT into NumbersTable values (128, 'as in 128 bits equal 16 bytes')", connection1); connection1.Open(); insertCommand.ExecuteNonQuery(); connection1.Close(); MessageBox.Show("Record inserted. Please check your table data. :)"); Here are some screenshots for the code, and running. Sorry, I could not resist to add some.

Looking at the actual database records So how do you know that the INSERT command worked? Well, I do not mention how to pull out the records from a database, yet, thus you need to look up the database itself. Thankfully VS2008 has a nice feature. In the Database Explorer right-click the table and click Show Table Data. You see... all your inserts are okay. Nothing else to do, but to save the project.

Writing SQL commands in C# - Part 2 - Reading and deleting records Welcome all! This is a second part of my SQL in C# tutorial series. If you are interested in writing INSERT commands then take a look at part 1: INSERT into table. In this tutorial I would like to show you how to read several records by using a SELECT statement, and how to delete records by using DELETE statement. Enjoy this short tutorial. Reading records with SQL SELECT statment: using SqlDataReader class So, so far we created a database, with a table for numbers and descriptions, and added a record. Remember, table NumbersTable has two columns, numbers and description. During insertion and deletion column names are not used, you need only their order. So when you write some code, take a look again at the table. If you make it wrong then god help you with debbuging. Code: SqlConnection connection1 = new SqlConnection( Properties.Settings.Default.some_numbersConnectionString); SqlCommand insertCommand = new SqlCommand( "INSERT into NumbersTable values (1002, 'will delete this one')", connection1); connection1.Open(); insertCommand.ExecuteNonQuery(); connection1.Close(); MessageBox.Show("Record inserted. Please check your table data. :)"); But a database is useless if you cannot use the data you inputed there, right? After all this is why created a database in the first place. So, let us read all the records from our table. While you can use some conditions to select only several records, it is not necessary in this case. For a start you need a SqlConnection and SqlCommand classes. They are required for any SQL statement. This time however, we could also use a SqlDataReader class. It fetches the received data and lets you access them one record at a time. After calling reader = selectCommand.ExecuteReader(), you are able to access your records one-by-one. By turns, call reader.Read() while checking are there any more records to read. If it returns false then you are done with reading. Then process the current record by reading reader[0], reader[1] and so on. Again, field order is important. Try hard to avoid making mistakes here. Code: SqlConnection connection1 = new SqlConnection( Properties.Settings.Default.some_numbersConnectionString); SqlCommand selectCommand = new SqlCommand( "SELECT * FROM NumbersTable", connection1); connection1.Open(); SqlDataReader reader = selectCommand.ExecuteReader(); string fetchedRecords = string.Empty; while (reader.Read() == true) { fetchedRecords += "Record: (number) " + reader[0] + " (descriptio) " + reader[1] + " \n"; } connection1.Close(); MessageBox.Show("Found following records: \n \n" + fetchedRecords);

Deleting several records: SQL DELETE statement Well, deletion is as easy as a pie. There is nothing more than the short code below. Note that you can use several conditions, but ntext and varchar field types do not play with equal-to operator (=). That is why the other version is commented out. Code: SqlConnection connection1 = new SqlConnection( Properties.Settings.Default.some_numbersConnectionString); SqlCommand insertCommand = new SqlCommand( "DELETE NumbersTable WHERE number = 1002", //"DELETE NumbersTable WHERE number = 1002 AND description = 'will delete this one'", connection1); connection1.Open(); insertCommand.ExecuteNonQuery(); connection1.Close(); MessageBox.Show("Record 1002 deleted. Please check your table data again. :)");

Thank the author, share some reputation points I would like to thank everyone, especially Jordan and Siten, that were supporting me. Writing tutorials is a hard work. If you want to leave a comment or +rep my post then go ahead. I thank you in advance.

Bijgevoegde miniaturen

Bijgevoegde bestanden

o o

SqlCommand example, version 02, Insert Select Delete.zip (55.9 KB, 63x gelezen) some_numbers database.zip (157.5 KB, 57x gelezen)

1. Writing SQL commands in C# - Part 3 - Editing records and maintainable code Welcome all! My previous two turorials about inserting, reading and deleting records were so welcomed that I decided to write another one. If you have read them then let's assume we already have a solution with a database attached. We also got few records in a table. Today however, I will focus on something more important than working code. I want you to see how awesome prototypes and dedicated classes are. First one will give us immediate feedback about how good the code is, second one will be a very well designed code that can be maintained over ages. Editing existing records: using SQL UPDATE statement Here is a piece of code that executes yet another SQL statment. It will modify as many records as you want, only the conditions you specify will make which records are changed. Warning: If you don't specify that WHERE clause then it will eat all your data in the table. I would rather not want to make a mistake like this and mess up my company database. I just copied this code from the code above, and modified one line. I strongly believe that it is a very good way to make a prototype and immediately know does it work or not. That is what a prototype is for. Code: SqlConnection connection1 = new SqlConnection( Properties.Settings.Default.some_numbersConnectionString); SqlCommand insertCommand = new SqlCommand( "UPDATE NumbersTable SET number = 1003, description = 'changed my mind' WHERE number = 1002", connection1); connection1.Open(); insertCommand.ExecuteNonQuery(); connection1.Close(); MessageBox.Show("Records 1002s have been changed to 1003s. Please check your table data again. :)");

Structure your code: dedicated class for database operations As you see here, most of SQL operations are very schematic (even reading). They are copied again and again and I just change one line that carries the SQL statment. Look at the full code and think about is this something you would like show to your employers. My honest opinion is that this code is too redundant. Every method alone works great. But making a new connection for every query seems wrong. Code: using using using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Linq; System.Text; System.Windows.Forms; System.Data.SqlClient;

namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void InsertButton_Click(object sender, EventArgs e) { SqlConnection connection1 = new SqlConnection(

Properties.Settings.Default.some_numbersConnectionString); SqlCommand insertCommand = new SqlCommand( "INSERT into NumbersTable values (1002, 'will delete this one')", connection1); connection1.Open(); insertCommand.ExecuteNonQuery(); connection1.Close(); MessageBox.Show("Record 1002 inserted. Please check your table data. :)"); } private void ReadButton_Click(object sender, EventArgs e) { SqlConnection connection1 = new SqlConnection( Properties.Settings.Default.some_numbersConnectionString); SqlCommand selectCommand = new SqlCommand( "SELECT * FROM NumbersTable", connection1); connection1.Open(); SqlDataReader reader = selectCommand.ExecuteReader(); string fetchedRecords = string.Empty; while (reader.Read() == true) { fetchedRecords += "Record: (number) " + reader[0] + " (descriptio) " + reader[1] + " \n"; } connection1.Close(); MessageBox.Show("Found following records: \n \n" + fetchedRecords); } private void DeleteButton_Click(object sender, EventArgs e) { SqlConnection connection1 = new SqlConnection( Properties.Settings.Default.some_numbersConnectionString); SqlCommand insertCommand = new SqlCommand( "DELETE NumbersTable WHERE number = 1002", connection1); connection1.Open(); insertCommand.ExecuteNonQuery(); connection1.Close(); MessageBox.Show("Records 1002s deleted. Please check your table data again. :)"); } private void EditButton_Click(object sender, EventArgs e) { SqlConnection connection1 = new SqlConnection( Properties.Settings.Default.some_numbersConnectionString); SqlCommand insertCommand = new SqlCommand( "UPDATE NumbersTable SET number = 1003, description = 'changed my mind' WHERE number = 1002", connection1); connection1.Open(); insertCommand.ExecuteNonQuery(); connection1.Close(); MessageBox.Show("Records 1002s have been changed to 1003s. Please check your table data again. :)"); }

} } Now the suprising part. I really think this way of coding is very *good*. You might ask "is this a good practice? this is crap". And I would agree. This code is a prototype. Making it took me less time (also because I copied and copied) so it saved me time on designing something that I would change later anyway. It also gave me a real insight into how my code should look like. What I would like to do now, is put all our database operations into a dedicated class. We already have a *working* prototype, shall we make a second *maintainable* solution?

Code: private void button1_Click(object sender, EventArgs e) { string message = "Here are logs for all operations made: \n"; message += "Adding a 1002 record twice. \n"; DatabaseOperations.ExecuteSqlStatement("INSERT into NumbersTable values (1002, 'will delete this one')"); DatabaseOperations.ExecuteSqlStatement("INSERT into NumbersTable values (1002, 'will delete this one')");

message += "Reading all records present: \n"; SqlDataReader reader = DatabaseOperations.ExecuteSqlReader("SELECT * FROM NumbersTable"); while (reader.Read() == true) message += " Record: (number) " + reader[0] + " (description) " + reader[1] + " \n"; reader.Close();

message += "Editing all 1002 records into 1003s. \n";

DatabaseOperations.ExecuteSqlStatement("UPDATE NumbersTable SET number = 1003, description = 'changed my mind' WHERE number = 1002");

message += "Reading all records present (again): \n"; reader = DatabaseOperations.ExecuteSqlReader("SELECT * FROM NumbersTable"); while (reader.Read() == true) message += " Record: (number) " + reader[0] + " (description) " + reader[1] + " \n"; reader.Close();

MessageBox.Show(message); } Code: using using using using using System; System.Collections.Generic; System.Linq; System.Text; System.Data.SqlClient;

namespace WindowsFormsApplication1 { /// <summary> /// This class performs the database operations. Pass on SQL statements and /// it will just return the data for you. /// </summary> public static class DatabaseOperations { /// <summary> /// This connection will do everything. Better to not throw connections /// on left and right. /// </summary> private static SqlConnection connectionForAllOperations; /// <summary> /// This method executes any non-reader command. Use it for INSERT, UPDATE /// and DELETE. It does not work for SELECT, sorry. /// </summary> public static void ExecuteSqlStatement(string sql) { if (connectionForAllOperations == null) { /// The connection will be opened only once, just before first operation. connectionForAllOperations = new SqlConnection( Properties.Settings.Default.some_numbersConnectionString); connectionForAllOperations.Open(); } SqlCommand anyCommand = new SqlCommand(sql, connectionForAllOperations); anyCommand.ExecuteNonQuery(); } /// <summary> /// This method executes a reader command. Use for SELECT queries. /// </summary> public static SqlDataReader ExecuteSqlReader(string sql) { if (connectionForAllOperations == null) { /// The connection will be opened only once, just before first operation. connectionForAllOperations = new SqlConnection( Properties.Settings.Default.some_numbersConnectionString); connectionForAllOperations.Open(); }

SqlCommand anyCommand = new SqlCommand(sql, connectionForAllOperations); SqlDataReader anyReader = anyCommand.ExecuteReader(); return anyReader; } } } I would like to take an opportunity to make a breaking point in the way coding is conducted. I think every manager would say that I should skip the first crap and proceed to working on the solution, probably to save time. I would totally disagree here. Here are my arguments. I made a prototype really quickly, almost in no time. That is because I could do as I want and no code quality was needed. I also made the solution really quickly. You might not believe me but I copied most of the stuff and just renamed and refactored it. At the same time... Class design is completely new. I eliminated the big flaws that were existing in the prototype. Therefore the solution is very maintainable. And that is worth some employees time, sweat and earnings in the future. Also building a prototype gave me a real insight into how SQL queries work. That knowledge is very important when building a solution (first or not), as much as when solving bugs. It will also pay off when implementing all the details that a solution would require. The manager could say: "Then design the software well in the beginning". Of course it sounds like a great idea. But how will I design something I never saw on my own eyes so far? I am pretty sure that the folks at NASA really took their time to design their first space rockets, those ones with higher oxygen level inside. They had the design, but not experience. Let the astronauts rest in peace.

Bijgevoegde miniaturen

Bijgevoegde bestanden

o o o

SqlCommand example, version 03, editing records.zip (58.5 KB, 67x gelezen) SqlCommand example, version 04, dedicated class.zip (58.2 KB, 62x gelezen) some_numbers database.zip (166.2 KB, 76x gelezen)

Potrebbero piacerti anche