[ADO.NET Tutorial] Lesson 03: Đối tượng SqlCommand

(The C# Station ADO.NET Tutorial)

Lesson này giới thiệu về đối tượng SqlCommand và cách sử dụng để thao tác với database. Qua bài viết này, bạn sẽ biết cách sử dụng các phương thức ExecuteReader(), ExecuteNonQuery() và ExecuteScalar() của đối tượng command.

Giới thiệu

Đối tượng SqlCommand cho phép bạn chọn kiểu tương tác mà bạn muốn thực hiện với database. Ví dụ, bạn có thể thực hiện các lệnh select, insert, modify, và delete các dòng trong một table của database. Đối tượng này có thể được dùng để hỗ trợ mô hình quản lý dữ liệu ngắt kết nối (disconnected), nhưng trong bài học này chúng ta chỉ dùng đối tượng SqlCommand làm việc độc lập. Bài học này cũng cho bạn thấy cách để lấy một giá trị đơn từ database, như là số dòng của một table.

Tạo một đối tượng người dùng SqlCommand

Tương tự như những đối tượng người tiêu dùng C # khác, bạn tạo đối tượng người dùng SqlCommand bằng cách khai báo một bộc lộ của nó :

SqlCommand cmd = new SqlCommand ( “ select CategoryName from Categories ”, conn ) ;

Dòng trên là nổi bật để tạo một đối tượng người dùng SqlCommand. Nó lấy một tham số là chuỗi lệnh bạn cần thực thi và một tham chiếu đến đối tượng người tiêu dùng SqlConnection. SqlCommand có một vài overload, mà bạn sẽ thấy trong những ví dụ của tutorial này .

Querying Data – Truy vấn tài liệu

Khi dùng một lệnh SQL select, bạn lấy được một tài liệu từ database để hiển thị. Để làm được điều này với SqlCommand, bạn cần dùng phương pháp ExecuteReader ( ) để trả về một đối tượng người dùng SqlDataReader. Chúng ta sẽ luận bàn về SqlDataReader trong bài tiếp theo. Ví dụ sau cho thấy cách dùng SqlCommand để lấy được một đối tượng người dùng SqlDataReader :

// 1. Instantiate a new command with a query and connection
SqlCommand cmd = new SqlCommand("select CategoryName from Categories", conn);

// 2. Call Execute reader to get query results
SqlDataReader rdr = cmd.ExecuteReader();

Trong ví dụ trên, tất cả chúng ta tạo một đối tượng người tiêu dùng SqlCommand, truyền chuỗi lệnh và đối tượng người dùng connection vào constructor. Sau đó tất cả chúng ta lấy về đối tượng người tiêu dùng SqlDataReader bằng cách gọi phương pháp ExecuteReader ( ) của đối tượng người tiêu dùng SqlCommand, cmd .

Inserting Data – Chèn dữ liệu

Để chèn tài liệu vào database, dùng phương pháp ExecuteNonQuery ( ) của đối tượng người tiêu dùng SqlCommand. Đoạn code sau cho thấy cách chèn tài liệu vào một bảng trong database :

 // prepare command string
 string insertString = @"
     insert into Categories
     (CategoryName, Description)
     values ('Miscellaneous', 'Whatever doesn''t fit elsewhere')";

 // 1. Instantiate a new command with a query and connection
 SqlCommand cmd = new SqlCommand(insertString, conn);

 // 2. Call ExecuteNonQuery to send command
 cmd.ExecuteNonQuery();

Lưu ý hai dấu nháy đơn ( ‘ ’ ) trong chuỗi insertString của từ “ doesn ’ ’ t ” ( không phải dấu nháy kép ). Đây là cách để bạn chèn một dấu nháy đơn vào chuỗi trong trường hợp chuỗi đó được bao bởi hai dấu nháy đơn ( ‘ ) thay vì nháy kép ( “ ). SQL sẽ xem hai dấu nháy đơn đứng sát nhau là một dấu nháy đơn, tựa như như cách viết ( \ ’ ) trong C # .
Một điểm cần chú ý quan tâm nữa là tất cả chúng ta xác lập rõ những cột CategoryName và Description. Bảng Categories có một primary key là CategoryID. Chúng ta không cần chèn tài liệu vào cột này do tại SQL Server sẽ tự động hóa thêm vào. Nếu bạn thử thêm giá trị vào cột primary key, như CategoryID, một ngoại lệ sẽ được tạo ra .
Để thực thi lệnh này, chỉ cần đơn thuần gọi phương pháp ExecuteNonQuery ( ) của đối tượng người tiêu dùng SqlCommand, cmd .

Updating Data – Cập nhật tài liệu

Phương thức ExecuteNonQuery cũng được dùng để update tài liệu, như đoạn mã sau :

// prepare command string
 string updateString = @"
     update Categories
     set CategoryName = 'Other'
     where CategoryName = 'Miscellaneous'";

 // 1. Instantiate a new command with command text only
 SqlCommand cmd = new SqlCommand(updateString);

 // 2. Set the Connection property
 cmd.Connection = conn;

 // 3. Call ExecuteNonQuery to send command
 cmd.ExecuteNonQuery();

Một lần nữa, tất cả chúng ta đặt câu SQL trong một biến string, nhưng lần này tất cả chúng ta dùng một constructor khác của SqlCommand, chỉ có một tham số là câu lệnh SQL. Trong bước 2, tất cả chúng ta gán đối tượng người dùng SqlConnection, conn, cho property Connection của đối tượng người tiêu dùng SqlCommand, cmd .
Thay vì cách này, bạn hoàn toàn có thể sử dụng constructor với hai tham số tựa như như cho đoạn mã insert phần trên. Nó cho thấy rằng bạn hoàn toàn có thể đổi khác đối tượng người tiêu dùng connection gán cho một command bất kỳ khi nào .
Bước ở đầu cuối, phương pháp ExecuteNonQuery ( ) thực thi lệnh update .

Deleting Data – Xóa dữ liệu

Bạn cũng hoàn toàn có thể xóa dữ liệu bằng phương pháp ExecuteNonQuery ( ). Ví dụ sau cho thấy cách xóa một dòng từ database với phương pháp ExecuteNonQuery ( ) :

// prepare command string
 string deleteString = @"
     delete from Categories
     where CategoryName = 'Other'";

 // 1. Instantiate a new command
 SqlCommand cmd = new SqlCommand();

 // 2. Set the CommandText property
 cmd.CommandText = deleteString;

 // 3. Set the Connection property
 cmd.Connection = conn;

 // 4. Call ExecuteNonQuery to send command
 cmd.ExecuteNonQuery();

Ví dụ này sử dụng constructor không có tham số của SqlCommand. Thay vào đó, nó gán cho hai property CommandText và Connection của đối tượng người tiêu dùng SqlCommand, cmd .
Chúng ta cũng hoàn toàn có thể dùng hai overload constructor trước đó của SqlCommand, dùng để insert và update, với hiệu quả tựa như. Điều này cho thấy rằng bạn hoàn toàn có thể thay đôi cả chuỗi lệnh và đối tượng người dùng connection bất kể khi nào .

Lời gọi phương thức ExecuteNonQuery()  gửi lệnh đến database.

Lấy một giá trị đơn

Đôi lúc tổng thể những gì bạn cần từ database chỉ là một giá trị đơn, đó hoàn toàn có thể là một giá trị đếm, tổng, trung bình, hoặc những giá trị phối hợp khác từ tài liệu. Thực thi phương pháp ExecuteReader ( ) để lấy về một đối tượng người dùng SqlDataReader và đo lường và thống kê hiệu quả trong mã lệnh của bạn không phải cách tốt để làm điều này. Cách tốt nhất là để database làm việc làm này và trả về giá trị bạn cần. Ví dụ sau cho thấy cách làm điều này với phương pháp ExecuteScalar ( ) :

// 1. Instantiate a new command
SqlCommand cmd = new SqlCommand("select count(*) from Categories", conn);

// 2. Call ExecuteNonQuery to send command
int count = (int)cmd.ExecuteScalar();

Câu truy vấn trong constructor của SqlCommand sẽ lấy về giá trị đếm của toàn bộ dòng trong bảng Categories. Câu truy vấn này chỉ trả về một giá trị đơn. Phương thức ExecuteScalar ( ) trong bước 2 trả về giá trị này. Bởi vì kiểu trả về của ExecuteScalar ( ) là object, tất cả chúng ta cần ép kiểu để chuyển giá trị sang int .

Kết hợp toàn bộ với nhau

Để đơn thuần, tôi cho thấy những đoạn mã ngắn trong những phần trước để minh họa những kĩ thuật tương ứng. Nó cũng rất có ích để xem cách mà mã lệnh thực thi trong một đoạn mã hoàn hảo của chương trình. Listing 1 cho thấy toàn bộ mã lệnh được dùng trong ví dụ này, cùng với phương pháp Main ( ) để thực thi và hiển thị tác dụng xuất ra :

Listing 1.  SqlConnection Demo
 using System;
 using System.Data;
 using System.Data.SqlClient;

 ///
 /// Demonstrates how to work with SqlCommand objects
 /// 
 class SqlCommandDemo
 {
     SqlConnection conn;

     public SqlCommandDemo()
     {
         // Instantiate the connection
         conn = new SqlConnection(
            "Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI");
     }

     // call methods that demo SqlCommand capabilities
     static void Main()
     {
         SqlCommandDemo scd = new SqlCommandDemo();

         Console.WriteLine();
         Console.WriteLine("Categories Before Insert");
         Console.WriteLine("------------------------");

         // use ExecuteReader method
         scd.ReadData();

         // use ExecuteNonQuery method for Insert
         scd.Insertdata();
         Console.WriteLine();
         Console.WriteLine("Categories After Insert");
         Console.WriteLine("------------------------------");

        scd.ReadData();

         // use ExecuteNonQuery method for Update
         scd.UpdateData();

         Console.WriteLine();
         Console.WriteLine("Categories After Update");
         Console.WriteLine("------------------------------");

         scd.ReadData();

         // use ExecuteNonQuery method for Delete
         scd.DeleteData();

         Console.WriteLine();
         Console.WriteLine("Categories After Delete");
         Console.WriteLine("------------------------------");

         scd.ReadData();

         // use ExecuteScalar method
         int numberOfRecords = scd.GetNumberOfRecords();

         Console.WriteLine();
         Console.WriteLine("Number of Records: {0}", numberOfRecords);
     }

     ///
 /// use ExecuteReader method
 /// 
     public void ReadData()
     {
        SqlDataReader rdr = null;

         try
         {
             // Open the connection
             conn.Open();

             // 1. Instantiate a new command with a query and connection
             SqlCommand cmd = new SqlCommand("select CategoryName from Categories", conn);

             // 2. Call Execute reader to get query results
             rdr = cmd.ExecuteReader();

             // print the CategoryName of each record
             while (rdr.Read())
             {
                 Console.WriteLine(rdr[0]);
             }
         }
         finally
         {
             // close the reader
             if (rdr != null)
             {
                 rdr.Close();
             }

             // Close the connection
             if (conn != null)
             {
                 conn.Close();
             }
         }
     }

     ///
 /// use ExecuteNonQuery method for Insert
 /// 
     public void Insertdata()
     {
         try
         {
             // Open the connection
             conn.Open();

             // prepare command string
             string insertString = @"
                 insert into Categories
                 (CategoryName, Description)
                 values ('Miscellaneous', 'Whatever doesn''t fit elsewhere')";

             // 1. Instantiate a new command with a query and connection
             SqlCommand cmd = new SqlCommand(insertString, conn);

             // 2. Call ExecuteNonQuery to send command
             cmd.ExecuteNonQuery();
         }
         finally
         {
             // Close the connection
             if (conn != null)
             {
                 conn.Close();
             }
         }
     }

     ///
 /// use ExecuteNonQuery method for Update
 /// 
     public void UpdateData()
     {
         try
         {
             // Open the connection
             conn.Open();

             // prepare command string
             string updateString = @"
                 update Categories
                 set CategoryName = 'Other'
                 where CategoryName = 'Miscellaneous'";

             // 1. Instantiate a new command with command text only
             SqlCommand cmd = new SqlCommand(updateString);

             // 2. Set the Connection property
             cmd.Connection = conn;

             // 3. Call ExecuteNonQuery to send command
             cmd.ExecuteNonQuery();
        }
         finally
         {
             // Close the connection
             if (conn != null)
             {
                 conn.Close();
             }
         }
     }

     ///
 /// use ExecuteNonQuery method for Delete
 /// 
     public void DeleteData()
     {
         try
         {
             // Open the connection
             conn.Open();

             // prepare command string
             string deleteString = @"
                 delete from Categories
                 where CategoryName = 'Other'";

             // 1. Instantiate a new command
             SqlCommand cmd = new SqlCommand();

             // 2. Set the CommandText property
             cmd.CommandText = deleteString;

             // 3. Set the Connection property
             cmd.Connection = conn;

             // 4. Call ExecuteNonQuery to send command
             cmd.ExecuteNonQuery();
         }
         finally
         {
             // Close the connection
             if (conn != null)
             {
                 conn.Close();
             }
         }
     }

     ///
 /// use ExecuteScalar method
 /// 
     /// number of records
     public int GetNumberOfRecords()
     {
         int count = -1;

         try
         {
             // Open the connection
             conn.Open();

             // 1. Instantiate a new command
             SqlCommand cmd = new SqlCommand("select count(*) from Categories", conn);

             // 2. Call ExecuteScalar to send command
             count = (int)cmd.ExecuteScalar();
         }
         finally
         {
            // Close the connection
             if (conn != null)
             {
                 conn.Close();
             }
         }
         return count;
     }
 }

Trong Lising 1, đối tượng người dùng SqlConnection được khởi tạo trong lớp SqlCommandDemo. Điều này hợp lệ vì đối tượng người dùng sẽ được quét dọn khi CLR garbage collector thao tác. Điều quan trọng là ta đóng connection sau khi sử dụng nó. Chương trình mở connection trong một khổi try và đóng nó trong một khối finally cho mỗi phương pháp .
Phương thức ReadData ( ) hiển thị nội dung của cột CategoryName của bảng Categories. Chúng ta dùng nó vài lần trong phương pháp Main ( ) để hiển thị trạng thái hiện tại của bảng Categories. Bảng này sẽ bị đổi khác khi mỗi lệnh insert, update, delete được thực thi .

Tổng kết

Đối tượng SqlCommand được cho phép bạn truy vấn và gửi lệnh đến một database. Nó có những phương pháp sử dụng cho những lệnh khác nhau. Phương thức ExecuteReader ( ) trả về một đối tượng người dùng SqlDataReader để hiển thị hiệu quả của câu truy vấn. Cho những lệnh insert, update và delete, bạn dùng phương pháp ExecuteNonQuery ( ). Nếu bạn chỉ cần một giá trị đơn từ một câu truy vấn, phương pháp ExecuteScalar ( ) là lựa chọn tốt nhất .
Tôi hy vọng bạn thích lesson này và chào mừng bạn đến bài tiếp theo trong series này, Lesson 04 : Đọc dữ liệu với SqlDataReader .
Nguồn tìm hiểu thêm : http://www.csharp-station.com/Tutorials/AdoDotNet/lesson03.aspx

Trang chủ

Đánh giá:

Share this:

Thích bài này:

Thích

Đang tải …

ĐÁNH GIÁ post
Bài viết liên quan

Tư vấn miễn phí (24/7) 094 179 2255