《Delphi程序設(shè)計實訓(xùn)教程》課件第7章_第1頁
《Delphi程序設(shè)計實訓(xùn)教程》課件第7章_第2頁
《Delphi程序設(shè)計實訓(xùn)教程》課件第7章_第3頁
《Delphi程序設(shè)計實訓(xùn)教程》課件第7章_第4頁
《Delphi程序設(shè)計實訓(xùn)教程》課件第7章_第5頁
已閱讀5頁,還剩71頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第7章系教學(xué)管理系統(tǒng)之學(xué)生教務(wù)子系統(tǒng)

-SQL語言在Delphi中的應(yīng)用

7.1學(xué)生教務(wù)子系統(tǒng)案例分析

7.2相關(guān)知識點

7.3實現(xiàn)方法

7.4案例總結(jié)

7.1學(xué)生教務(wù)子系統(tǒng)案例分析

7.1.1任務(wù)的提出

每學(xué)期學(xué)生要進(jìn)行選修課程的工作,如果以手工方式進(jìn)行,比較麻煩且容易出錯??荚嚱Y(jié)束后,學(xué)生最關(guān)心自己每門課程的分?jǐn)?shù),以及該課程成績的總體狀況,往往等不到成績單發(fā)送到個人,就去系里詢問,這時是系教務(wù)干事最忙的時候,沒有時間答復(fù)學(xué)生的咨詢。運用學(xué)生教務(wù)子系統(tǒng),可解決學(xué)生選修課程信息維護(hù)和課程成績查詢的問題,使用計算機(jī)進(jìn)行管理,效率高,出錯率低,學(xué)生滿意度高。

學(xué)生教務(wù)子系統(tǒng)的實現(xiàn)主要是使用數(shù)據(jù)集組件TQuery。通過本章子系統(tǒng)的實現(xiàn),我們將學(xué)習(xí)對數(shù)據(jù)庫中的數(shù)據(jù)進(jìn)行維護(hù)的另一種方式,即通過數(shù)據(jù)集組件TQuery使用SQL語句來操作數(shù)據(jù)集當(dāng)中的數(shù)據(jù)。7.1.2系統(tǒng)設(shè)計

本章的學(xué)生教務(wù)子系統(tǒng)的功能模塊圖如圖7.1所示。

圖7.1學(xué)生教務(wù)子系統(tǒng)功能模塊圖

7.1.3數(shù)據(jù)庫設(shè)計及實現(xiàn)

學(xué)生教務(wù)子系統(tǒng)與教務(wù)管理子系統(tǒng)同屬于教學(xué)管理系統(tǒng),使用同一個數(shù)據(jù)庫,其設(shè)計與實現(xiàn)見第6章。

7.2相

關(guān)

7.2.1TQuery組件在SQL編程中的運用

在Delphi中是通過TQuery組件來實現(xiàn)對SQL語言支持的,也就是說用Delphi開發(fā)數(shù)據(jù)庫應(yīng)用程序時,使用SQL語言操作數(shù)據(jù)庫中的數(shù)據(jù)的途徑是通過TQuery組件。

TQuery組件在Delphi中占有非常重要的地位。

1.TQuery組件的使用

TQuery組件是一個數(shù)據(jù)集組件,它在Delphi組件面板的“BDE”標(biāo)簽頁上,該組件與TTable組件具有很多共同的特性,實現(xiàn)了Delphi對SQL語言的支持。在Delphi開發(fā)的數(shù)據(jù)庫應(yīng)用中,SQL語句是通過TQuery組件傳遞到要訪問的數(shù)據(jù)庫系統(tǒng)的數(shù)據(jù)庫引擎中,由數(shù)據(jù)庫引擎具體執(zhí)行SQL語句,以實現(xiàn)對數(shù)據(jù)的操作,而不是傳遞給Delphi中的BDE,由BDE實施具體的SQL動作。

TTable組件在訪問數(shù)據(jù)庫時已經(jīng)具備很強(qiáng)大的功能,而TQuery組件提供了一些TTable組件不具備的功能,它們是:

●多表聯(lián)接查詢;

