第7章 SQL Server數據庫應用程序開發

7.1. 客戶基本信息管理示例
本節給出的示例是客戶信息維護的程序實現,程序實現了查詢、添加和刪除客戶信息的功能。程序界面如下,
圖 7 1 合同管理系統客戶維護模塊功能界面
在圖 7 1中,窗口下部的客戶信息列表是自動顯示的。“插入”按鈕負責將新輸入的客戶信息插入到數據庫中並在客戶信息列表中顯示,“刪除”按鈕刪除客戶信息列表中當前行。
7.1.1. 準備數據庫環境
下面的過程在利用AdventureWorks示例數據庫創建一個簡單的數據庫Example,它有Customer和SalesOrderHeader兩個表,它們分別是AventureWorks數據庫中Salses.Customer和Sales.SalesOrderDetail表的簡化版本。
創建Example數據庫的操作如下:
(1) 創建Example數據庫。
(2) 運行下面的代碼在Example數據庫中創建表Customer和SalesOrderHeader。
USE Example
GO

SELECT C.CustomerID,P.LastName,P.FirstName,C.AccountNumber
INTO Customer
FROM AdventureWorks.Person.Person P INNER JOIN
AdventureWorks.Sales.Customer C
ON C.PersonID=P.BusinessEntityID;
GO

ALTER TABLE Customer ADD CONSTRAINT
PK_Customer PRIMARY KEY CLUSTERED
(
CustomerID
)

GO

SELECT SalesOrderID,CustomerID,OrderDate,DueDate,ShipDate
into SalesOrderHeader
FROM AdventureWorks.Sales.SalesOrderHeader
GO

ALTER TABLE SalesOrderHeader ADD CONSTRAINT
PK_SalesOrderHeader PRIMARY KEY CLUSTERED
(
SalesOrderID
)
GO

ALTER TABLE SalesOrderHeader ADD CONSTRAINT
FK_SalesOrderHeader_Customer FOREIGN KEY
(CustomerID) REFERENCES Customer(CustomerID)
GO

7.1.2. 創建項目和窗體

(1) 創建項目
打開Visual Studio,選擇“文件/新建/項目”菜單創建項目,進入VisualStudio.NET的“新建項目”對話框(圖 7 2),在“新建項目”對話框中選擇項目類型爲“Visual C#項目”,模板爲“Windows應用程序”,設置項目的名稱爲“客戶管理”,項目所在的路徑爲“C:\”,程序會將創建的項目存儲在“C:\客戶管理”目錄下,最後點擊“確定”按鈕完成項目的創建。
圖 7 2 創建客戶管理項目
這時會在Visual Studio中出現如圖 7 3所示的結果。
(2) 修改窗體的標題。
選擇Form1窗體,在右下角的屬性窗口中修改Form1的Text屬性爲“客戶管理”,結果Form1窗體的標題顯示爲“客戶管理”。如果選擇Form1後沒有出現屬性窗口,可以通過右鍵彈出菜單顯示屬性窗口。
(3) 添加控件
如果工具箱面板沒有出現,可以通過“視圖/工具箱”菜單顯示“工具箱”面板。在“工具箱”面板的“Windows窗體”分類中選擇“Label”,然後在Form1窗體放置“客戶編號”的位置點擊,窗體上會出現一個“label1”的控件,修改“屬性”窗口中label1的Text屬爲的值爲“客戶編號”。
再選擇“工具箱”面板中的文本框控件TextBox,然後在窗體上放置客戶編號的文本框的位置點擊,窗體上會出現一個textBox1的文本框,修改該文本框的Name屬性爲tbxCustomerID,Text屬性的值清空。
完成後的結果窗體如圖 7 4所示,
圖 7 3 新創建的客戶管理項目
圖 7 4 添加客戶編號文本框後的窗體

