![《Delphi程序設(shè)計(jì)實(shí)訓(xùn)教程》課件第7章_第1頁(yè)](http://file4.renrendoc.com/view12/M0B/34/3A/wKhkGWdQNXKAXnqoAAO_JXKuE20553.jpg)
![《Delphi程序設(shè)計(jì)實(shí)訓(xùn)教程》課件第7章_第2頁(yè)](http://file4.renrendoc.com/view12/M0B/34/3A/wKhkGWdQNXKAXnqoAAO_JXKuE205532.jpg)
![《Delphi程序設(shè)計(jì)實(shí)訓(xùn)教程》課件第7章_第3頁(yè)](http://file4.renrendoc.com/view12/M0B/34/3A/wKhkGWdQNXKAXnqoAAO_JXKuE205533.jpg)
![《Delphi程序設(shè)計(jì)實(shí)訓(xùn)教程》課件第7章_第4頁(yè)](http://file4.renrendoc.com/view12/M0B/34/3A/wKhkGWdQNXKAXnqoAAO_JXKuE205534.jpg)
![《Delphi程序設(shè)計(jì)實(shí)訓(xùn)教程》課件第7章_第5頁(yè)](http://file4.renrendoc.com/view12/M0B/34/3A/wKhkGWdQNXKAXnqoAAO_JXKuE205535.jpg)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第7章系教學(xué)管理系統(tǒng)之學(xué)生教務(wù)子系統(tǒng)
-SQL語(yǔ)言在Delphi中的應(yīng)用
7.1學(xué)生教務(wù)子系統(tǒng)案例分析
7.2相關(guān)知識(shí)點(diǎn)
7.3實(shí)現(xiàn)方法
7.4案例總結(jié)
7.1學(xué)生教務(wù)子系統(tǒng)案例分析
7.1.1任務(wù)的提出
每學(xué)期學(xué)生要進(jìn)行選修課程的工作,如果以手工方式進(jìn)行,比較麻煩且容易出錯(cuò)??荚嚱Y(jié)束后,學(xué)生最關(guān)心自己每門(mén)課程的分?jǐn)?shù),以及該課程成績(jī)的總體狀況,往往等不到成績(jī)單發(fā)送到個(gè)人,就去系里詢問(wèn),這時(shí)是系教務(wù)干事最忙的時(shí)候,沒(méi)有時(shí)間答復(fù)學(xué)生的咨詢。運(yùn)用學(xué)生教務(wù)子系統(tǒng),可解決學(xué)生選修課程信息維護(hù)和課程成績(jī)查詢的問(wèn)題,使用計(jì)算機(jī)進(jìn)行管理,效率高,出錯(cuò)率低,學(xué)生滿意度高。
學(xué)生教務(wù)子系統(tǒng)的實(shí)現(xiàn)主要是使用數(shù)據(jù)集組件TQuery。通過(guò)本章子系統(tǒng)的實(shí)現(xiàn),我們將學(xué)習(xí)對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行維護(hù)的另一種方式,即通過(guò)數(shù)據(jù)集組件TQuery使用SQL語(yǔ)句來(lái)操作數(shù)據(jù)集當(dāng)中的數(shù)據(jù)。7.1.2系統(tǒng)設(shè)計(jì)
本章的學(xué)生教務(wù)子系統(tǒng)的功能模塊圖如圖7.1所示。
圖7.1學(xué)生教務(wù)子系統(tǒng)功能模塊圖
7.1.3數(shù)據(jù)庫(kù)設(shè)計(jì)及實(shí)現(xiàn)
學(xué)生教務(wù)子系統(tǒng)與教務(wù)管理子系統(tǒng)同屬于教學(xué)管理系統(tǒng),使用同一個(gè)數(shù)據(jù)庫(kù),其設(shè)計(jì)與實(shí)現(xiàn)見(jiàn)第6章。
7.2相
關(guān)
知
識(shí)
點(diǎn)
7.2.1TQuery組件在SQL編程中的運(yùn)用
在Delphi中是通過(guò)TQuery組件來(lái)實(shí)現(xiàn)對(duì)SQL語(yǔ)言支持的,也就是說(shuō)用Delphi開(kāi)發(fā)數(shù)據(jù)庫(kù)應(yīng)用程序時(shí),使用SQL語(yǔ)言操作數(shù)據(jù)庫(kù)中的數(shù)據(jù)的途徑是通過(guò)TQuery組件。
TQuery組件在Delphi中占有非常重要的地位。
1.TQuery組件的使用
TQuery組件是一個(gè)數(shù)據(jù)集組件,它在Delphi組件面板的“BDE”標(biāo)簽頁(yè)上,該組件與TTable組件具有很多共同的特性,實(shí)現(xiàn)了Delphi對(duì)SQL語(yǔ)言的支持。在Delphi開(kāi)發(fā)的數(shù)據(jù)庫(kù)應(yīng)用中,SQL語(yǔ)句是通過(guò)TQuery組件傳遞到要訪問(wèn)的數(shù)據(jù)庫(kù)系統(tǒng)的數(shù)據(jù)庫(kù)引擎中,由數(shù)據(jù)庫(kù)引擎具體執(zhí)行SQL語(yǔ)句,以實(shí)現(xiàn)對(duì)數(shù)據(jù)的操作,而不是傳遞給Delphi中的BDE,由BDE實(shí)施具體的SQL動(dòng)作。
TTable組件在訪問(wèn)數(shù)據(jù)庫(kù)時(shí)已經(jīng)具備很強(qiáng)大的功能,而TQuery組件提供了一些TTable組件不具備的功能,它們是:
●多表聯(lián)接查詢;
●復(fù)雜的嵌套查詢;
●明確需要使用SQL語(yǔ)言進(jìn)行的操作。
TTable組件不能使用SQL語(yǔ)言,而TQuery組件可以使用SQL語(yǔ)言,因此TQuery組件也就具備了強(qiáng)大的關(guān)系查詢能力。
在Delphi應(yīng)用程序中編寫(xiě)和使用的SQL語(yǔ)句有兩種,即靜態(tài)SQL語(yǔ)句和動(dòng)態(tài)SQL語(yǔ)句。
靜態(tài)方式是在程序設(shè)計(jì)階段,把SQL命令文本作為T(mén)Query組件的SQL屬性值進(jìn)行設(shè)置。靜態(tài)SQL語(yǔ)句在程序設(shè)計(jì)時(shí)便已固定下來(lái),它不包含任何參數(shù)和變量。這樣,當(dāng)執(zhí)行應(yīng)用程序時(shí),Delphi便執(zhí)行TQuery組件SQL屬性中設(shè)置的SQL命令。如果是SQL中的查詢命令,把TQuery組件通過(guò)TDataSource組件與數(shù)據(jù)控制組件相連,查詢的結(jié)果將會(huì)顯示在與TQuery組件相連接的數(shù)據(jù)瀏覽組件中。例如下面的語(yǔ)句便是一條靜態(tài)SQL語(yǔ)句:
Select*FromSCOREWherecourse='C003'
動(dòng)態(tài)SQL語(yǔ)句也被稱作參數(shù)化的語(yǔ)句,即SQL語(yǔ)句中包含一些參數(shù)變量,在程序中可以動(dòng)態(tài)地為這些參數(shù)賦值,在程序運(yùn)行過(guò)程中,各個(gè)參數(shù)值是可變的。例如下面的語(yǔ)句便是一條動(dòng)態(tài)SQL語(yǔ)句:
Select*FromSCOREWherecourse=:c
2.在TQuery組件中編寫(xiě)簡(jiǎn)單的SQL查詢命令示例
此處我們通過(guò)一個(gè)簡(jiǎn)單的實(shí)例學(xué)習(xí)如何使用TQuery組件編寫(xiě)簡(jiǎn)單的SQL查詢命令,并在Delphi應(yīng)用程序中實(shí)現(xiàn)SQL查詢。
例如,如果我們想查詢出選修課程“C003”的全部學(xué)生的學(xué)號(hào)、課程號(hào)及成績(jī),將結(jié)果顯示在表格中,可按下列步驟來(lái)實(shí)現(xiàn):
(1)在應(yīng)用程序的窗體中放置一個(gè)TQuery組件、一個(gè)TDataSource組件和一個(gè)TDBGrid組件,TDBGrid組件對(duì)象的DataSource屬性值為T(mén)DataSource組件對(duì)象名稱,TDataSource組件對(duì)象的DataSet屬性值為T(mén)Query組件對(duì)象名稱。
(2)設(shè)置窗體TQuery組件對(duì)象Query1的DatabaseName屬性值為T(mén)EACH。
(3)雙擊ObjectInspector窗口中Query1的SQL屬性,將顯示StringListEditor窗口,在該窗口中輸入SQL語(yǔ)句:
select*fromscorewherecourse='C003'
然后單擊“OK”按鈕,關(guān)閉StringListEditor窗口。
(4)設(shè)置Query的Active屬性為T(mén)rue。
這樣在TDBGrid組件對(duì)象上馬上可以看見(jiàn)SQL語(yǔ)句查詢的結(jié)果。
7.2.2SQL語(yǔ)言編程概述
在Delphi應(yīng)用程序中的SQL命令語(yǔ)句包含在TQuery組件的SQL屬性中,TQuery組件的SQL屬性是TString類型的,也就是說(shuō)SQL屬性值是一個(gè)字符串列表,這個(gè)字符串列表非常類似于一個(gè)字符串類型的數(shù)組。
1.SQL命令文本的編輯
1)使用StringListEditor編輯SQL命令文本
在程序設(shè)計(jì)過(guò)程中,可以通過(guò)對(duì)象查看器編輯SQL屬性。在ObjectInspector中雙擊SQL屬性,這樣會(huì)打開(kāi)StringListEditor窗口,如圖7.2所示,在其中我們便可以編輯SQL命令。
圖7.2編輯SQL命令的StringListEditor窗口
2)在代碼中編輯SQL命令文本
可以在代碼中編輯SQL命令文本。在程序運(yùn)行過(guò)程中,要想設(shè)置TQuery組件的SQL屬性,必須首先調(diào)用TQuery組件的Close方法關(guān)閉當(dāng)前的TQuery組件,然后調(diào)用Clear方法清除SQL屬性中現(xiàn)存的SQL命令的文本內(nèi)容,最后調(diào)用Add方法為SQL屬性設(shè)置新的SQL命令語(yǔ)句。例如:
Query1.Close; //關(guān)閉Query1
Query1.SQL.Clear; //清除SQL屬性中的SQL命令文本
Query1.SQL.Add('Select*FromSCORE');
Query1.SQL.Add('WhereCOURSE=''C003'''); //添加SQL語(yǔ)句
注意在應(yīng)用程序中為SQL屬性設(shè)置新的SQL命令語(yǔ)句時(shí),必須要調(diào)用Clear方法清除SQL屬性中現(xiàn)存的SQL命令語(yǔ)句;如果不調(diào)用Clear方法而直接調(diào)用Add方法向SQL屬性中設(shè)置SQL命令語(yǔ)句,那么新設(shè)置的SQL命令語(yǔ)句會(huì)追加在現(xiàn)存SQL命令語(yǔ)句的后面,在程序運(yùn)行時(shí)常常會(huì)出現(xiàn)出乎意料的查詢結(jié)果甚至程序無(wú)法運(yùn)行下去。
2.SQL命令的執(zhí)行
在為T(mén)Query組件設(shè)置完SQL屬性的屬性值之后,即編寫(xiě)好SQL命令之后,可用多種方式來(lái)執(zhí)行SQL命令。
在設(shè)計(jì)過(guò)程中,設(shè)置完TQuery組件的SQL屬性之后將其Active屬性值設(shè)置為T(mén)rue,
這樣便可以執(zhí)行SQL屬性中的SQL命令,如果應(yīng)用程序中有與TQuery組件相連的數(shù)據(jù)控制組件(如TDBGrid、TDBEdit等),那么在這些數(shù)據(jù)控制組件中會(huì)顯示SQL命令的執(zhí)行結(jié)果。
在應(yīng)用程序運(yùn)行過(guò)程中,通過(guò)程序調(diào)用TQuery組件的Open方法或ExecSQL方法可以執(zhí)行其SQL屬性中的SQL命令。
Open方法和ExecSQL方法是不一樣的,在程序設(shè)計(jì)過(guò)程中一定要注意。Open方法只能用來(lái)執(zhí)行SQL語(yǔ)言的查詢語(yǔ)句(Select命令),并返回一個(gè)查詢結(jié)果集;而ExecSQL方法主要是用來(lái)執(zhí)行其他的SQL語(yǔ)句,如INSERT、UPDATE、DELETE等命令。例如:
Query1.Open;如果調(diào)用Open方法,而沒(méi)有查詢結(jié)果時(shí),會(huì)出錯(cuò)。此時(shí)應(yīng)該調(diào)用ExecSQL方法來(lái)代替Open方法:
Query1.ExecSQL;
當(dāng)然在設(shè)計(jì)應(yīng)用程序時(shí),有時(shí)程序設(shè)計(jì)人員是無(wú)法確定TQuery組件中的SQL語(yǔ)句是否會(huì)返回一個(gè)查詢結(jié)果的。對(duì)于這種情況應(yīng)當(dāng)用Try…Except模塊來(lái)設(shè)計(jì)程序。在Try部分調(diào)用Open方法,而在Except部分調(diào)用ExceSQL方法,這樣才能保證程序的正確運(yùn)行。
例如:
Try
Query1.Open;
Except
Query1.ExecSQL;
End;
3.通過(guò)TQuery組件獲得活動(dòng)的數(shù)據(jù)
通過(guò)TTable組件從數(shù)據(jù)庫(kù)中獲得的數(shù)據(jù)都是活動(dòng)的,也就是說(shuō)用戶可以直接通過(guò)數(shù)據(jù)控制組件對(duì)這些數(shù)據(jù)進(jìn)行編輯修改。而通過(guò)TQuery組件可以獲得兩種類型的數(shù)據(jù):
1)“活動(dòng)”的數(shù)據(jù)
這種數(shù)據(jù)就與通過(guò)TTable組件獲得的數(shù)據(jù)一樣,用戶可以通過(guò)數(shù)據(jù)控制組件來(lái)編輯修改這些數(shù)據(jù),并且當(dāng)調(diào)用Post方法或當(dāng)焦點(diǎn)離開(kāi)當(dāng)前的數(shù)據(jù)控制組件時(shí),用戶對(duì)數(shù)據(jù)的修改自動(dòng)地被寫(xiě)回到數(shù)據(jù)庫(kù)中。
2)非活動(dòng)”的數(shù)據(jù)(只讀數(shù)據(jù))
對(duì)于“非活動(dòng)”的數(shù)據(jù),用戶通過(guò)數(shù)據(jù)控制組件不能修改其中的數(shù)據(jù)。在缺省情況下,通過(guò)TQuery組件獲得的查詢結(jié)果數(shù)據(jù)是只讀數(shù)據(jù)即“非活動(dòng)”的,要想獲得“活動(dòng)”的數(shù)據(jù),在應(yīng)用程序中必須要設(shè)置TQuery組件的RequestLive屬性值為T(mén)rue,然而并不是在任何情況下如此設(shè)置都可以獲得“活動(dòng)”的數(shù)據(jù)。要想獲得“活動(dòng)”的數(shù)據(jù),除了將TQuery組件的RequestLive屬性設(shè)置為T(mén)rue外,還要能夠返回“活動(dòng)”的數(shù)據(jù),相應(yīng)的SQL命令語(yǔ)句要滿足一定的約束條件。根據(jù)查詢的數(shù)據(jù)庫(kù)類型不同,約束條件也不相同,大致的約束條件如下:
(1)查詢只能涉及到一個(gè)單獨(dú)的表;
(2)SQL語(yǔ)句中不能包含ORDERBY命令;
(3)SQL語(yǔ)句中不能含有SUM、AVG等聚集運(yùn)算符;
(4)在Select后的字段列表中不能有計(jì)算字段。
當(dāng)TQuery組件返回一個(gè)“活動(dòng)”的查詢結(jié)果數(shù)據(jù)集時(shí),它的CanModify屬性的值會(huì)被設(shè)置成True。
7.2.3動(dòng)態(tài)SQL語(yǔ)句的使用
動(dòng)態(tài)SQL語(yǔ)句又被稱為參數(shù)化的SQL語(yǔ)句,在其中包含著在程序過(guò)程中可以變化的參數(shù)。在實(shí)際的程序設(shè)計(jì)中使用得更多的是動(dòng)態(tài)SQL語(yǔ)句。此處將重點(diǎn)介紹如何給動(dòng)態(tài)SQL語(yǔ)句的參數(shù)賦值,以在應(yīng)用程序中靈活地使用SQL語(yǔ)句。動(dòng)態(tài)SQL語(yǔ)句的編寫(xiě)、執(zhí)行等與前面介紹的靜態(tài)SQL語(yǔ)句的編寫(xiě)、執(zhí)行是相同的。
對(duì)于動(dòng)態(tài)SQL語(yǔ)句中的參數(shù),我們可以通過(guò)兩種途徑來(lái)為它賦值。
1.使用參數(shù)編輯器(ParameterEditor)為參數(shù)賦值
具體方法是:選中TQuery組件,在對(duì)象查看器中雙擊Params屬性,便可以打開(kāi)參數(shù)編輯器。
例如,在TQuery組件對(duì)象Query1的SQL屬性中設(shè)置如下的SQL語(yǔ)句:
Setect*FromSCOREWherecourse=:c;
Query1的DatabaseName屬性為T(mén)EACH。Query1的SQL語(yǔ)句中的c為參數(shù)變量。雙擊對(duì)象查看器中的Params屬性,打開(kāi)參數(shù)編輯器,可看見(jiàn)其中所有的參數(shù)(本例中只有一個(gè)參數(shù)“0-c”),選擇參數(shù)c,對(duì)象查看器內(nèi)容如圖7.3所示。
圖7.3參數(shù)值的賦值方式之一
在對(duì)象查看器中,DateType組合框中選擇該參數(shù)的數(shù)據(jù)類型為字符型ftString,ParamType中選擇ptInput,在Value編輯框中可以為參數(shù)c賦值。這樣Query1的SQL查詢便準(zhǔn)備好了,參數(shù)值賦值給了動(dòng)態(tài)SQL語(yǔ)句中相應(yīng)的參數(shù),此時(shí)當(dāng)把Query1的Active屬性設(shè)置成True,與Query1組件相連的數(shù)據(jù)控制組件中便會(huì)顯示出查詢結(jié)果。
通過(guò)參數(shù)編輯器為參數(shù)賦值,這種方式缺乏應(yīng)有的靈活性,在實(shí)際應(yīng)用中用得較少,在實(shí)際應(yīng)用中程序設(shè)計(jì)人員希望用更靈活方便的方式為參數(shù)賦值,這就是我們接下來(lái)要介紹的另一種途徑。
2.在程序中為參數(shù)賦值
在程序中為動(dòng)態(tài)SQL語(yǔ)句的參數(shù)賦值有四種方法:
●根據(jù)參數(shù)在SQL語(yǔ)句中出現(xiàn)的順序,設(shè)置TQuery組件的Params屬性值為參數(shù)賦值。
●使用ParamValues屬性為各參數(shù)賦值。
●調(diào)用ParamByName方法為各參數(shù)賦值。
●
將TQuery組件的DataSource屬性設(shè)置為另一個(gè)數(shù)據(jù)源,這樣將另一個(gè)數(shù)據(jù)源中與當(dāng)前TQuery組件的SQL語(yǔ)句中的參數(shù)名相匹配的字段值賦給其對(duì)應(yīng)的參數(shù)。
1)使用Params屬性為參數(shù)賦值
TQuery組件有一個(gè)Params屬性,它們?cè)谠O(shè)計(jì)期間不可用,在程序運(yùn)行期間可用,并且是動(dòng)態(tài)建立的。當(dāng)為T(mén)Query組件編寫(xiě)動(dòng)態(tài)SQL語(yǔ)句時(shí),Delphi會(huì)自動(dòng)地建立一個(gè)數(shù)組Params,數(shù)組Params是從0下標(biāo)開(kāi)始的,依次對(duì)應(yīng)動(dòng)態(tài)SQL語(yǔ)句中的每個(gè)參數(shù),也就是說(shuō)動(dòng)態(tài)SQL語(yǔ)句中第一個(gè)參數(shù)對(duì)應(yīng)Params[0],第二個(gè)參數(shù)對(duì)應(yīng)Params[1],依此類推。
例如,有一個(gè)TQuery組件對(duì)象Query1,我們?yōu)樗帉?xiě)的動(dòng)態(tài)SQL語(yǔ)句是:
InsertIntoSCORE(course,student,score)
Values(:cou,:stu,:score)
對(duì)于上述這條動(dòng)態(tài)SQL語(yǔ)句中的參數(shù),我們可以利用Query1的Params屬性為參數(shù)賦值:
Query1.Params[0].AsString:='C003';
Query1.Params[1].AsString:='20060066';
Query1.Params[2].AsInteger:=90;
上述語(yǔ)句將把'C003'賦值給參數(shù):cou,'20060066'賦值給參數(shù):stu,90賦值給參數(shù):score。
2)使用Params的ParamValues屬性為參數(shù)賦值
TQuery組件有一個(gè)Params屬性是參數(shù)數(shù)組,它有一個(gè)ParamValues屬性,使用ParamValues['參數(shù)名']的形式可以直接引用到參數(shù)名指定的參數(shù)的值。使用這種方式是直接引用到參數(shù)的值,所以在使用該形式對(duì)參數(shù)進(jìn)行賦值時(shí),不必使用AsString等類型轉(zhuǎn)換函數(shù)進(jìn)行類型轉(zhuǎn)換。使用這種方式時(shí)要知道參數(shù)的名字。
對(duì)于上面的例子,也可以使用下面的方式對(duì)參數(shù)賦值:
Query1.Params.ParamValues['cou']:='C003';
Query1.Params.ParamValues['stu']:='20060066';
Query1.Params.ParamValues['score']:=90;
3)使用ParamByName方法為參數(shù)賦值
ParamByName是一個(gè)函數(shù),以動(dòng)態(tài)SQL語(yǔ)句中的參數(shù)名字作為調(diào)用ParamByName函數(shù)的實(shí)際參數(shù),這樣便可以為它們賦值。使用這種賦值方法,必須要知道動(dòng)態(tài)SQL語(yǔ)句參數(shù)的名字。
例如在上面的例子中,也可以用下述方法給參數(shù)賦值:
Query1.ParamByName('cou').AsString:='C003';
Query1.ParamByName('stu').AsString:='20060066';
Query1.ParamByName('score').AsInteger:=90;注意使用上述第1)種和第3)種方式對(duì)參數(shù)進(jìn)行賦值時(shí),Query1.Params[0]或Query1.ParamByName('cou')等形式引用到的是參數(shù),其類型是TParam類型,而非String、Integer等類型,不能直接進(jìn)行賦值,所以這兩種方式引用參數(shù)后都要使用AsString、AsInteger等類型轉(zhuǎn)換函數(shù)進(jìn)行類型轉(zhuǎn)換后再賦值。
4)使用DataSource屬性為參數(shù)賦值
上述三種方法的共同特點(diǎn)是:在為各參數(shù)賦值時(shí),我們是知道各參數(shù)對(duì)應(yīng)的具體參數(shù)值的。而在具體的應(yīng)用程序中,有些參數(shù)的值常常是無(wú)法確定的。例如參數(shù)的值來(lái)自于另一個(gè)查詢結(jié)果,對(duì)于這種情況,Delphi提供了使用DataSource屬性為動(dòng)態(tài)SQL語(yǔ)句中的參數(shù)賦值。當(dāng)SQL語(yǔ)句中尚存在沒(méi)有賦值的參數(shù)時(shí),Delphi會(huì)自動(dòng)檢查T(mén)Query組件的DataSource屬性,如果為DataSource屬性設(shè)置了屬性值(該屬性的值是另一個(gè)TDataSource組件對(duì)象的名字),Delphi會(huì)把沒(méi)有賦值的參數(shù)與TDataSource組件對(duì)象對(duì)應(yīng)的數(shù)據(jù)集中的各字段進(jìn)行比較,Delphi會(huì)將同名的字段的值賦值給該參數(shù)。這種方法主要是實(shí)現(xiàn)主細(xì)表數(shù)據(jù)庫(kù)應(yīng)用,與我們?cè)趯W(xué)習(xí)使用TTable組件時(shí)曾創(chuàng)建主要——明細(xì)型數(shù)據(jù)庫(kù)應(yīng)用是相似的。
例如,在如圖7.4所示的應(yīng)用中,在左側(cè)表格中選定了某門(mén)課程,右側(cè)表格中相應(yīng)地顯示該門(mén)課程的所有成績(jī),注意右側(cè)表格內(nèi)容跟隨左側(cè)表格中所選定的課程而變化。窗體中放置了如表7-1所示的組件對(duì)象。
圖7.4TQuery主細(xì)表應(yīng)用
表7-1TQuery主細(xì)表應(yīng)用的主要組件對(duì)象及屬性表
在窗體的OnCreate事件中加入如下代碼:
procedureTForm1.FormCreate(Sender:TObject);
begin
database1.Open;
table1.Open;
query1.Open;
end;
Query1中的動(dòng)態(tài)SQL語(yǔ)句中的參數(shù):id,在設(shè)計(jì)期間中沒(méi)有給它賦值,代碼中也沒(méi)有對(duì)其賦值。當(dāng)該應(yīng)用程序運(yùn)行時(shí)Delphi會(huì)自動(dòng)地到其Datasource屬性中說(shuō)明的數(shù)據(jù)源datasource1對(duì)應(yīng)數(shù)據(jù)集table1中查找與參數(shù):id匹配的字段,而table1中正好有一個(gè)名字為
id的字段與參數(shù):id相匹配。
這樣table1數(shù)據(jù)集中當(dāng)前記錄的id字段值賦值給了參數(shù):id,
每當(dāng)移動(dòng)table1數(shù)據(jù)集中的記錄指針時(shí),參數(shù):id的值會(huì)隨之改變,而參數(shù):id的值發(fā)生改變時(shí),query1中的動(dòng)態(tài)SQL語(yǔ)句會(huì)根據(jù)新的參數(shù)值重新查詢,從數(shù)據(jù)庫(kù)表中獲取相應(yīng)的成績(jī)數(shù)據(jù),這樣也就實(shí)現(xiàn)了主要-明細(xì)型應(yīng)用。
7.3實(shí)
現(xiàn)
方
法
7.3.1教務(wù)管理子系統(tǒng)功能模塊的創(chuàng)建
在Delphi7中創(chuàng)建一個(gè)新的工程,工程名為“STTEACH.dpr”。
1.登錄窗體
圖7.5登錄窗體布局
登錄窗體的基本功能和布局與教務(wù)管理子系統(tǒng)中的登錄窗體相似,如圖7.5所示。
將教務(wù)子系統(tǒng)中的“clerk_login.pas”和“clerk_login.dfm”文件復(fù)制到新工程所存放的文件夾中。將clerk_login窗體添加到STTEACH工程中,再將該窗體另存為“stu_login.pas”,在文件夾中出現(xiàn)“stu_login.pas”及“stu_login.dfm”文件,可將該文件夾中的“clerk_login.pas”和“clerk_login.dfm”文件刪除。將窗體布局和“登錄”按鈕的OnClick代碼做適當(dāng)?shù)男薷模?/p>
procedureTf_login.Button1Click(Sender:TObject);
begin
...
ift_user['authority']='1'then
...
end;
2.主要功能窗體
學(xué)生教務(wù)子系統(tǒng)主要功能窗體名為“stu_main.pas”。學(xué)生教務(wù)子系統(tǒng)有兩部分功能:選修課程信息添加、刪除和成績(jī)查詢、統(tǒng)計(jì)。同樣,使用PageControl組件的兩個(gè)TabSheet來(lái)實(shí)現(xiàn)這兩部分功能。
1)學(xué)生選修課程記錄的添加與刪除
該界面的功能是進(jìn)行學(xué)生選修課程的信息維護(hù),包括選課信息的添加和刪除,若要修改則應(yīng)該先刪除再添加。左側(cè)DBGrid組件對(duì)象顯示學(xué)生未選修的課程具體信息,右側(cè)DBGrid組件對(duì)象顯示學(xué)生已經(jīng)選修的課程信息。在左側(cè)表格中選定課程,雙擊課程或點(diǎn)擊“加入”按鈕將添加該學(xué)生選修該課程的信息至SCORE表。在右側(cè)表格中選定課程,雙擊課程或點(diǎn)擊“刪除”按鈕將從SCORE表中刪除該學(xué)生選修該課程的記錄??倢W(xué)分要隨加入或刪除課程而動(dòng)態(tài)變化,數(shù)據(jù)表格的內(nèi)容也要隨加入或刪除課程而動(dòng)態(tài)變化。
圖7.6學(xué)生選課管理
表7-2學(xué)生選課管理界面主要組件對(duì)象及屬性表
關(guān)閉該窗體將中止整個(gè)應(yīng)用程序的運(yùn)行。
procedureTf_stu.FormClose(Sender:TObject;varAction:TCloseAction);
begin
application.Terminate;
end;在窗體的標(biāo)題上顯示登錄該應(yīng)用程序的學(xué)生姓名,在該窗體創(chuàng)建或顯示時(shí)執(zhí)行該代碼,將代碼放在窗體的OnShow事件中,代碼如下:
procedureTf_stu.FormShow(Sender:TObject);
begin
t_student.Filter:='id='''+trim(f_login.Edit1.Text)+'''';
t_student.Filtered:=true;
t_student.Open;
f_stu.Caption:=f_stu.Caption+'--學(xué)生:'+t_student['name'];
end;
在“學(xué)生選課”頁(yè)顯示時(shí),左側(cè)數(shù)據(jù)表格要顯示學(xué)生尚未選修的全部課程具體信息,右側(cè)數(shù)據(jù)表格中顯示學(xué)生已經(jīng)選修的全部課程信息,在總學(xué)分處顯示該學(xué)生已經(jīng)選修的全部課程的學(xué)分總和。這里分別使用了三個(gè)TQuery組件對(duì)象來(lái)實(shí)現(xiàn)。注意,此處總學(xué)分的計(jì)算要求總和,如果使用TTable組件,求總和要在程序中遍歷全部數(shù)據(jù)并求和,很麻煩,而使用SQL語(yǔ)句則直接使用統(tǒng)計(jì)函數(shù)求和即可。學(xué)生選修全部課程信息有課程編號(hào)和課程名稱,涉及到SCORE和COURSE兩個(gè)數(shù)據(jù)表中的數(shù)據(jù),使用TTable實(shí)現(xiàn)比較麻煩,使用SQL語(yǔ)句進(jìn)行這樣的查詢是很容易實(shí)現(xiàn)的。而在左側(cè)數(shù)據(jù)表格中顯示學(xué)生尚未選修的全部課程具體信息,要從COURSE表中去掉已經(jīng)選修的課程,然后顯示這些課程的信息,使用SQL語(yǔ)句進(jìn)行這樣的查詢都比較復(fù)雜,更不會(huì)使用TTable來(lái)實(shí)現(xiàn),故三處的數(shù)據(jù)都來(lái)自TQuery數(shù)據(jù)集。我們看到此處TabSheet1的OnShow事件代碼非常簡(jiǎn)單,因?yàn)榇蟛糠止ぷ魇窃谇懊嬖O(shè)置TQuery組件對(duì)象的SQL屬性時(shí)完成的。注意查看前面屬性表格中TQuery組件對(duì)象的SQL屬性值。注意,由于登錄應(yīng)用程序的學(xué)生不同,SQL的內(nèi)容也會(huì)不同,所以三個(gè)TQuery組件對(duì)象的SQL屬性值中都使用了參數(shù),并在程序中動(dòng)態(tài)地給出參數(shù)值。
procedureTf_stu.TabSheet1Show(Sender:TObject);
begin
q_course1.Close;
q_course1.Params[0].AsString:=trim(f_login.Edit1.Text);
q_course1.Open;
q_course_selected.Close;
q_course_selected.Params[0].AsString:=trim(f_login.Edit1.Text);
q_course_selected.Open;
q_sum_credit_hour.Close;
q_sum_credit_hour.Params[0].AsString:=trim(f_login.Edit1.Text);
q_sum_credit_hour.Open;
dbgrid1.Columns[0].Width:=52;
dbgrid1.Columns[1].Width:=100;
dbgrid1.Columns[2].Width:=40;
dbgrid1.Columns[3].Width:=30;
dbgrid1.Columns[4].Width:=30;
end;點(diǎn)擊“加入”按鈕時(shí),使用insertinto語(yǔ)句實(shí)現(xiàn)數(shù)據(jù)的添加。該處并沒(méi)有使用一個(gè)預(yù)先定義好SQL屬性值的TQuery組件對(duì)象,而是在程序中使用SQL屬性的Clear、Add等方法動(dòng)態(tài)地設(shè)置SQL屬性值,這樣做是由于此處的添加與后面的刪除共用了一個(gè)TQuery組件對(duì)象。
procedureTf_stu.Button1Click(Sender:TObject);
begin
q_adddel.Close;
q_adddel.SQL.Clear;
q_adddel.SQL.Add('insertintoscore(student,course)');
q_adddel.SQL.Add('values('''+trim(f_login.Edit1.Text)+''','''+q_course1['課程編號(hào)']+''')');
q_adddel.ExecSQL;
TabSheet1Show(nil);
end;雙擊DBGrid1組件對(duì)象中的行時(shí),也會(huì)將該課程的選修信息添加至SCORE表,也就是相當(dāng)于點(diǎn)擊了“加入”按鈕。故在DBGrid1的OnDblClick事件中調(diào)用Button1的OnClick事件代碼:
procedureTf_stu.DBGrid1DblClick(Sender:TObject);
begin
Button1Click(nil);
end;點(diǎn)擊“刪除”按鈕時(shí),使用deletefrom語(yǔ)句實(shí)現(xiàn)數(shù)據(jù)的刪除。該處同樣是在程序中動(dòng)態(tài)地設(shè)置SQL屬性值。
procedureTf_stu.Button2Click(Sender:TObject);
begin
withq_adddeldo
begin
Close;
sql.Clear;
sql.Add('deletefromscore');
sql.Add('whereid='+inttostr(q_course_selected['id']));
ExecSQL;
end;
TabSheet1Show(nil);
end;雙擊DBGrid2組件對(duì)象中的行時(shí),同樣相當(dāng)于點(diǎn)擊了“刪除”按鈕。
procedureTf_stu.DBGrid2DblClick(Sender:TObject);
begin
Button2Click(nil);
end;
2)學(xué)生成績(jī)查詢與成績(jī)統(tǒng)計(jì)
本界面的功能是查詢學(xué)生的某門(mén)課程的成績(jī),并對(duì)該門(mén)課程做簡(jiǎn)單的統(tǒng)計(jì)。用一個(gè)DBGrid組件對(duì)象給出登錄該應(yīng)用程序的學(xué)生所選修并有成績(jī)的所有課程信息,提供給學(xué)生選擇查詢成績(jī)的課程。當(dāng)選定數(shù)據(jù)表格中的一行時(shí),在界面的右側(cè)給出該學(xué)生該課程的成績(jī),以及選修這門(mén)課程的全部學(xué)生的成績(jī)的平均值、最高值和最低值。
界面布局如圖7.7所示,其主要組件及屬性見(jiàn)表7-3。
圖7.7成績(jī)查詢
表7-3成績(jī)查詢界面主要組件對(duì)象及屬性表
“成績(jī)查詢”頁(yè)顯示時(shí),DBGrid3對(duì)象中要顯示學(xué)生選修并有成績(jī)的課程信息,右側(cè)顯示第一條記錄的課程成績(jī)信息。TabSheet2的OnShow事件代碼如下:
procedureTf_stu.TabSheet2Show(Sender:TObject);
begin
q_course_learned.Close;
q_course_learned.Params[0].AsString:=trim(f_login.Edit1.Text);
q_course_learned.Open;
DBGrid3CellClick(nil);
end;點(diǎn)擊DBGrid3的單元格時(shí),表示要顯示該行對(duì)應(yīng)的課程的該學(xué)生成績(jī)、課程的平均成績(jī)、最高成績(jī)和最低成績(jī)。平均成績(jī)、最高成績(jī)和最低成績(jī)分別使用了三個(gè)TQuery組件對(duì)象,這些TQuery組件對(duì)象均使用課程編號(hào)作為參數(shù),此處要將選定的課程編號(hào)賦值給參數(shù),以下分別使用三種方式引用參數(shù)值。DBGrid3的OnCellClick事件代碼如下:
procedureTf_stu.DBGrid3CellClick(Column:TColumn);
begin
q_avg.Close;
q_avg.Params.ParamValues['c']:=q_course_learned['課程編號(hào)'];
q_avg.Open;
q_max.Close;
q_max.Params[0].AsString:=q_course_learned['課程編號(hào)'];
q_max.Open;
q_min.Close;
q_min.Params.ParamByName('c').AsString:=q_course_learned['課程編號(hào)'];
q_min.Open;
end;本系統(tǒng)的代碼量不大,是因?yàn)榇罅渴褂昧薚Query組件。TQuery組件能夠很方便地對(duì)多個(gè)數(shù)據(jù)表進(jìn)行操作,并且能夠使用統(tǒng)計(jì)函數(shù)對(duì)數(shù)據(jù)進(jìn)行統(tǒng)計(jì),在這樣的情況下,我們首選TQuery組件而非TTable組件。
圖7.8用戶登錄窗體
7.3.2系統(tǒng)的實(shí)現(xiàn)
程序運(yùn)行時(shí),同樣會(huì)先顯示用戶登錄窗體,如圖7.8所示。
輸入用戶名和密碼后,單擊“登錄”按鈕,在此將驗(yàn)證用戶名、密碼和權(quán)限是否正確,若其中任一處驗(yàn)證失敗,將分別給出錯(cuò)誤提示信息。驗(yàn)證通過(guò),將顯示主要功能窗體,如圖7.9所示。
圖7.9選修課程信息維護(hù)
在窗體的標(biāo)題
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 天然氣的供應(yīng)安全與供應(yīng)保障考核試卷
- 建筑物清潔服務(wù)行業(yè)人才培養(yǎng)與交流考核試卷
- D掃描設(shè)備考核試卷
- 2025-2030年手術(shù)顯微鏡高清視頻錄制企業(yè)制定與實(shí)施新質(zhì)生產(chǎn)力戰(zhàn)略研究報(bào)告
- 2025-2030年插畫(huà)包裝設(shè)計(jì)行業(yè)深度調(diào)研及發(fā)展戰(zhàn)略咨詢報(bào)告
- 2025-2030年可再生能源建筑一體化企業(yè)制定與實(shí)施新質(zhì)生產(chǎn)力戰(zhàn)略研究報(bào)告
- 2025-2030年手持式計(jì)算器創(chuàng)新企業(yè)制定與實(shí)施新質(zhì)生產(chǎn)力戰(zhàn)略研究報(bào)告
- 2025-2030年整形外科手術(shù)模擬系統(tǒng)行業(yè)跨境出海戰(zhàn)略研究報(bào)告
- 2025-2030年地下空間環(huán)境監(jiān)測(cè)與預(yù)警機(jī)器人行業(yè)跨境出海戰(zhàn)略研究報(bào)告
- 2025-2030年地黃補(bǔ)腎滋陰液行業(yè)跨境出海戰(zhàn)略研究報(bào)告
- 2024年濰坊工程職業(yè)學(xué)院?jiǎn)握新殬I(yè)適應(yīng)性測(cè)試題庫(kù)完美版
- GB/T 44823-2024綠色礦山評(píng)價(jià)通則
- 人教版英語(yǔ)高考試卷與參考答案(2024年)
- 河砂、碎石生產(chǎn)質(zhì)量保證措施方案
- 三位數(shù)除以兩位數(shù)過(guò)關(guān)練習(xí)口算題大全附答案
- 紅樓夢(mèng)服飾文化
- 湖北省2024年村干部定向考試真題
- 2024年沙石材料運(yùn)輸合同
- 浙江省中小學(xué)心理健康教育課程標(biāo)準(zhǔn)
- 老年人能力評(píng)估標(biāo)準(zhǔn)解讀-講義課件
- 醫(yī)保物價(jià)管理培訓(xùn)
評(píng)論
0/150
提交評(píng)論