●復(fù)雜的嵌套查詢;

●明確需要使用SQL語言進(jìn)行的操作。

TTable組件不能使用SQL語言,而TQuery組件可以使用SQL語言,因此TQuery組件也就具備了強(qiáng)大的關(guān)系查詢能力。

在Delphi應(yīng)用程序中編寫和使用的SQL語句有兩種,即靜態(tài)SQL語句和動態(tài)SQL語句。

靜態(tài)方式是在程序設(shè)計階段,把SQL命令文本作為TQuery組件的SQL屬性值進(jìn)行設(shè)置。靜態(tài)SQL語句在程序設(shè)計時便已固定下來,它不包含任何參數(shù)和變量。這樣,當(dāng)執(zhí)行應(yīng)用程序時,Delphi便執(zhí)行TQuery組件SQL屬性中設(shè)置的SQL命令。如果是SQL中的查詢命令,把TQuery組件通過TDataSource組件與數(shù)據(jù)控制組件相連,查詢的結(jié)果將會顯示在與TQuery組件相連接的數(shù)據(jù)瀏覽組件中。例如下面的語句便是一條靜態(tài)SQL語句:

Select*FromSCOREWherecourse='C003'

動態(tài)SQL語句也被稱作參數(shù)化的語句,即SQL語句中包含一些參數(shù)變量,在程序中可以動態(tài)地為這些參數(shù)賦值,在程序運行過程中,各個參數(shù)值是可變的。例如下面的語句便是一條動態(tài)SQL語句:

Select*FromSCOREWherecourse=:c

2.在TQuery組件中編寫簡單的SQL查詢命令示例

此處我們通過一個簡單的實例學(xué)習(xí)如何使用TQuery組件編寫簡單的SQL查詢命令,并在Delphi應(yīng)用程序中實現(xiàn)SQL查詢。

例如,如果我們想查詢出選修課程“C003”的全部學(xué)生的學(xué)號、課程號及成績,將結(jié)果顯示在表格中,可按下列步驟來實現(xiàn):

(1)在應(yīng)用程序的窗體中放置一個TQuery組件、一個TDataSource組件和一個TDBGrid組件,TDBGrid組件對象的DataSource屬性值為TDataSource組件對象名稱,TDataSource組件對象的DataSet屬性值為TQuery組件對象名稱。

(2)設(shè)置窗體TQuery組件對象Query1的DatabaseName屬性值為TEACH。

(3)雙擊ObjectInspector窗口中Query1的SQL屬性,將顯示StringListEditor窗口,在該窗口中輸入SQL語句:

select*fromscorewherecourse='C003'

然后單擊“OK”按鈕,關(guān)閉StringListEditor窗口。

(4)設(shè)置Query的Active屬性為True。

這樣在TDBGrid組件對象上馬上可以看見SQL語句查詢的結(jié)果。

7.2.2SQL語言編程概述

在Delphi應(yīng)用程序中的SQL命令語句包含在TQuery組件的SQL屬性中,TQuery組件的SQL屬性是TString類型的,也就是說SQL屬性值是一個字符串列表,這個字符串列表非常類似于一個字符串類型的數(shù)組。

1.SQL命令文本的編輯

1)使用StringListEditor編輯SQL命令文本

在程序設(shè)計過程中,可以通過對象查看器編輯SQL屬性。在ObjectInspector中雙擊SQL屬性,這樣會打開StringListEditor窗口,如圖7.2所示,在其中我們便可以編輯SQL命令。

圖7.2編輯SQL命令的StringListEditor窗口

2)在代碼中編輯SQL命令文本

