文章源代碼: msaccess_sp2.zip 介紹 歡迎來(lái)到ms access存儲(chǔ)過(guò)程的第二部分討論。第一部分詳細(xì)地描述了如何使用ado.net和visual basic.net在access中創(chuàng)建存儲(chǔ)過(guò)程. 第二部分將會(huì)示范如何通過(guò)數(shù)據(jù)庫(kù)訪問(wèn)層訪問(wèn)在第一部分已經(jīng)創(chuàng)建的存儲(chǔ)過(guò)程,你可以模仿它并且用在自己的應(yīng)用程序里。這篇文章會(huì)詳細(xì)地描述如何使用visual basic.net實(shí)現(xiàn)數(shù)據(jù)庫(kù)的訪問(wèn)層。 數(shù)據(jù)庫(kù)層的主要目的是通過(guò)類模塊提供一個(gè)訪問(wèn)數(shù)據(jù)庫(kù)的網(wǎng)關(guān)。這個(gè)類模塊將充當(dāng)數(shù)據(jù)庫(kù)和應(yīng)用程序之間的粘合劑。利用數(shù)據(jù)庫(kù)訪問(wèn)層來(lái)訪問(wèn)數(shù)據(jù)庫(kù)有2個(gè)優(yōu)點(diǎn):你可以有改變你的后臺(tái)數(shù)據(jù)庫(kù)技術(shù)(從access改到sql server)而不影響應(yīng)用系統(tǒng)的能力。你還能夠通過(guò)在應(yīng)用程序和數(shù)據(jù)庫(kù)訪問(wèn)層之間增加一個(gè)控制層,來(lái)保證傳過(guò)去的數(shù)據(jù)是“純凈”的。在.net里,數(shù)據(jù)庫(kù)訪問(wèn)層通常會(huì)包括一個(gè)遵循面向?qū)ο笠?guī)范的類模塊,而visual basic 的較早的版本會(huì)使用一個(gè)標(biāo)準(zhǔn)模塊來(lái)處理。 數(shù)據(jù)庫(kù)訪問(wèn)層 - 代碼 現(xiàn)在該是我們卷起袖子來(lái)看一些代碼的時(shí)候了。在添加一個(gè)空類以后的第一件事情,就是列出這里需要使用的.net類庫(kù),如下所示: imports system imports system.data imports system.data.oledb system 庫(kù) 對(duì)大多數(shù)程序來(lái)說(shuō)是標(biāo)準(zhǔn)的, 但是我把它作為一個(gè)習(xí)慣,在所有的代碼中都包含這個(gè)類庫(kù)。而system.data 庫(kù)則是一個(gè)對(duì)于大多數(shù)數(shù)據(jù)庫(kù)訪問(wèn)程序都需要的庫(kù)。system.data.oledb 將用在訪問(wèn)access所需要的ole db provider。如果我們需要使用sql server,則我們最好使用定制的sql provider system.data.sqlclient. 下一行開(kāi)始了類的定義 public class dbtier 這里我們定義類名為 dbtier, 并且給他public 修飾符, 因此它將可以被其他代碼模塊訪問(wèn)。在類定義以后,將聲明所有要用到的屬性。 shared connectionstring as string = _ "provider=microsoft.jet.oledb.4.0;data source=c:/program " _ & "files/microsoft office/office10/samples/northwind.mdb" 這里只聲明了一個(gè)string屬性,connectionstring. 這個(gè)變量保存了 northwind access數(shù)據(jù)庫(kù)的連接字符串。聲明這個(gè)變量為shared,說(shuō)明它是一個(gè)“類變量(class variable)”,一個(gè)class variable是和類關(guān)聯(lián)的,二不是和這個(gè)類產(chǎn)生的每個(gè)對(duì)象相關(guān)聯(lián)。(譯者:vb.net的shared 修飾符相當(dāng)于c++或c#的static修飾符) 在連接字符串的定義之后,你可以看到這里有3個(gè)過(guò)程和1個(gè)函數(shù)。函數(shù)返回了一個(gè)包含所有產(chǎn)品列表的dataset。它調(diào)用了在第一部分已經(jīng)創(chuàng)建的存儲(chǔ)過(guò)程 procproductslist. 然后你可以看到3個(gè)過(guò)程。他們對(duì)應(yīng)于每個(gè)存儲(chǔ)過(guò)程,用于增加、刪除、修改產(chǎn)品;它們都有類似的結(jié)構(gòu); 每個(gè)使用了一個(gè)command,并聲明了連接對(duì)象和必須的參數(shù)。 作為一個(gè)例子, 我們來(lái)分開(kāi)討論productsdeleteitem過(guò)程。理解了這個(gè)過(guò)程,其他2個(gè)就很容易消化了. 一開(kāi)始,這個(gè)過(guò)程使用了一個(gè)參數(shù), productid, 表示需要?jiǎng)h除的產(chǎn)品的id。 sub productsdeleteitem(byval productid as integer) 接著,聲明了所有的變量. 分別用于存儲(chǔ)過(guò)程將要使用的connection,command和parameter. 這個(gè)參數(shù)就是需要?jiǎng)h除的那格產(chǎn)品id. dim con as oledbconnection dim cmd as oledbcommand = new oledbcommand() dim paramproductid as new oledbparameter() command和connection的初始化: con = new oledbconnection(connectionstring) cmd.connection = con 確認(rèn)了paramproductid 參數(shù)的屬性,然后這個(gè)參數(shù)被添加到command對(duì)象. 在這個(gè)例子中,要用到存儲(chǔ)過(guò)程里的參數(shù)名字是inproductid, 它是一個(gè)整型變量,并用函數(shù)的參數(shù)進(jìn)行賦值。 with paramproductid .parametername = "inproductid" .oledbtype = oledbtype.integer .size = 4 .value = productid end with cmd.parameters.add(paramproductid) 最后一步是真正調(diào)用存儲(chǔ)過(guò)程. cmd.commandtext = "execute procproductsdeleteitem" con.open() cmd.executenonquery() con.close() 注意connection對(duì)象這里只在需要執(zhí)行存儲(chǔ)過(guò)程的時(shí)候保留,然后就馬上關(guān)閉了。這將減少可能有的資源占用。 雖然這個(gè)例子中使用的dbtier類已經(jīng)清楚的介紹了如何使用access存儲(chǔ)過(guò)程, 它的功能仍然需要更多的增強(qiáng)來(lái)達(dá)到產(chǎn)品級(jí)的水平。因?yàn)闆](méi)有錯(cuò)誤處理。他仍然需要更多的強(qiáng)化。 本文的源代碼包括了dbtier.vb,這個(gè)文件同時(shí)包含了一些簡(jiǎn)單的form來(lái)測(cè)試類的實(shí)現(xiàn)。 總而言之,我希望您至少通過(guò)這些文章獲得了2個(gè)信息:一個(gè)是在microsoft access中存儲(chǔ)過(guò)程是存在的并且是不錯(cuò)的, 雖然有不足。第二個(gè)你需要同時(shí)理解需要把應(yīng)用程序的數(shù)據(jù)庫(kù)訪問(wèn)分解到獨(dú)立的類、函數(shù)、過(guò)程里面,這將使軟件的維護(hù)和升級(jí)變得更加容易。 完整的dbtier.vb: imports system imports system.data imports system.data.oledb
' functions and subroutines for executing stored procedures in access. public class dbtier
' change data source to the location of northwind.mdb on your local ' system. shared connectionstring as string = _ "provider=microsoft.jet.oledb.4.0;data source=c:/program " _ & "files/microsoft office/office10/samples/northwind.mdb" ' this function returns a dataset containing all records in ' the products table. function productslist() as dataset dim con as oledbconnection dim da as oledbdataadapter dim ds as dataset dim ssql as string
ssql = "execute procproductslist"
con = new oledbconnection(connectionstring) da = new oledbdataadapter(ssql, con) ds = new dataset() da.fill(ds, "products")
return ds
end function
' this function adds one record to the products table. sub productsadditem(byval productname as string, _ byval supplierid as integer, byval categoryid as integer) dim con as oledbconnection dim cmd as oledbcommand = new oledbcommand() dim paramproductname as new oledbparameter() dim paramsupplierid as new oledbparameter() dim paramcategoryid as new oledbparameter()
con = new oledbconnection(connectionstring) cmd.connection = con
with paramproductname .parametername = "inproductname" .oledbtype = oledbtype.varchar .size = 40 .value = productname end with cmd.parameters.add(paramproductname)
with paramsupplierid .parametername = "insupplierid" .oledbtype = oledbtype.integer .size = 4 .value = supplierid end with cmd.parameters.add(paramsupplierid)
with paramcategoryid .parametername = "incategoryid" .oledbtype = oledbtype.integer .size = 4 .value = categoryid end with cmd.parameters.add(paramcategoryid)
' this function updates a specific jobtitle record with new data. sub productsupdateitem(byval productid as integer, _ byval productname as string) dim con as oledbconnection dim cmd as oledbcommand = new oledbcommand() dim paramproductname as new oledbparameter() dim paramproductid as new oledbparameter()
con = new oledbconnection(connectionstring) cmd.connection = con
with paramproductid .parametername = "inproductid" .oledbtype = oledbtype.integer .size = 4 .value = productid end with cmd.parameters.add(paramproductid)
with paramproductname .parametername = "inproductname" .oledbtype = oledbtype.varchar .size = 40 .value = productname end with cmd.parameters.add(paramproductname)
' this function deletes one record from the products table. sub productsdeleteitem(byval productid as integer) dim con as oledbconnection dim cmd as oledbcommand = new oledbcommand() dim paramproductid as new oledbparameter()
con = new oledbconnection(connectionstring) cmd.connection = con
with paramproductid .parametername = "inproductid" .oledbtype = oledbtype.integer .size = 4 .value = productid end with cmd.parameters.add(paramproductid)