其它的文本和文本框的添加方法與客戶編號相似。
顯示客戶信息列表的是數據網格控件DataGrid,將它放置在所有輸入信息控件的下方,最後放置按鈕控件“插入”、“刪除”和“關閉”完成控件的添加。
註釋:如果Visual Studio的工具箱/數據分支中沒有出現DataGrid,則可以使用彈出菜單的“選擇項…”從.NET Framework組件中添加DataGrid控件。
(4) 佈置控件
你可以使用“格式”菜單來調整控件的大小和位置。修改數據網格控件的錨接屬性Anchor爲“Top,Bottom,Left,Right”,這樣,在運行的過程中數據網格與其它控件的相對位置不會隨着窗體的大小變化而變化(通過自動調整其大小來調整相對位置),將三個按鈕的Anchor屬性修改爲“Bottom,Right”,這樣,它們相對於窗體右下角的位置不會發生變化。
此時,運行程序後看不到客戶信息的內容,因爲你還沒有爲程序添加訪問數據庫的內容。
7.1.3. 查詢功能的實現
註釋:Visual Studio 2012中介紹的主要方法爲使用BindingSource與TableAdapter等組件,使用這種方法需要編寫的代碼更少,但其缺點是很多過程無法編寫代碼加以控制,只能通過設計器完成,也難以掌握ADO.NET數據訪問的相關概念和方法,因此,本示例中所使用的數據綁定方法爲較早版本中的方法。
1. 創建數據連接和數據適配器
(1) 從“工具箱”的“數據”選項卡中,將 OleDbDataAdapter 對象拖到窗體上。
“數據適配器配置嚮導”啓動,它將創建連接和適配器。
註釋:如果Visual Studio的工具箱/數據分支中沒有出現OleDbDataAdapter,則可以使用彈出菜單的“選擇項…”從.NET Framework組件中添加OleDbDataAdapter組件。
(2) 在該向導中,執行下列操作:
 在第二個窗格中,創建或選擇一個指向 Example數據庫的連接。
 在第三個窗格中,指定使用 SQL 語句來訪問數據庫。
 在第四個窗格中創建以下 SQL 語句:
圖 7 5 客戶信息的查詢語句
爲了便於生成 SQL 語句,請單擊“查詢生成器”以啓動“查詢生成器”。
(3) 單擊“完成”完成該向導。
嚮導完成後,將獲得一個連接oleDbConnection1,該連接包含與如何訪問數據庫有關的信息。數據適配器oleDbDataAdapter1和oleDbConnect連接對象將添加到組件窗口中。
每個數據適配器對象有DeleteCommand、InsertCommand、UpdateCommand和SelectCommand四個命令對象屬性,命令對象有連接對象屬性Connection和CommaneText命令文本屬性。oleDbDataAdapter1.SelectCommand.Connection的值爲oleDbConnection1,oleDbDataAdapter1.SelectCommand.CommandText爲上面的查詢語句。這些屬性的值都是使用設計器生成的,你可以手工修改這些內容。
註釋:.NET組件是實現了IComponent接口的類的實例,而控件是擁有用戶界面的組件。
2. 生成數據集
(1) 在組件窗口選擇數據適配器對象oleDbDataAdapter1生成數據集(可以從彈出菜單、智能編輯、屬性窗口中選擇“生成數據集”)。
顯示“生成數據集”對話框。
(2) 選擇“新建”選項,將數據集命名爲 dataSet1。
在“選擇要添加到數據集中的表”下面的列表中,應選擇“Customer”表。
(3) 確保“將此數據集添加到設計器”已選中,然後單擊“確定”。
最後,Visual Studio 將新數據集的一個實例dataSet11添加到窗體中。
此時,已完成爲從數據庫中獲取信息並將信息轉移到數據集所需的全部設置。準備創建一個顯示數據的窗體。
3. 綁定數據到數據網格
(1) 在客戶信息列表數據網格控件dataGrid1的DataSource 屬性中,選擇 dataSet11作爲數據源。不選擇 dataSet11.Customer。 如果是從DataSource屬性的下拉列表框中選擇,則展開“其它數據庫源”並選擇“列表實例”節點下面的數據庫集dataSet11而不選擇“項目數據源”下的數據集dataSet11。
(2) 在 DataMember 屬性中選擇“Customer”。設置這兩個屬性會將 dataSet11數據集內的 Customer數據表綁定到網格。
(3) 調整網格的大小,以便可以看到所有列。更改其高度,以便能夠看到多個客戶記錄。
4. 填充DataGrid控件
(1) 雙擊該窗體(空白處)以創建其 Load 事件的事件處理程序Form1_Load。
(2) 在該方法中,然後調用數據適配器的 Fill 方法,向該方法傳遞要填充的數據集。
下面的示例顯示完整的方法:
圖 7 6 窗體的Load事件處理方法
窗體的Load事件是窗體第一次顯示時觸發的事件,對於設計器來說,它是窗體的默認事件。按鈕的默認事件是Click。在設計器中,雙擊一個控件會自動生成該控件的默認事件處理方法,如果方法已經存在,則雙擊會打開事件處理方法的代碼。
事件處理方法Form1_Load中只有一條語句,該語句的功能是調用數據適配器oleDbAdapter1的Fill方法填充數據集dataSet11。它會導致使用數據連接對象oleDbConnection1連接數據庫並執行數據適配器中的SELECT語句,最後將查詢結果寫到數據集中。
數據適配器的Fill()方法的執行流程如下:
 如果SELECT命令對象的連接還沒有打開,則打開相應的連接;
 將SELECT SQL命令發送給數據庫服務器執行;
 服務器將查詢結果返回數據適配器,如果命令無法執行則拋出異常;
 數據適配器將查詢結果填充到指定的數據集dataSet11的數據表Customer;
 如果SELECT命令對象的連接是在執行Fill ()方法時執行了打開操作,關閉相應的連接;
 Fill()方法執行完畢。