可以在代碼中編輯SQL命令文本。在程序運行過程中,要想設(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命令語句。例如:

Query1.Close; //關(guān)閉Query1

Query1.SQL.Clear; //清除SQL屬性中的SQL命令文本

Query1.SQL.Add('Select*FromSCORE');

Query1.SQL.Add('WhereCOURSE=''C003'''); //添加SQL語句

注意在應(yīng)用程序中為SQL屬性設(shè)置新的SQL命令語句時,必須要調(diào)用Clear方法清除SQL屬性中現(xiàn)存的SQL命令語句;如果不調(diào)用Clear方法而直接調(diào)用Add方法向SQL屬性中設(shè)置SQL命令語句,那么新設(shè)置的SQL命令語句會追加在現(xiàn)存SQL命令語句的后面,在程序運行時常常會出現(xiàn)出乎意料的查詢結(jié)果甚至程序無法運行下去。

2.SQL命令的執(zhí)行

在為TQuery組件設(shè)置完SQL屬性的屬性值之后,即編寫好SQL命令之后,可用多種方式來執(zhí)行SQL命令。

在設(shè)計過程中,設(shè)置完TQuery組件的SQL屬性之后將其Active屬性值設(shè)置為True,

這樣便可以執(zhí)行SQL屬性中的SQL命令,如果應(yīng)用程序中有與TQuery組件相連的數(shù)據(jù)控制組件(如TDBGrid、TDBEdit等),那么在這些數(shù)據(jù)控制組件中會顯示SQL命令的執(zhí)行結(jié)果。

在應(yīng)用程序運行過程中,通過程序調(diào)用TQuery組件的Open方法或ExecSQL方法可以執(zhí)行其SQL屬性中的SQL命令。

Open方法和ExecSQL方法是不一樣的,在程序設(shè)計過程中一定要注意。Open方法只能用來執(zhí)行SQL語言的查詢語句(Select命令),并返回一個查詢結(jié)果集;而ExecSQL方法主要是用來執(zhí)行其他的SQL語句,如INSERT、UPDATE、DELETE等命令。例如:

Query1.Open;如果調(diào)用Open方法,而沒有查詢結(jié)果時,會出錯。此時應(yīng)該調(diào)用ExecSQL方法來代替Open方法:

Query1.ExecSQL;

當(dāng)然在設(shè)計應(yīng)用程序時,有時程序設(shè)計人員是無法確定TQuery組件中的SQL語句是否會返回一個查詢結(jié)果的。對于這種情況應(yīng)當(dāng)用Try…Except模塊來設(shè)計程序。在Try部分調(diào)用Open方法,而在Except部分調(diào)用ExceSQL方法,這樣才能保證程序的正確運行。

例如:

Try

Query1.Open;

Except

Query1.ExecSQL;

End;

3.通過TQuery組件獲得活動的數(shù)據(jù)

通過TTable組件從數(shù)據(jù)庫中獲得的數(shù)據(jù)都是活動的,也就是說用戶可以直接通過數(shù)據(jù)控制組件對這些數(shù)據(jù)進(jìn)行編輯修改。而通過TQuery組件可以獲得兩種類型的數(shù)據(jù):

1)“活動”的數(shù)據(jù)

這種數(shù)據(jù)就與通過TTable組件獲得的數(shù)據(jù)一樣,用戶可以通過數(shù)據(jù)控制組件來編輯修改這些數(shù)據(jù),并且當(dāng)調(diào)用Post方法或當(dāng)焦點離開當(dāng)前的數(shù)據(jù)控制組件時,用戶對數(shù)據(jù)的修改自動地被寫回到數(shù)據(jù)庫中。

2)非活動”的數(shù)據(jù)(只讀數(shù)據(jù))

對于“非活動”的數(shù)據(jù),用戶通過數(shù)據(jù)控制組件不能修改其中的數(shù)據(jù)。在缺省情況下,通過TQuery組件獲得的查詢結(jié)果數(shù)據(jù)是只讀數(shù)據(jù)即“非活動”的,要想獲得“活動”的數(shù)據(jù),在應(yīng)用程序中必須要設(shè)置TQuery組件的RequestLive屬性值為True,然而并不是在任何情況下如此設(shè)置都可以獲得“活動”的數(shù)據(jù)。要想獲得“活動”的數(shù)據(jù),除了將TQuery組件的RequestLive屬性設(shè)置為True外,還要能夠返回“活動”的數(shù)據(jù),相應(yīng)的SQL命令語句要滿足一定的約束條件。根據(jù)查詢的數(shù)據(jù)庫類型不同,約束條件也不相同,大致的約束條件如下:

(1)查詢只能涉及到一個單獨的表;

