ADO.NET入門教程之Command物件與資料檢索

duanhao發表於2021-09-09

1. 準備

      學習知識最快也最好的方法,那就是將理論與實踐相結合。為了幫助大家更好的理解和掌握Command物件,我也準備了很多實踐的例子。我希望大家能做好充分的準備,這樣的話不至於在實踐的時候手忙腳亂。您需要準備以下幾件事情:

(1)確保你的電腦裝有SQL Server 2005/2008資料庫伺服器。如果未裝有SQL Server伺服器,點此下載 SQL Server 2008 EXPRESS R2。

(2)建立一個名為db_MyDemo的資料庫。

圖片描述

USE master;
GO
CREATE DATABASE db_MyDemo
ON
(
  NAME = MyDemo_data, /*指定檔案的邏輯名稱*/
  FILENAME = 'D:mydemo_dat.mdf',/*物理檔名稱*/
  SIZE = 10,/*指定檔案大小,單位MB*/
  MAXSIZE = 50,/*檔案最大值,單位MB*/
  FILEGROWTH = 5  /*自動增量*/
)
LOG ON
(
   Name = MyDemo_log,
   FILENAME = 'D:mydemo_log.ldf',
   SIZE = 5MB,
   MAXSIZE = 25MB,
   FILEGROWTH = 5MB
)
GO

圖片描述

(3)建立顧客表tb_SelCustomer。

圖片描述

use db_MyDemo;
GO
CREATE TABLE tb_SelCustomer
(
   ID INT IDENTITY(1,1) PRIMARY KEY, /*ID,主鍵*/
   Name varchar(20) NOT NULL, /*姓名*/
   Sex char(1) default('0'), /*性別:0為男,1為女,預設為0*/
   CustomerType char(1) default('0'), /*客戶型別:0為普通使用者,1為VIP使用者,預設為0*/
   Phone varchar(12), /*聯絡電話*/
   Email varchar(50), /*電子郵件*/
   ContactAddress varchar(200), /*聯絡地址*/
   Lat float, /*所在位置維度,用於在地圖顯示*/
   Lng float, /*所在位置經度,用於在地圖顯示*/
   Postalcode varchar(10), /*郵政編碼*/
   Remark varchar(50) /*備註*/
)

圖片描述

 好了,恭喜你!終於把準備工作做好了。下面,讓我們一起來揭開Command物件的面紗!

 

2. 什麼是Command物件?

      我們知道ADO.NET最主要的目的對外部資料來源提供一致的訪問。而訪問資料來源資料,就少不了增刪查改等操作。儘管Connection物件已經我們連線好了外部資料來源,但它卻忠於職守,並不提供對外部資料來源的任何操作。就在糾結萬分的時刻,Command物件誕生了。它封裝了所有對外部資料來源的操作(包括增、刪、查、改等SQL語句與儲存過程),並在執行完成後返回合適的結果。與Connection物件一樣,對於不同的資料來源,ADO.NET提供了不同的Command物件。具體來說,可分為以下Command物件。

.NET資料提供程式                                                                  對應Command物件                                                                                          
用於 OLE DB 的 .NET Framework 資料提供程式  OleDbCommand物件
用於 SQL Server 的 .NET Framework 資料提供程式  SqlCommand物件
用於 ODBC 的 .NET Framework 資料提供程式  OdbcCommand 物件
用於 Oracle 的 .NET Framework 資料提供程式  OracleCommand 物件

不管是哪種Command物件,它都繼承於DBCommand類。與DBConnection類一樣,DBCommand類也是抽象基類,不能被例項化,並期待派生類(對應於特定.NET資料提供程式的Command類)來實現方法。 DBCommand類定義了完善的健全的資料庫操作的基本方法和基本屬性,它的結構如下:

public abstract class DbCommand : Component, 
    IDbCommand, IDisposable

從上面我們可以知道,它繼承了Component類以及IDbCommand介面和IDisposable介面。

 

3. 必須掌握的幾個屬性

 CommandText: 獲取或設定對資料來源執行的文字命令。預設值為空字串。

 CommandType: 命令型別,指示或指定如何解釋CommandText屬性。CommandType屬性的值是一個列舉型別,定義結構如下:

public enum CommandType    
{      Text = 1,    //SQL 文字命令。(預設。)          
        StoredProcedure = 4,    // 儲存過程的名稱。          
        TableDirect = 512    //表的名稱。  
}