註釋:當數據集dataSet11中的內容發生變化時,綁定的數據控件dataGrid1會收到數據集中內容發生變化的事件,並使用新的內容填充數據控件。這個任務與數據適配器無關。
(3) 運行程序,可以看到如圖 7 1所示的結果。
7.1.4. 添加功能的實現
(1) 雙擊“插入”按鈕,Visual Studio會自動生成該控件的Click事件的處理程序btnInsert_Click,其中btnInsert是控件的名稱。
(2) 在事件處理程序btnInsert_Click中輸入相應的內容,完整的處理程序如下,
方法一:使用命令對象完成插入操作

圖 7 7 插入按鈕的Click事件處理程序
在程序中首先構造一個插入命令,該命令負責插入記錄到Customer表中,它有4個參數,使用一個字符串對象strCustomerInsert存儲該命令。需要注意的是,前面添加的數據連接對象使用的是OLEDB數據提供程序,因此,這裏構造一個OLEDB數據提供程序的命令對象cmdCustomerInsert,構造函數的參數是插入命令語句的文本,最後將命令對象的Connection屬性設置成oleDbConnection1數據連接對象,這樣就完成了該命令對象的構造。
也可以不使用參數而直接將獲得的值加入到插入命令的文本中,後面的刪除操作演示了不使用參數的方法。
接下來的語句是創建命令對象的參數,它使用了命令對象參數集合Parameters的Add方法添加參數。Add方法的三個參數分別是參數的名稱、參數的數據類型和參數的最大長度。Add方法導致生成一個參數對象,其類型是Parameter,你可以將Add方法生成的參數對象存儲到一個類型爲Parameter的變量中,也可以像示例中的程序一樣直接給Parameter對象的Value屬性賦值。所賦的值是從客戶編號文本框中取得的內容。
在程序中,調用命令對象的ExecuteNonQuery方法執行插入命令,在此以前通過執行數據連接對象oleDbConnection1的Open方法建立與數據庫的連接,執行完命令後再調用數據連接對象的Close方法關閉與數據庫的連接。
程序的最後是刷新客戶信息。
運行程序,輸入客戶編號10999的相應信息,點擊“插入”按鈕,新記錄顯示在客戶信息中。
方法二:使用數據集完成插入操作