(2)SQL語句中不能包含ORDERBY命令;

(3)SQL語句中不能含有SUM、AVG等聚集運算符;

(4)在Select后的字段列表中不能有計算字段。

當(dāng)TQuery組件返回一個“活動”的查詢結(jié)果數(shù)據(jù)集時,它的CanModify屬性的值會被設(shè)置成True。

7.2.3動態(tài)SQL語句的使用

動態(tài)SQL語句又被稱為參數(shù)化的SQL語句,在其中包含著在程序過程中可以變化的參數(shù)。在實際的程序設(shè)計中使用得更多的是動態(tài)SQL語句。此處將重點介紹如何給動態(tài)SQL語句的參數(shù)賦值,以在應(yīng)用程序中靈活地使用SQL語句。動態(tài)SQL語句的編寫、執(zhí)行等與前面介紹的靜態(tài)SQL語句的編寫、執(zhí)行是相同的。

對于動態(tài)SQL語句中的參數(shù),我們可以通過兩種途徑來為它賦值。

1.使用參數(shù)編輯器(ParameterEditor)為參數(shù)賦值

具體方法是:選中TQuery組件,在對象查看器中雙擊Params屬性,便可以打開參數(shù)編輯器。

例如,在TQuery組件對象Query1的SQL屬性中設(shè)置如下的SQL語句:

Setect*FromSCOREWherecourse=:c;

Query1的DatabaseName屬性為TEACH。Query1的SQL語句中的c為參數(shù)變量。雙擊對象查看器中的Params屬性,打開參數(shù)編輯器,可看見其中所有的參數(shù)(本例中只有一個參數(shù)“0-c”),選擇參數(shù)c,對象查看器內(nèi)容如圖7.3所示。

圖7.3參數(shù)值的賦值方式之一

在對象查看器中,DateType組合框中選擇該參數(shù)的數(shù)據(jù)類型為字符型ftString,ParamType中選擇ptInput,在Value編輯框中可以為參數(shù)c賦值。這樣Query1的SQL查詢便準(zhǔn)備好了,參數(shù)值賦值給了動態(tài)SQL語句中相應(yīng)的參數(shù),此時當(dāng)把Query1的Active屬性設(shè)置成True,與Query1組件相連的數(shù)據(jù)控制組件中便會顯示出查詢結(jié)果。

通過參數(shù)編輯器為參數(shù)賦值,這種方式缺乏應(yīng)有的靈活性,在實際應(yīng)用中用得較少,在實際應(yīng)用中程序設(shè)計人員希望用更靈活方便的方式為參數(shù)賦值,這就是我們接下來要介紹的另一種途徑。

2.在程序中為參數(shù)賦值

在程序中為動態(tài)SQL語句的參數(shù)賦值有四種方法:

●根據(jù)參數(shù)在SQL語句中出現(xiàn)的順序,設(shè)置TQuery組件的Params屬性值為參數(shù)賦值。

●使用ParamValues屬性為各參數(shù)賦值。

●調(diào)用ParamByName方法為各參數(shù)賦值。

將TQuery組件的DataSource屬性設(shè)置為另一個數(shù)據(jù)源,這樣將另一個數(shù)據(jù)源中與當(dāng)前TQuery組件的SQL語句中的參數(shù)名相匹配的字段值賦給其對應(yīng)的參數(shù)。

1)使用Params屬性為參數(shù)賦值

TQuery組件有一個Params屬性,它們在設(shè)計期間不可用,在程序運行期間可用,并且是動態(tài)建立的。當(dāng)為TQuery組件編寫動態(tài)SQL語句時,Delphi會自動地建立一個數(shù)組Params,數(shù)組Params是從0下標(biāo)開始的,依次對應(yīng)動態(tài)SQL語句中的每個參數(shù),也就是說動態(tài)SQL語句中第一個參數(shù)對應(yīng)Params[0],第二個參數(shù)對應(yīng)Params[1],依此類推。

例如,有一個TQuery組件對象Query1,我們?yōu)樗帉懙膭討B(tài)SQL語句是:

InsertIntoSCORE(course,student,score)