需要特別注意的是,將CommandType 設定為 StoredProcedure 時,應將 CommandText 屬性設定為儲存過程的名稱。 當呼叫 Execute 方法之一時,該命令將執行此儲存過程。

Connection: 設定或獲取與資料來源的連線。

Parameters: 繫結SQL語句或儲存過程的引數。引數化查詢中不可或缺的物件,非常重要。

Tranction: 獲取或設定在其中執行 .NET Framework 資料提供程式的 Command 物件的事務。

 

4. 必須掌握的幾個方法

 ExecuteNonQuery: 執行不返回資料行的操作,並返回一個int型別的資料。

 注意:對於 UPDATE、INSERT 和 DELETE 語句,返回值為該命令所影響的行數。 對於其他所有型別的語句,返回值 為 -1。

 ExecuteReader: 執行查詢,並返回一個 DataReader 物件。
 ExecuteScalar: 執行查詢,並返回查詢結果集中第一行的第一列(object型別)。如果找不到結果集中第一行的第一列,則返回 null 引用。

 

5. 如何建立Command物件?

      在建立Command物件之前,你需要明確兩件事情:(1)你要執行什麼樣的操作?(2)你要對哪個資料來源進行操作?明白這兩件事情,一切都好辦了。我們可用透過string字串來構造一條SQL語句,也可以透過Connection物件指定連線的資料來源。那麼我們如何將這些資訊交給Command物件呢?一般來說,有兩種方法:

(1)透過建構函式。程式碼如下:

string strSQL = "Select * from tb_SelCustomer";
SqlCommand cmd = new SqlCommand(strSQL, conn);

(2)透過Command物件的屬性。程式碼如下:

SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = strSQL;

提示:上面兩個例項是相對於SQL Server來說的,如果你訪問其他資料來源,應當選擇其他的Command物件。具體參照 #2 什麼是Command物件 中的表格。

 

6. 選擇合適的執行命令

      Command物件提供了豐富的執行命令操作,具體方法可參考 #4 必須掌握的幾個方法 。凡是有利有弊,Comandante物件既然提供多種執行命令,我們在實際開發中就要有所取捨,選擇合適的執行命令。其實,使用者對資料來源的操作不外乎CRUD-S(Create、Update、Delete、Select)操作。下面我將探討如何在不同的場景選擇合適的執行命令。

(1)場景一:執行CRUD操作,不返回資料行,返回影響的行數(可選)

      當我們對資料表的行(記錄)進行增加,刪除,更新操作或者處理資料定義語句(比如用Create Table來建立表結構)時,實際上資料庫是不返回資料行的,僅僅返回一個包含影響行數資訊的整數。一般地,在執行非查詢操作時,我們需要呼叫ExcuteNonQuery方法。還是,先看一個例項吧!我們在tb_SelCustomer表中插入一行記錄,程式碼如下:

圖片描述

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;//必須引入
using System.Data.SqlClient;//必須引入

namespace Command
{
    class Program
    {
        static void Main(string[] args)
        {
            string connSQL = @"Data Source=.SQLEXPRESS; Initial Catalog=db_MyDemo; Integrated Security=SSPI";//構造連線字串
            SqlConnectionStringBuilder connStr = new SqlConnectionStringBuilder(connSQL);

            using(SqlConnection conn = new SqlConnection(connStr.ConnectionString))
            {
                //拼接SQL語句
                  StringBuilder strSQL = new StringBuilder();
                strSQL.Append("insert into tb_SelCustomer ");
                strSQL.Append("values(");
                strSQL.Append("'liuhao','0','0','13822223333','liuhaorain@163.com','廣東省深圳市寶安區',12.234556,34.222234,'422900','備註資訊')");

                Console.WriteLine("Output SQL:n{0}",strSQL.ToString());

                //建立Command物件
                  SqlCommand cmd = new SqlCommand();
                cmd.Connection = conn;
                cmd.CommandType = CommandType.Text;
                cmd.CommandText = strSQL.ToString();

                try
                {
                    conn.Open();//一定要注意開啟連線

                       int rows = cmd.ExecuteNonQuery();//執行命令
                       Console.WriteLine("nResult: {0}行受影響",rows);
                }
                catch(Exception ex)
                {
                    Console.WriteLine("nError:n{0}", ex.Message);
                }
            }

            Console.Read();
        }
    }
}

圖片描述

 執行後,輸出結果如下:

圖片描述

從上面輸出資訊我們可以看到,已經成功的新增一行資料。