數據表的NewRow()方法創建一個與數據結構相同的數據行,即創建的新數據行與數據的數據行有相同的列。無法使用new DataRow()構造一個數據行對象,因爲DataRow的構造方法無法訪問。
構造的新行可以通過調用數據表的Rows集合屬性的Add()或InsertAt()方法添加到指定的數據表。雖然上面的代碼構造數據行和添加數據行使用的都是Customer數據表,但這兩個操作並沒有這樣的要求,但添加到數據表的數據行必須和數據表有相同的結構。
後續的代碼調用數據適配器的Update()方法將數據集dataSet11的Customer數據表的更新寫到數據庫。Update()方法是通過在數據庫服務器上執行其命令對象屬性DeleteCommand、InsertCommand和UpdateCommand中的SQL命令完成相應的更新操作。在執行Update()方法時,數據適配器會依次檢索相應數據表中的行,根據數據行的“插入”、“刪除”和“更新”標記完成數據庫的更新操作。如果沒新插入的行,則適配器並不會將相應的Insert命令發送給數據庫服務器。
數據適配器的Update()方法的執行流程如下:
(1) 數據適配器根據數據表中插入的新行填充相應INSERT命令對象屬性InsertCommand的參數,如果命令參數與插入新行的列不匹配則拋出異常;如果沒有新行則執行(6);
(2) 如果INSERT命令對象的連接還沒有打開,則打開相應的連接;
(3) 將INSERT SQL命令發送給數據庫服務器執行;
(4) 服務器執行完後回送給數據適配器一個執行結果的信息,如果命令無法執行則拋出異常;
(5) 如果INSERT命令對象的連接是在執行Update()方法時執行了打開操作,關閉相應的連接;
(6) 類似(1)-(5)完成刪除記錄的操作;
(7) 類似(1)-(5)完成修改記錄的操作;(注:三種操作的順序可能並不是這樣)
(8) Update()方法執行完畢。

7.1.5. 刪除功能的實現
(1) 雙擊“刪除”按鈕,Visual Studio自動添加該按鈕的Click事件處理程序btnDelete_Click,其中,btnDelete是該按鈕的控件名稱。
(2) 添加事件處理程序btnDelete_Click相應的內容,完整的程序如圖 7 10,
Click事件處理程序根據用戶在客戶信息列表中的選擇刪除所選擇的客戶記錄。程序首先從數據網格dataGrid1的當前行獲得客戶編號,具體的方法是
this.dataGrid1[this.dataGrid1.CurrentRowIndex,0]
其中,CurrentRowIndex是數據網格的屬性,表示當前行的序號(從0開始),因爲第1列顯示的是客戶編號,所以以上代碼從用戶選擇的行中取第1列的值,即客戶編號。
與前面插入操作的事件處理程序不同,在構造DELETE刪除命令時沒有使用參數,而是直接把獲取的客戶編號加入到DELETE命令中。
其它的內容與前面插入操作的編程相似,這裏不再作進一步的說明。如果有時間的話,也可以將打開與數據庫的連接、執行命令和關閉數據庫的連接編寫成一個方法,在插入和刪除操作的事件處理程序中調用該方法,這樣可以提高程序的複用性。刷新客戶列表信息的操作也可以編寫一個方法。
方法一:使用命令對象
圖 7 10 刪除按鈕的事件處理程序
方法二:使用數據適配器的命令對象

數據適配器對象oleDbDataAapter1有DeleteCommand、InsertCommand、UpdateCommand和SelectCommand四個命令對象屬性,它們的類型爲OleDbCommand。數據適配器的命令對象屬性的類型與數據適配器的類型有關,如果適配器對象的類型爲SqlDataAapter,則其命令對象屬性的類型爲SqlCommand。
使用數據適配器命令對象屬性與創建單獨的命令對象完成刪除記錄的操作沒有本質上的區別。
方法三:使用數據集刪除記錄