Values(:cou,:stu,:score)

對于上述這條動態(tài)SQL語句中的參數(shù),我們可以利用Query1的Params屬性為參數(shù)賦值:

Query1.Params[0].AsString:='C003';

Query1.Params[1].AsString:='20060066';

Query1.Params[2].AsInteger:=90;

上述語句將把'C003'賦值給參數(shù):cou,'20060066'賦值給參數(shù):stu,90賦值給參數(shù):score。

2)使用Params的ParamValues屬性為參數(shù)賦值

TQuery組件有一個Params屬性是參數(shù)數(shù)組,它有一個ParamValues屬性,使用ParamValues['參數(shù)名']的形式可以直接引用到參數(shù)名指定的參數(shù)的值。使用這種方式是直接引用到參數(shù)的值,所以在使用該形式對參數(shù)進(jìn)行賦值時,不必使用AsString等類型轉(zhuǎn)換函數(shù)進(jìn)行類型轉(zhuǎn)換。使用這種方式時要知道參數(shù)的名字。

對于上面的例子,也可以使用下面的方式對參數(shù)賦值:

Query1.Params.ParamValues['cou']:='C003';

Query1.Params.ParamValues['stu']:='20060066';

Query1.Params.ParamValues['score']:=90;

3)使用ParamByName方法為參數(shù)賦值

ParamByName是一個函數(shù),以動態(tài)SQL語句中的參數(shù)名字作為調(diào)用ParamByName函數(shù)的實際參數(shù),這樣便可以為它們賦值。使用這種賦值方法,必須要知道動態(tài)SQL語句參數(shù)的名字。

例如在上面的例子中,也可以用下述方法給參數(shù)賦值:

Query1.ParamByName('cou').AsString:='C003';

Query1.ParamByName('stu').AsString:='20060066';

Query1.ParamByName('score').AsInteger:=90;注意使用上述第1)種和第3)種方式對參數(shù)進(jìn)行賦值時,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ù)賦值

上述三種方法的共同特點是:在為各參數(shù)賦值時,我們是知道各參數(shù)對應(yīng)的具體參數(shù)值的。而在具體的應(yīng)用程序中,有些參數(shù)的值常常是無法確定的。例如參數(shù)的值來自于另一個查詢結(jié)果,對于這種情況,Delphi提供了使用DataSource屬性為動態(tài)SQL語句中的參數(shù)賦值。當(dāng)SQL語句中尚存在沒有賦值的參數(shù)時,Delphi會自動檢查TQuery組件的DataSource屬性,如果為DataSource屬性設(shè)置了屬性值(該屬性的值是另一個TDataSource組件對象的名字),Delphi會把沒有賦值的參數(shù)與TDataSource組件對象對應(yīng)的數(shù)據(jù)集中的各字段進(jìn)行比較,Delphi會將同名的字段的值賦值給該參數(shù)。這種方法主要是實現(xiàn)主細(xì)表數(shù)據(jù)庫應(yīng)用,與我們在學(xué)習(xí)使用TTable組件時曾創(chuàng)建主要——明細(xì)型數(shù)據(jù)庫應(yīng)用是相似的。

例如,在如圖7.4所示的應(yīng)用中,在左側(cè)表格中選定了某門課程,右側(cè)表格中相應(yīng)地顯示該門課程的所有成績,注意右側(cè)表格內(nèi)容跟隨左側(cè)表格中所選定的課程而變化。窗體中放置了如表7-1所示的組件對象。

圖7.4TQuery主細(xì)表應(yīng)用

表7-1TQuery主細(xì)表應(yīng)用的主要組件對象及屬性表

在窗體的OnCreate事件中加入如下代碼:

procedureTForm1.FormCreate(Sender:TObject);

begin

database1.Open;

table1.Open;

query1.Open;

end;

Query1中的動態(tài)SQL語句中的參數(shù):id,在設(shè)計期間中沒有給它賦值,代碼中也沒有對其賦值。當(dāng)該應(yīng)用程序運行時Delphi會自動地到其Datasource屬性中說明的數(shù)據(jù)源datasource1對應(yīng)數(shù)據(jù)集table1中查找與參數(shù):id匹配的字段,而table1中正好有一個名字為