(2)場景二:執行Select操作,返回多個資料

      當我們透過執行Select操作返回一行或多行資料時,這時候ExcuteNonQuery就需要休息了。不過也別慌,話說Command物件手下猛將如雲,處理這種事情就需要請ExcuteReader方法上場了。ExcuteReader方法返回一個DataReader物件。DataReader是一個快速的,輕量級,只讀的遍歷訪問每一行資料的資料流。使用DataReader時,需要注意以下幾點:

  • DataReader一次遍歷一行資料,並返回一個包含列名字集合。

  • 第一次呼叫Read()方法獲取第一行資料,並將遊標指向下一行資料。當再次呼叫該方法時候,將讀取下一行資料。

  • 當檢測到不再有資料行時,Read()方法將返回false。

  • 透過HasRows屬性,我們知道查詢結果中是否有資料行。

  • 當我們使用完DataReader時,一定要注意關閉。SQL Server預設只允許開啟一個DataReader。

好吧,還是先看一個簡單的例子吧。查詢出tb_SelCustomer表中所有的資料。程式碼如下:

 

圖片描述

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace Command2
{
    class Program
    {
        static void Main(string[] args)
        {
            //構造連線字串
              SqlConnectionStringBuilder strConn = new SqlConnectionStringBuilder();
            strConn.DataSource = @"(local)SQLEXPRESS";
            strConn.InitialCatalog = "db_MyDemo";
            strConn.IntegratedSecurity = true;

            using (SqlConnection conn = new SqlConnection(strConn.ConnectionString))
            {
                string strSQL = "select * from tb_SelCustomer";
                SqlCommand cmd = new SqlCommand(strSQL, conn);//使用建構函式方式建立Command物件

                   conn.Open();//記得開啟連線

                try
                {
                    SqlDataReader reader = cmd.ExecuteReader();//執行ExecuteReader

                    if (reader != null && reader.HasRows)
                    {
                        int rows = 0;//記錄行數
                            Console.WriteLine("**********Records of tb_SelCustomer**********n");
                        while (reader.Read())
                        {
                            for (int i = 0; i 

圖片描述

執行上面程式碼後,我們可以看到在 場景(一) 中新增的資料。結果下圖所示。

 圖片描述

(3)場景三:執行Select操作,返回單個值

      上面兩個場景相信大家都十分熟悉了。但是,當我們在運算元據庫時僅僅只需要返回一個值(比如返回行數),那該怎麼辦呢?在此,我不得不承認Command物件確實人才濟濟,ExcuteScalar方法就是處理單個資料最優秀的人才。ExcuteScalar返回一個System.Object型別的資料,因此我們在獲取資料時需要進行強制型別轉換。當沒有資料時,ExcuteScalar方法返回System.DBNull。理論在於實踐,我們還是先看看一個例項吧!獲取tb_SelCustomer中的行數。程式碼如下:

 

圖片描述

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace Command3
{
    class Program
    {
        static void Main(string[] args)
        {
            string connSQL = @"Data Source=.SQLEXPRESS; Initial Catalog=db_MyDemo; Integrated Security=SSPI";

using (SqlConnection conn = new SqlConnection(connSQL))
{
string strSQL = "select count(*) from tb_SelCustomer";
SqlCommand cmd = new SqlCommand(strSQL, conn);//建立Command物件 

try
{
conn.Open();//一定要注意開啟連線 
int rows = (int)cmd.ExecuteScalar();//執行命令 
Console.WriteLine("執行ExcuteScalar方法:共{0}行記錄", rows);
}
catch (Exception ex)
{
Console.WriteLine("nError:n{0}", ex.Message);
}
}
            Console.Read();
        }
    }
}

圖片描述

 輸出結果如下:

 圖片描述

 

7. 總結

       終於鬆一口氣了,歷時一個多星期,總算將Command物件一些最最基礎但又重要的知識點講完了。也不知道大家對Command物件瞭解了多少,不過我敢肯定的是,只要你認認真真看完本篇文章,至少對Command物件的一些基礎知識有印象了。歸根結底,Command物件就是一個載體。它向資料庫傳達了使用者的操作資訊,而資料庫則透過Command物件向使用者返回處理結果。在下一篇文章中,我將講解Command物件的一些高階應用,希望大家能繼續關注和推薦。

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1343/viewspace-2801008/,如需轉載,請註明出處,否則將追究法律責任。

相關文章