作者簡(jiǎn)介:
龍瓊芳(1982年2月),女,漢族,湖南攸縣人,現(xiàn)任教于廣東省東莞市經(jīng)濟(jì)貿(mào)易學(xué)校計(jì)算機(jī)科組,講師,碩士學(xué)位,研究方向:軟件工程。
摘要:針對(duì)SQL(結(jié)構(gòu)化查詢(xún)語(yǔ)言)課程操作考試的組卷和閱卷中的實(shí)際問(wèn)題,對(duì)VB訪問(wèn)SQL Server 2000 數(shù)據(jù)庫(kù)使用的ADO技術(shù)進(jìn)行了闡述,論述采用VB結(jié)合SQL Server 2000實(shí)現(xiàn)SQL考試隨機(jī)組卷改卷系統(tǒng)設(shè)計(jì)的依據(jù)和實(shí)現(xiàn)方法,并給出了系統(tǒng)開(kāi)發(fā)過(guò)程中所需的一些關(guān)鍵技術(shù)的程序代碼。
關(guān)鍵詞:ADO VB SQL 隨機(jī)組卷 自動(dòng)閱卷
中圖分類(lèi)號(hào):G712文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1672-3791(2012)01(a)-0000-00
1 問(wèn)題的提出
SQL是結(jié)構(gòu)化查詢(xún)語(yǔ)言的簡(jiǎn)稱(chēng),課程目標(biāo)是要求學(xué)生掌握在SQL Server 2000中編寫(xiě)查詢(xún)的能力,在教學(xué)過(guò)程中每次課每個(gè)學(xué)生都需要完成大量的練習(xí),由于每一個(gè)查詢(xún)都是一個(gè)獨(dú)立的“.sql”文件,因此如果采用人工檢查的方式不但工作量大而且容易出錯(cuò)。而使用計(jì)算機(jī)輔助改題不但速度快而且效率高。
此外,為了避免考試的時(shí)候相鄰學(xué)生互相抄襲、減少考生作弊的情況,用計(jì)算機(jī)生成試卷也利實(shí)行隨機(jī)組卷。
2 設(shè)計(jì)思想、關(guān)鍵技術(shù)和關(guān)鍵問(wèn)題
SQL課程練習(xí)和考試都在SQL Server 2000 下完成,每一個(gè)小題都是一個(gè)獨(dú)立的“.sql”文件。因此改卷的過(guò)程就是驗(yàn)證每一個(gè)“.sql”文件在SQL Server 2000環(huán)境下執(zhí)行的結(jié)果是否正確的過(guò)程。SQL練習(xí)和考試的題目都是一個(gè)個(gè)獨(dú)立的查詢(xún)要求,例如:請(qǐng)查詢(xún)“學(xué)生課程”數(shù)據(jù)庫(kù)中姓“何”或“蘇”的教師且學(xué)時(shí)數(shù)大于70的教師名和學(xué)時(shí)數(shù)。因此出卷的過(guò)程就是將一組難度分布合理的查詢(xún)題目列出來(lái)。為了能夠單獨(dú)使用組卷和改卷兩個(gè)模塊,例如平時(shí)練習(xí)時(shí)題目是固定的只需要使用改卷部分,這兩個(gè)模塊并不整合在一起而是獨(dú)立開(kāi)來(lái)的。
系統(tǒng)包括試題數(shù)據(jù)庫(kù)、題庫(kù)數(shù)據(jù)庫(kù)、改卷程序、組卷程序,其中,試題數(shù)據(jù)庫(kù)是指題目本身進(jìn)行查詢(xún)或修改操作的數(shù)據(jù)庫(kù),題庫(kù)數(shù)據(jù)庫(kù)是存放所有試題的數(shù)據(jù)庫(kù),改卷程序和組卷程序均由Visual Basic 6.0編寫(xiě),標(biāo)準(zhǔn)答案和學(xué)生答案均為一組“.sql”文件,生成的試卷可以選擇文本文檔或者word文檔。
2.1 Visual Basic訪問(wèn)SQL Server數(shù)據(jù)庫(kù)技術(shù)
使用Visual Basic作為前端開(kāi)發(fā)語(yǔ)言,與SQL Server接口有幾種常用的方法,即:數(shù)據(jù)訪問(wèn)對(duì)象/Jet、為ODBC API編程、使用SQL Server的Visual Basic庫(kù)(VBSQL)為DB庫(kù)的API編程、ADO 數(shù)據(jù)對(duì)象(Active Data Objects)。以上幾種訪問(wèn)SQL Server的方法各有各的特點(diǎn)。DAOs方法是基于對(duì)象的,因而便于使用,但是它是從Visual Basic到SQL Server最慢的連接方式。ODBC API和VBSQL方法從本質(zhì)上講是基于程序的。ODBC API方法通用性好,允許最強(qiáng)的互操作性,編程簡(jiǎn)單,但速度慢于VBSQL方法。VBSQL方法通過(guò)VBSQL控件,提供了重要的SQL Server前端應(yīng)用程序所需的靈活性、強(qiáng)大功能和良好性能。它具有真正的事件驅(qū)動(dòng)及錯(cuò)誤處理能力,完全支持異步處理、游標(biāo)和計(jì)算列等。這些都是VBSQL方法超出其它方法的優(yōu)勢(shì),但其編程稍復(fù)雜。
2.2 ADO技術(shù)
ADO向我們提供了一個(gè)熟悉的,高層的對(duì)OLE DB的Automation封裝接口。對(duì)那些熟悉RDO的程序員來(lái)說(shuō),你可以把OLE DB比作是ODBC驅(qū)動(dòng)程序。如同RDO對(duì)象是ODBC驅(qū)動(dòng)程序接口一樣,ADO對(duì)象是OLE DB的接口;如同不同的數(shù)據(jù)庫(kù)系統(tǒng)需要它們自己的ODBC驅(qū)動(dòng)程序一樣,不同的數(shù)據(jù)源要求它們自己的OLE DB提供者(OLE DB provider)。
ADO向VB程序員提供了很多好處。包括易于使用,熟悉的界面,高速度以及較低的內(nèi)存占用。同傳統(tǒng)的數(shù)據(jù)對(duì)象層次(DAO和RDO)不同,ADO可以獨(dú)立創(chuàng)建。因此你可以只創(chuàng)建一個(gè)”Connection”對(duì)象,但是可以有多個(gè)、獨(dú)立的”Recordset”對(duì)象來(lái)使用它。
2.3 改卷的依據(jù)
檢驗(yàn)學(xué)生答案是否正確有兩種方法:
②判定過(guò)程
判定過(guò)程即分析學(xué)生的“.sql”文件是否正確。例如:請(qǐng)查詢(xún)“學(xué)生課程”數(shù)據(jù)庫(kù)中姓“何”或“蘇”的教師且學(xué)時(shí)數(shù)大于70的教師名和學(xué)時(shí)數(shù)。
標(biāo)準(zhǔn)的答案應(yīng)該為:
use 學(xué)生課程
select 教師名,學(xué)時(shí)數(shù)
from 授課表
where (教師名 like ‘何%’or 教師名 like ‘蘇%’)and(學(xué)時(shí)數(shù)>70)
go
如果學(xué)生的答案與標(biāo)準(zhǔn)答案一致則判定該題得分。方法是讀取學(xué)生的“.sql”文件和標(biāo)準(zhǔn)答案的“.sql”文件,進(jìn)行比對(duì)。這種方法的優(yōu)點(diǎn)在于實(shí)現(xiàn)簡(jiǎn)單,執(zhí)行的效率高,改題速度快,但是也有一些缺點(diǎn)。
A.比對(duì)的過(guò)程中有些字符甚至語(yǔ)句是結(jié)果無(wú)關(guān)的。例如這里的“use 學(xué)生課程”,在實(shí)際做題時(shí)本條語(yǔ)句若缺不影響查詢(xún)。因此對(duì)比前應(yīng)先把學(xué)生答案和標(biāo)準(zhǔn)答案中這些結(jié)果無(wú)關(guān)的語(yǔ)句刪除。再如學(xué)生若在“from”和“授課表”中間插入了若干空格,由于這些空格不影響語(yǔ)句的執(zhí)行,因此對(duì)比前應(yīng)也先把學(xué)生答案和標(biāo)準(zhǔn)答案中這些空格刪除。但是如果學(xué)生答案是“fr om”,在“fr”和“om”中間插入了若干空格則應(yīng)視為錯(cuò)誤答案,因?yàn)檫@在查詢(xún)中將影響查詢(xún)的結(jié)果。因此像這樣位置不同時(shí)有可能結(jié)果無(wú)關(guān)也可能結(jié)果相關(guān)的字符在實(shí)際處理起來(lái)比較困難。這種情況一般是學(xué)生的誤操作導(dǎo)致,學(xué)生只要在做題之后執(zhí)行查詢(xún)檢查一下就能發(fā)現(xiàn),因此這種情況發(fā)生的概率非常小,不過(guò)仍有可能。
B.有些查詢(xún)可能有多種方法實(shí)現(xiàn),例如上面的查詢(xún)也可以編寫(xiě)查詢(xún)?nèi)缦?/p>
use 學(xué)生課程
select 教師名,學(xué)時(shí)數(shù)
from 授課表
where (教師名 like ‘何%’ and 學(xué)時(shí)數(shù)>70)or (教師名 like ‘蘇%’ and 學(xué)時(shí)數(shù)>70)
go
加下劃線的部分有了較大的改變,但實(shí)際與where (教師名 like ‘何%’or 教師名 like ‘蘇%’)and(學(xué)時(shí)數(shù)>70)是一樣的。這樣有多種方法實(shí)現(xiàn)的查詢(xún)?cè)诰毩?xí)和考試中非常多。
因此,使用判定過(guò)程的方法有可能導(dǎo)致判斷錯(cuò)誤。原因A導(dǎo)致原本錯(cuò)誤的答案判為正確,而原因B導(dǎo)致原本正確的答案判為錯(cuò)誤。
② 判定結(jié)果
判定結(jié)果與判定過(guò)程正好相反,不關(guān)心學(xué)生是如何編寫(xiě)“.sql”文件的,而是執(zhí)行“.sql”文件然后判斷結(jié)果是否與標(biāo)準(zhǔn)答案的執(zhí)行結(jié)果相同。
這種方法可以避免上述的原因A和原因B所導(dǎo)致的錯(cuò)誤判斷,是比較理想的判斷方法。只要仔細(xì)的設(shè)置試題數(shù)據(jù)庫(kù)中的記錄和數(shù)據(jù)就能使得不同的查詢(xún)具有不同的結(jié)果記錄集合,因而可以避免不同的查詢(xún)結(jié)果相同,也就不會(huì)出現(xiàn)錯(cuò)判的現(xiàn)象。
但是這種方法也有缺點(diǎn),由于要對(duì)比學(xué)生答案的執(zhí)行結(jié)果和標(biāo)準(zhǔn)答案的執(zhí)行結(jié)果,就必須至少訪問(wèn)試題數(shù)據(jù)庫(kù)兩次,這樣改卷的速度必然會(huì)慢很多。
綜合分析以上兩種判定方法的優(yōu)缺點(diǎn),可以設(shè)定先用判定過(guò)程比對(duì)兩個(gè)答案,若比對(duì)結(jié)果不相同再進(jìn)行結(jié)果判定。這樣既兼顧了改卷的速度又可較大限度的避免錯(cuò)判。
2.4 試題的設(shè)置
根據(jù)考試和改卷的需要,試題的設(shè)置需要遵循以下原則:
2.4.1 難易結(jié)合,涵蓋所有知識(shí)點(diǎn)
對(duì)試題根據(jù)考查的知識(shí)點(diǎn)和難易程度進(jìn)行分類(lèi),隨機(jī)抽題時(shí)依據(jù)這種分類(lèi)進(jìn)行組卷,使得得到的試卷能夠覆蓋大部分知識(shí)點(diǎn)并可以兼顧難易不同程度的比例。這樣可以避免不同學(xué)生抽取的試卷難度不一、考查知識(shí)點(diǎn)較偏等問(wèn)題,使得生成的試卷真正反映學(xué)生的實(shí)際掌握情況。
2.4.2 試題之間沒(méi)有交叉干擾
前面的試題不能影響后續(xù)試題的完成結(jié)果。例如,如果有試題要更新學(xué)號(hào)為“200009001”的學(xué)生記錄,則之前不能有刪除查詢(xún)刪除該記錄,也不能有更新查詢(xún)修改該學(xué)生的學(xué)號(hào)。
因此正確安排題目的順序非常重要,也可以在題庫(kù)數(shù)據(jù)庫(kù)中設(shè)置一字段使得某些題目不能同時(shí)被抽中。
因此在隨機(jī)抽題組成的一份試卷中,選擇查詢(xún)的試題要在前,動(dòng)作查詢(xún)的試題應(yīng)放在選擇查詢(xún)后,且所有的動(dòng)作查詢(xún)?cè)囶}所操作的記錄均不能相同。
2.4.3 所有查詢(xún)結(jié)果集合要包括特征記錄和邊緣記錄
采用判定結(jié)果方法驗(yàn)證答案的時(shí)候,如果試題數(shù)據(jù)庫(kù)中的記錄數(shù)量不夠、或者沒(méi)有特征記錄、或者沒(méi)有邊緣記錄、或者這些記錄不完整,都會(huì)導(dǎo)致判斷錯(cuò)誤。
查詢(xún)得到的是一個(gè)記錄集合,在這個(gè)記錄集合中,有些記錄位于集合中間被稱(chēng)為特征記錄,有些位于集合邊緣被稱(chēng)為邊緣記錄。特征記錄反映了這個(gè)查詢(xún)的一般性,而邊緣記錄反映了這個(gè)查詢(xún)的特殊性。
例如:1、查找成績(jī)小于等于80的學(xué)生記錄。在結(jié)果集合中成績(jī)?yōu)?0的記錄就是一個(gè)特征記錄;而成績(jī)?yōu)?0的就是這個(gè)查詢(xún)的邊緣記錄。
再如:2、查找成績(jī)大于60的學(xué)生記錄。在結(jié)果集合中成績(jī)?yōu)?0的記錄就是一個(gè)特征記錄;而成績(jī)?yōu)?0的記錄雖然不在結(jié)果集合中,但位于集合的邊緣,它也是一個(gè)邊緣記錄。
在以上兩個(gè)例子中:如果例1的試題數(shù)據(jù)庫(kù)中沒(méi)有成績(jī)?yōu)?0的記錄,則如果學(xué)生的實(shí)際查詢(xún)?yōu)椤安檎页煽?jī)小于80的學(xué)生記錄”所得到的結(jié)果集合將與預(yù)期的結(jié)果集合相同。如果例2的試題數(shù)據(jù)庫(kù)中沒(méi)有成績(jī)?yōu)?0的記錄,一旦學(xué)生的實(shí)際查詢(xún)?yōu)椤安檎页煽?jī)大于等于60的學(xué)生記錄” 所得到的結(jié)果集合也會(huì)與預(yù)期的結(jié)果集合相同。這樣就會(huì)產(chǎn)生誤判。
因此,在設(shè)計(jì)試題數(shù)據(jù)庫(kù)的時(shí)候,一定要分析試題本身,找出所有的邊緣特征記錄和一定數(shù)量的特征記錄。試題數(shù)據(jù)庫(kù)必須涵蓋這些記錄,采用結(jié)果判定才不會(huì)出現(xiàn)錯(cuò)判的情況。
3 隨機(jī)組卷程序的設(shè)計(jì)和實(shí)現(xiàn)
組卷程序重點(diǎn)包括連接題庫(kù)數(shù)據(jù)庫(kù),抽取試題,最后斷開(kāi)題庫(kù)數(shù)據(jù)庫(kù)等操作。
3.1 連接題庫(kù)數(shù)據(jù)庫(kù)的代碼
(其中Text1.Text為題庫(kù)數(shù)據(jù)庫(kù)所在服務(wù)器名或IP)
‘創(chuàng)建對(duì)象
Dim objcn As Connection
Dim objcom As Command
Dim objrs As Recordset
‘實(shí)例化對(duì)象
Set objcn = New Connection
Set objcom = New Command
Set objrs = New Recordset
‘創(chuàng)建數(shù)據(jù)庫(kù)連接
objcn.Provider = “SQLOLEDB”
objcn.ConnectionString = “User ID=sa;PWD=;Data Source=” + Text1.Text + “;Initial Catalog=SQL期末考試試題”
RichTextBox1.Text = “SQL期末考試試題” vbCrLf
3.2 斷開(kāi)題庫(kù)數(shù)據(jù)庫(kù)的代碼
‘?dāng)嚅_(kāi)連接
objcn.Close
‘釋放連接
Set objcn = Nothing
3.3抽取試題的代碼如下:(以生成第一大題的代碼為例)
‘生成第一大題
For i = 1 To 12
Label1: Randomize ‘ 對(duì)隨機(jī)數(shù)生成器做初始化的動(dòng)作。
MyValue = Int((102 * Rnd) + 1001) ‘ 生成 1001 到 1102 之間的隨機(jī)數(shù)值。
For j = 1 To i – 1
If one(j) = MyValue Then
GoTo Label1:
End If
Next j
one(i) = MyValue
Next i
4 改卷程序的設(shè)計(jì)和實(shí)現(xiàn)
改卷程序依次讀取學(xué)生的.sql文件,全部讀取并改卷后退出。
4.1 讀取學(xué)生文件和初始化學(xué)生文件代碼如下:
‘讀取學(xué)生文件
Open Dir1.Path “\” title For Input As #1
Do While Not EOF(1)
Line Input #1, s_add
‘將大寫(xiě)字母轉(zhuǎn)換為小寫(xiě)字母
s_add = LCase(s_add)
‘去除go
s_add = Replace(s_add, “go”, “”)
s_stu_show = s_stu_show + s_add + Chr(13) + Chr(10)
‘去除空格
s_add = Replace(s_add, “ “, “”)
‘去除引號(hào)
s_add = Replace(s_add, “’”, “”)
‘去除回車(chē)
‘s_add = Replace(s_add, “’”, “”)
If pos = InStr(1, s_add, “/*”) < 0 Then
‘獲取文檔內(nèi)容
s_stu = s_stu + s_add
End If
Loop
Close #1
4.2 判斷結(jié)果集合是否相同代碼如下:
'分別執(zhí)行兩個(gè)語(yǔ)句,判斷結(jié)果是否相同
temp = \"Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=\" + temp + \";Data Source=\" + Text4.Text
Adodc1.ConnectionString = temp
Adodc2.ConnectionString = temp
Adodc1.Enabled = True
Adodc1.Enabled = True
Adodc1.RecordSource = s_stu_show
Adodc2.RecordSource = s_ansr_show
Adodc1.Refresh
On Error GoTo tag2:
Adodc2.Refresh
5 總結(jié)和展望
在期中考試和期末考試以及部分平時(shí)練習(xí)中使用了這個(gè)組卷改卷系統(tǒng),運(yùn)行良好,無(wú)故障,改卷的效率也有很大的提高,基本達(dá)到了最初的目的。但由于時(shí)間倉(cāng)促,本系統(tǒng)有很多有待改進(jìn)的地方,主要總結(jié)如下:
1、系統(tǒng)的安全性較差。在程序中實(shí)現(xiàn)了拒絕學(xué)生重復(fù)抽題的代碼,這在一定程度上避免了學(xué)生人為選題的操作,有一定的安全考慮。并且考試的時(shí)候題庫(kù)數(shù)據(jù)庫(kù)位于教師機(jī)上,抽題領(lǐng)卷在學(xué)生機(jī)器上,但是由于數(shù)據(jù)庫(kù)所在的一端并沒(méi)有編寫(xiě)服務(wù)器代碼,學(xué)生通過(guò)領(lǐng)卷程序直接訪問(wèn)教師機(jī)上的題庫(kù)數(shù)據(jù)庫(kù),造成了數(shù)據(jù)的安全性較差。若將題庫(kù)數(shù)據(jù)庫(kù)、領(lǐng)卷程序、服務(wù)程序分置三臺(tái)機(jī)器上則可大大提高安全性能。同時(shí)也可避免一部分較聰明的學(xué)生直接訪問(wèn)題庫(kù)數(shù)據(jù)庫(kù)的可能。
2、系統(tǒng)的應(yīng)用范圍較窄。本系統(tǒng)是針對(duì)SQL一門(mén)課程設(shè)計(jì)和編寫(xiě)的,因此講授完本門(mén)課程后該系統(tǒng)很難修改應(yīng)用到其它課程的組卷和改卷中來(lái)。且一旦試題改動(dòng)了,試題數(shù)據(jù)庫(kù)也要隨之改動(dòng)(原因見(jiàn)二.4.③),使得擴(kuò)充試題比較難。如果能夠找到一種方法自動(dòng)尋找邊緣記錄,則擴(kuò)充試題后可自動(dòng)調(diào)整試題數(shù)據(jù)庫(kù),則應(yīng)用的范圍將大大擴(kuò)展。
參考文獻(xiàn)
[1] 宋琦凡,付敬平.《使用Visual Basic開(kāi)發(fā)數(shù)據(jù)庫(kù)應(yīng)用軟件》.北京:電子工業(yè)出版社
[2] Evangelos Petroutsos. 《Visual Basic從入門(mén)到精通》.北京:電子工業(yè)出版社
[3] 孟小峰.《開(kāi)放數(shù)據(jù)庫(kù)互連—ODBC 2.0使用大全》.北京:清華大學(xué)出版社
[4] 廖衛(wèi)東,趙軍.《Visual Basic編程手冊(cè)》.北京:機(jī)械工業(yè)出版社
[5] 《電腦編程技巧與維護(hù)》