id的字段與參數(shù):id相匹配。

這樣table1數(shù)據(jù)集中當(dāng)前記錄的id字段值賦值給了參數(shù):id,

每當(dāng)移動table1數(shù)據(jù)集中的記錄指針時,參數(shù):id的值會隨之改變,而參數(shù):id的值發(fā)生改變時,query1中的動態(tài)SQL語句會根據(jù)新的參數(shù)值重新查詢,從數(shù)據(jù)庫表中獲取相應(yīng)的成績數(shù)據(jù),這樣也就實現(xiàn)了主要-明細(xì)型應(yīng)用。

7.3實

現(xiàn)

7.3.1教務(wù)管理子系統(tǒng)功能模塊的創(chuàng)建

在Delphi7中創(chuàng)建一個新的工程,工程名為“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)有兩部分功能:選修課程信息添加、刪除和成績查詢、統(tǒng)計。同樣,使用PageControl組件的兩個TabSheet來實現(xiàn)這兩部分功能。

1)學(xué)生選修課程記錄的添加與刪除

該界面的功能是進(jìn)行學(xué)生選修課程的信息維護(hù),包括選課信息的添加和刪除,若要修改則應(yīng)該先刪除再添加。左側(cè)DBGrid組件對象顯示學(xué)生未選修的課程具體信息,右側(cè)DBGrid組件對象顯示學(xué)生已經(jīng)選修的課程信息。在左側(cè)表格中選定課程,雙擊課程或點擊“加入”按鈕將添加該學(xué)生選修該課程的信息至SCORE表。在右側(cè)表格中選定課程,雙擊課程或點擊“刪除”按鈕將從SCORE表中刪除該學(xué)生選修該課程的記錄??倢W(xué)分要隨加入或刪除課程而動態(tài)變化,數(shù)據(jù)表格的內(nèi)容也要隨加入或刪除課程而動態(tài)變化。

圖7.6學(xué)生選課管理

表7-2學(xué)生選課管理界面主要組件對象及屬性表

關(guān)閉該窗體將中止整個應(yīng)用程序的運行。

procedureTf_stu.FormClose(Sender:TObject;varAction:TCloseAction);

begin

application.Terminate;