除了使用命令對象完成刪除記錄的操作方法外,還可以通過修改數據集完成刪除記錄的操作。每個數據集有一個類型爲DataTableCollection的數據表集合屬性Tables,要訪問某一個數據表可以通過索引如Tables[0]表示第1個表,或者數據表名如Tables[“Customer”]表示數據集中的Customer數據表。
每個數據表有一個類型爲DataRowCollection的行集合屬性Rows,其元素的類型爲DataRow。可以使用列索引或數據表列名訪問行集合中的元素,如Rows[0][0]和Rows[0][“CustomerID”]分別表示數據中的第1行的第1列和第1行的CustomerID列。
DataRow對象的Delete()從數據表中刪除該數據行對象。但需要注意的是,Delete()方法僅是在數據行對象上打上“已刪除”的標記,並不會真正從數據表中刪除該行,因爲,使用數據適配器將數據集中數據表的更新寫到數據庫時還需要該行的信息。當然,Delete()不會更新數據庫。如果要從數據表中刪除數據行,則調用數據的Rows集後屬性的Remove()或RemoveAt()方法。
註釋:實際上,數據集對象並不與數據庫交互,它並不提供更新數據庫的手段或其它任何操作數據庫的手段,與數據庫的交互是數據適配器對象的任務。
7.1.6. 更新功能的實現
由於dataGrid1對象綁定的數據爲數據集dataSet11中的數據表Customer,因此,在dataGrid1中可直接修改相應的內容,然後調用數據適配器的Update()方法,更新就會保存到數據庫。
需要注意的是,CustomerID的修改可能會導致違反引用性約束。
7.1.7. 如何運行該示例
本節給出的示例的完整文件可以到公共郵箱下載。示例是使用Visual Studio 2012和C#語言開發的,與連接的SQL Server數據庫的版本沒有聯繫,但要保證程序連接的數據庫服務器中有的示例數據庫Example和Customer和SalesOrderHeader表。
運行該示例需要做以下的工作:
(1) 創建Example數據庫。可以選擇下面的方法之一創建Example數據庫:
 使用前面的命令創建表Customer和SalesOrderHeader。
 通過“附加”數據庫添加Example。
(2) 修改連接信息。下載的示例中的連接信息可能與你的SQL Server環境並不相同,可以通過下面的方法之一修改連接對象的內容:
 方法一:直接修改數據連接對象的ConnectString屬性,將其中的Data Source=GUO-PC\SQLEXPRESS的數據庫服務器名修改爲你自己的數據庫服務器名。
 方法二:選擇“視圖/服務器資源管理器”菜單,打開“服務器資源管理器”,修改數據連接對象對應的數據連接或創建一個新的數據連接,然後再到數據連接對象oleDbConnection1的屬性面板中修改其ConnectString屬性,點擊右邊的下拉邊框並從中選擇相應的連接。
 方法三:重新運行數據適配器配置嚮導。選擇oleDbAdapter1數據適配器對象,點擊右鍵彈出菜單,選擇“配置數據適配器”。
7.2. 訂單查詢
圖 7 13顯示了訂單查詢程序的用戶界面。在用戶界面上,可以在“客戶姓”(表示LastName)文本框和“名”(表示FisrtName)文本框中輸入客戶的LastName和FirstName,在“發貨日期”中選擇或輸入發貨日期(表示ShipDate)。如果相應的條件爲空,則表示沒有該查詢條件。圖中顯示的查詢條件爲:LastName的值爲“Elson”,ShipDate的值爲2005年7月8日。
窗體的下面是一個顯示查詢結果的DataGrid,第一次運行時,顯示所有的訂單。相應的查詢語句爲:

點擊“查詢”按鈕在下面的DataGrid中顯示如圖 7 15所示的查詢結果。

程序的創建流程如下:
(1) 創建Windows窗體應用程序項目

(2) 在窗體上添加相應的控件,如下表所示:
名稱 類型 作用
tbxLastName TextBox 輸入客戶姓
tbxFirstName TextBox 輸入客戶名
tmpShipDate DateTimePicker 輸入發貨日期
btnSelect Button 查詢按鈕
dataGrid1 DataGrid 查詢查詢結果

(3) 將數據適配器組件從工具箱中拖到窗體Form1上,數據適配器配置嚮導啓動,配置後的連接對象olDbConnection1和數據適配器對象olDbDatapAdapter1出現在組件窗口。
數據連接對象的連接字符串如下:

數據適配器的查詢命令對象的查詢命令如圖 7 14所示。因爲數據適配器的查詢命令是兩個表的連接查詢,所以,數據適配器配置嚮導不會自動生成數據適配器的Delete、Insert和Update命令對象。如果需要,可以在設計器中手工修改或在程序中編碼修改數據適配器的DeleteCommand、InsertCommand和UpdateCommand屬性。
(4) 使用數據適配器oleDbDataAdapter1生成數據集,數據集的類型爲DataSet1,數據集對象dataSet11被自動添加到程序中並出現在組件窗口;
(5) 設置數據控件dataGrid1的數據綁定。屬性DataSource爲dataSet11,DataMember爲Customer。
(6) 設置窗體的加載事件,其代碼如下:
(7) 設置查詢按鈕的Click事件處理程序,實現訂單查詢功能。具體的代碼如下:
訂單查詢按鈕的事件處理程序中,因爲發貨日期只是判斷日期部分(年、月、日)的值是否相等,而沒有對時間部分(小時、分、秒等)進行判斷,因此,使用T-SQL的CAST()函數將DateTime類型的ShipDate轉換爲Date類型,將輸入的發貨日期和時間的字符串也轉換爲Date類型。
如果要判斷日期早於或易於某一時間,可以直接使用小於或大於。
7.3. 實驗內容與要求
使用ADO.NET並任選一種程序設計語言進行編程。
實驗報告需要說明所採用的方法、結果和總結(結果分析)。
實驗方法部分說明採用的開發環境,包括操作系統、數據庫管理系統及其版本、編程工具及其版本、和編程語言。如果使用ADO.NET則在實驗方法部分回答下面的問題:
(1) 使用哪種數據提供程序?
(2) 使用的數據連接對象是哪一個?連接對象是如何建立的?最後生成的連接對象中的連接字符串是什麼?代表什麼含義?
(3) 使用的數據適配器對象是什麼?其中的查詢或更新語句是什麼?如果有參數則參數是如何處理的?
(4) 使用的數據集對象是什麼?數據集中有哪些數據表?數據表是由哪些適配器對象生成的?(或採用其它方法)。
實驗方法中還需要給出手工添加的代碼及對代碼的說明。
實驗結果部分給出程序運行的界面和操作的簡單說明。
總結部分對實驗過程中出現的總是進行分析,同時提出所開發的程序還有哪些可以改進的地方。
7.3.1. 實驗一:合同管理系統查詢功能的程序實現
(1) 查詢合同。首先列表所有的合同(包括合同編號、合同名稱、簽訂日期、銷售負責人),然後可以輸入合同編號或合同名稱查詢某一特定合同的內容。
表 7 1 合同一覽表
編號 合同名稱 簽訂日期 銷售 合同額
1 北京理工大學校園網一期 2006-1-1 張軍 1000000.00
2 北京地理研究所存儲系統 2006-2-10 趙蕊 500000.00
3 上海通用備份系統 2006-5-8 張軍 7400000.00
4 北京理想公司存儲系統 2006-5-30 李向陽 1500000.00
5 北京重工 2006-7-1 李向陽 3000000.00
6 北京大學備份系統 2006-8-8 王桐 3800000.00
7 北京理工大學備份系統 2006-8-9 王桐 4000000.00

(2) 查詢應付款項。根據合同的內容查詢目前已經付款總和小於合同總額的且已經超過合同所規定的付款日期的合同信息,包括應付款款項和應付款的日期,將相應的內容通知銷售負責人以便進行應付款摧交。參考格式如下:
表 7 2 應付款款項
銷售 合同編號 合同名稱 應付款 應付日期
張軍 1 北京理工大學校園網一期 1000000.00 2006-12-1
張軍 3 上海通用備份系統 6500000.00 2006-12-4
李向陽 5 北京重工 230000.00 2006-11-1

(3) 員工基本信息維護,查詢、添加、修改和刪除員工的信息。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章