end;在窗體的標(biāo)題上顯示登錄該應(yīng)用程序的學(xué)生姓名,在該窗體創(chuàng)建或顯示時執(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é)生選課”頁顯示時,左側(cè)數(shù)據(jù)表格要顯示學(xué)生尚未選修的全部課程具體信息,右側(cè)數(shù)據(jù)表格中顯示學(xué)生已經(jīng)選修的全部課程信息,在總學(xué)分處顯示該學(xué)生已經(jīng)選修的全部課程的學(xué)分總和。這里分別使用了三個TQuery組件對象來實現(xiàn)。注意,此處總學(xué)分的計算要求總和,如果使用TTable組件,求總和要在程序中遍歷全部數(shù)據(jù)并求和,很麻煩,而使用SQL語句則直接使用統(tǒng)計函數(shù)求和即可。學(xué)生選修全部課程信息有課程編號和課程名稱,涉及到SCORE和COURSE兩個數(shù)據(jù)表中的數(shù)據(jù),使用TTable實現(xiàn)比較麻煩,使用SQL語句進(jìn)行這樣的查詢是很容易實現(xiàn)的。而在左側(cè)數(shù)據(jù)表格中顯示學(xué)生尚未選修的全部課程具體信息,要從COURSE表中去掉已經(jīng)選修的課程,然后顯示這些課程的信息,使用SQL語句進(jìn)行這樣的查詢都比較復(fù)雜,更不會使用TTable來實現(xiàn),故三處的數(shù)據(jù)都來自TQuery數(shù)據(jù)集。我們看到此處TabSheet1的OnShow事件代碼非常簡單,因為大部分工作是在前面設(shè)置TQuery組件對象的SQL屬性時完成的。注意查看前面屬性表格中TQuery組件對象的SQL屬性值。注意,由于登錄應(yīng)用程序的學(xué)生不同,SQL的內(nèi)容也會不同,所以三個TQuery組件對象的SQL屬性值中都使用了參數(shù),并在程序中動態(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;點擊“加入”按鈕時,使用insertinto語句實現(xiàn)數(shù)據(jù)的添加。該處并沒有使用一個預(yù)先定義好SQL屬性值的TQuery組件對象,而是在程序中使用SQL屬性的Clear、Add等方法動態(tài)地設(shè)置SQL屬性值,這樣做是由于此處的添加與后面的刪除共用了一個TQuery組件對象。

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['課程編號']+''')');

q_adddel.ExecSQL;

TabSheet1Show(nil);

end;雙擊DBGrid1組件對象中的行時,也會將該課程的選修信息添加至SCORE表,也就是相當(dāng)于點擊了“加入”按鈕。故在DBGrid1的OnDblClick事件中調(diào)用Button1的OnClick事件代碼:

procedureTf_stu.DBGrid1DblClick(Sender:TObject);

begin

Button1Click(nil);

end;點擊“刪除”按鈕時,使用deletefrom語句實現(xiàn)數(shù)據(jù)的刪除。該處同樣是在程序中動態(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組件對象中的行時,同樣相當(dāng)于點擊了“刪除”按鈕。

procedureTf_stu.DBGrid2DblClick(Sender:TObject);

begin

Button2Click(nil);

end;

2)學(xué)生成績查詢與成績統(tǒng)計

本界面的功能是查詢學(xué)生的某門課程的成績,并對該門課程做簡單的統(tǒng)計。用一個DBGrid組件對象給出登錄該應(yīng)用程序的學(xué)生所選修并有成績的所有課程信息,提供給學(xué)生選擇查詢成績的課程。當(dāng)選定數(shù)據(jù)表格中的一行時,在界面的右側(cè)給出該學(xué)生該課程的成績,以及選修這門課程的全部學(xué)生的成績的平均值、最高值和最低值。

界面布局如圖7.7所示,其主要組件及屬性見表7-3。

圖7.7成績查詢

表7-3成績查詢界面主要組件對象及屬性表

“成績查詢”頁顯示時,DBGrid3對象中要顯示學(xué)生選修并有成績的課程信息,右側(cè)顯示第一條記錄的課程成績信息。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;點擊DBGrid3的單元格時,表示要顯示該行對應(yīng)的課程的該學(xué)生成績、課程的平均成績、最高成績和最低成績。平均成績、最高成績和最低成績分別使用了三個TQuery組件對象,這些TQuery組件對象均使用課程編號作為參數(shù),此處要將選定的課程編號賦值給參數(shù),以下分別使用三種方式引用參數(shù)值。DBGrid3的OnCellClick事件代碼如下:

procedureTf_stu.DBGrid3CellClick(Column:TColumn);

begin

q_avg.Close;

q_avg.Params.ParamValues['c']:=q_course_learned['課程編號'];

q_avg.Open;

q_max.Close;

q_max.Params[0].AsString:=q_course_learned['課程編號'];

q_max.Open;

q_min.Close;

q_min.Params.ParamByName('c').AsString:=q_course_learned['課程編號'];

q_min.Open;

end;本系統(tǒng)的代碼量不大,是因為大量使用了TQuery組件。TQuery組件能夠很方便地對多個數(shù)據(jù)表進(jìn)行操作,并且能夠使用統(tǒng)計函數(shù)對數(shù)據(jù)進(jìn)行統(tǒng)計,在這樣的情況下,我們首選TQuery組件而非TTable組件。

圖7.8用戶登錄窗體

7.3.2系統(tǒng)的實現(xiàn)

程序運行時,同樣會先顯示用戶登錄窗體,如圖7.8所示。

輸入用戶名和密碼后,單擊“登錄”按鈕,在此將驗證用戶名、密碼和權(quán)限是否正確,若其中任一處驗證失敗,將分別給出錯誤提示信息。驗證通過,將顯示主要功能窗體,如圖7.9所示。

圖7.9選修課程信息維護(hù)

在窗體的標(biāo)題

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。