?? 041.htm
字號(hào):
部件返回一個(gè)“活動(dòng)”的查詢(xún)結(jié)果數(shù)據(jù)集時(shí),它的CanModify屬性的值會(huì)被設(shè)置成True。</p><p> </p><p>表17.1 TQuery部件返回查詢(xún)結(jié)果數(shù)據(jù)的類(lèi)型</p><p>━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</p><p>RequestLive屬性值 CanModify屬性值 查詢(xún)結(jié)果的類(lèi)型</p><p>────────────────────────────────</p><p>False False 只讀數(shù)據(jù)</p><p>True(SQL語(yǔ)句滿足約束條件) True “活動(dòng)”數(shù)據(jù)</p><p>True(SQL語(yǔ)句不滿足約束條件) False 只讀數(shù)據(jù)</p><p>━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</p><p> </p><p>當(dāng)TQuery部件返回只讀的查詢(xún)結(jié)果數(shù)據(jù)集,而用戶又希望修改這只讀的數(shù)據(jù)集時(shí),一般這樣來(lái)處理,在應(yīng)用程序中另外增加一個(gè) TQuery 部件 Query2( 假設(shè)獲得只讀結(jié)果的TQuery部件的名字是Query1),在Query2中設(shè)置修改語(yǔ)句UpDATE對(duì)Query1中的數(shù)據(jù)進(jìn)行修改操作,這樣會(huì)實(shí)現(xiàn)對(duì)只讀數(shù)據(jù)的修改。</p><p> </p><p>17.4 動(dòng)態(tài)SQL語(yǔ)句的編程</p><p> </p><p>在17.3節(jié)中,我們已經(jīng)介紹了動(dòng)態(tài)SQL語(yǔ)句(又被稱(chēng)為參數(shù)化的SQL語(yǔ)句),在其中包含在程序過(guò)程中可以變化的參數(shù),在實(shí)際的程序設(shè)計(jì)中使用得更多的是動(dòng)態(tài)SQL語(yǔ)句,因而在這一節(jié)里我們重點(diǎn)介紹如何給動(dòng)態(tài)SQL語(yǔ)句的參數(shù)賦值,以在應(yīng)用程序中靈活地使用SQL語(yǔ)句。動(dòng)態(tài)SQL語(yǔ)句的編寫(xiě)、執(zhí)行等等與17.3節(jié)中介紹的SQL語(yǔ)句的編寫(xiě)、執(zhí)行是一樣的。</p><p>動(dòng)態(tài)SQL語(yǔ)句中的參數(shù),我們可以通過(guò)兩種途徑來(lái)為它賦值:</p><p>1. 利用參數(shù)編輯器(Parameter Editor)來(lái)為參數(shù)賦值</p><p>具體方法是:選中TQuery部件,單擊鼠標(biāo)右鍵,然后從中選擇DefineParameters 便可以打開(kāi)參數(shù)編輯器。 </p><p>例如,在TQuery部件的SQL屬性中我們?cè)O(shè)置如下的SQL語(yǔ)句: </p><p>Setect * From Customer Where CustNO=:Number;</p><p> </p><p>TQuery的DatabaseName屬性為DBDEMOS,其中Number為參數(shù)變量。我們便可以為參數(shù)Number賦值,在Datetype組合框中選擇該參數(shù)的數(shù)據(jù)類(lèi)型為整數(shù)Integer,在Value編輯框中可以為參數(shù)Number賦一個(gè)值,也可以單擊NullValue檢查框?yàn)閰?shù)Number賦一個(gè)空值Null。給參數(shù)賦值之后,單擊OK按鈕,這樣TQuery部件中的SQL查詢(xún)便準(zhǔn)備好了,而且參數(shù)值也被賦給了動(dòng)態(tài)SQL語(yǔ)句中相應(yīng)的參數(shù),此時(shí)當(dāng)把TQuery部件的Active屬性設(shè)置成True時(shí),在與TQuery部件相連的數(shù)據(jù)瀏覽部件中會(huì)顯示出查詢(xún)結(jié)果,通過(guò)參數(shù)編輯器為參數(shù)賦值,這種方式缺乏應(yīng)有的靈活性,在實(shí)際應(yīng)用中用得較少,在實(shí)際應(yīng)用中程序設(shè)計(jì)人員希望用更靈活方便的方式為參數(shù)賦值,那就是我們接下來(lái)要介紹的另一種途徑:</p><p>2. 在運(yùn)行過(guò)程中,通過(guò)程序?yàn)閰?shù)賦值</p><p>用這種方式為參數(shù)賦值有三種方法:</p><p>①根據(jù)參數(shù)在SQL語(yǔ)句中出現(xiàn)的順序,設(shè)置TQuery部件的Params屬性值為參數(shù)賦值。</p><p>②直接根據(jù)SQL語(yǔ)句中各參數(shù)的名字,調(diào)用ParamByName方法來(lái)為各參數(shù)賦值。</p><p>③將TQuery部件的DataSource屬性設(shè)置為另一個(gè)數(shù)據(jù)源,這樣將另一個(gè)數(shù)據(jù)源中與當(dāng)前TQuery部件的SQL語(yǔ)句中的參數(shù)名相匹配的字段值賦給其對(duì)應(yīng)的參數(shù)。</p><p>這三種方法我們將在下面的三小節(jié)中具體地介紹</p><p> </p><p>17.4.1 使用Params屬性為參數(shù)賦值</p><p> </p><p>TQuery部件具有一個(gè)Params屬性,它們?cè)谠O(shè)計(jì)時(shí)不可用,在程序運(yùn)行過(guò)程中可用,并且是動(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ǔ)句中的參數(shù), 也就是說(shuō)動(dòng)態(tài)SQL語(yǔ)句中第一個(gè)參數(shù)對(duì)應(yīng)Params[0],第二個(gè)參數(shù)對(duì)應(yīng)params[1],依此類(lèi)推。</p><p>例如:一個(gè)TQuery部件Query1,我們?yōu)樗帉?xiě)的動(dòng)態(tài)SQL語(yǔ)句是:</p><p> </p><p>Insert Into Customer(CustNo,Name,Country)</p><p>Values(:CustNo,:Name, : Country)</p><p> </p><p>對(duì)于上述這條動(dòng)態(tài)SQL語(yǔ)句中的參數(shù),我們可以利用TQuery部件的params屬性為參數(shù)賦值:</p><p> </p><p>Query1.params[0].AsString := "1988";</p><p>Query1.params[1].AsString := "Lichtenstein";</p><p>Query1.params[2].AsString := "USA";</p><p> </p><p>上述語(yǔ)句將把"1988"賦給參數(shù):Cuse_No,"Lichtenstein"賦給參數(shù):Name,"USA"賦給參數(shù):Country。</p><p> </p><p>17.4.2 使用ParamByName方法為參數(shù)賦值</p><p> </p><p>ParamByName是一個(gè)函數(shù),用動(dòng)態(tài)SQL語(yǔ)句中的參數(shù)作為調(diào)用ParamByName函數(shù)的參數(shù),這樣便可以為它們賦值,使用這種賦值方法,必須要知道動(dòng)態(tài)SQL語(yǔ)句參數(shù)的名字。</p><p>例如在17.4.1節(jié)中的例子中,也可以用下述方法給參數(shù)賦值:</p><p> </p><p>Query1.ParamByName('CustNo').AsString := "1988";</p><p>Query1.ParamByName('Name').AsString := "Lichtenstein";</p><p>Query1.ParamByName('Country').AsString := "USA";</p><p> </p><p>使用這種方法同樣可以為各參數(shù)賦值,而且更加直觀一些。</p><p> </p><p>17.4.3 使用Datasource屬性為參數(shù)賦值</p><p> </p><p>上述兩種方法的共同特點(diǎn)是:我們?cè)跒楦鲄?shù)賦值時(shí),我們是知道各參數(shù)對(duì)應(yīng)的具體參數(shù)值的。而在具體的應(yīng)用程序中,有些參數(shù)值常常是無(wú)法確定的,例如參數(shù)值來(lái)自于另一個(gè)查詢(xún)結(jié)果,對(duì)于這種情況,Delphi提供了使用Datasource屬性為動(dòng)態(tài)SQL語(yǔ)句中尚存在沒(méi)有賦值的參數(shù)時(shí), Delphi 會(huì)自動(dòng)檢查 TQuery 部件的Datasource 屬性, 如果為Datasource屬性設(shè)置了屬性值(該屬性的值是另一個(gè)TDatasource部件的名字),Delphi會(huì)把沒(méi)有賦值的參數(shù)與TDatasource部件中的各字段比較,Delphi會(huì)將相應(yīng)的字段值賦給與其相匹配的參數(shù),利用這種方法也能實(shí)現(xiàn)所謂的連接查詢(xún),我們?cè)趯W(xué)習(xí)使用TTable部件時(shí),便會(huì)創(chuàng)建主要--明細(xì)型數(shù)據(jù)庫(kù)應(yīng)用,用TQuery部件創(chuàng)建的連接查詢(xún)與主要--明細(xì)型應(yīng)用是相似的。</p><p>例如:在如圖17.7所示的應(yīng)用中,設(shè)置了下列部件:</p><p>● 一個(gè)TTable部件</p><p>名字為Cust,它的DatabaseName屬性為DEMOS,TableName屬性為Customer。</p><p>● 一個(gè)TDatasource部件</p><p>名字為Custsource,其Dataset屬性被設(shè)置為Cust。</p><p>● 一個(gè)TQuery部件</p><p>名字為ORDERS,其DatabaseName被設(shè)置為DEMOS,SQL屬性值為:</p><p> </p><p>Select Orders.CustNo,Orders.OrderNo,Orders.SaleDate FROM Orders</p><p>WHERE Orders.CustNo =: CustNo</p><p> </p><p>ORDERS的DataSouce屬性被設(shè)置為CustSource</p><p>● 一個(gè)TDatasource部件</p><p>名字為OrderSource,其DataSet屬性被設(shè)置為Orders。</p><p>● 兩個(gè)TDBGrid部件</p><p>它們分別連接CustSource和OrderSource。</p><p>TQuery部件Orders中的動(dòng)態(tài)SQL語(yǔ)句中的參數(shù):CustNo在程序設(shè)計(jì)過(guò)程中沒(méi)有給它賦值,當(dāng)該應(yīng)用程序運(yùn)行時(shí)Delphi會(huì)自動(dòng)地到其Datasource屬性中說(shuō)明的數(shù)據(jù)源CustSource中查找與參數(shù):CustNo匹配的字段,而CustSource中正好有一個(gè)名字為CustNo 的字段與參數(shù):CustNo匹配,這樣Customer表中的CustNo字段值被賦給了參數(shù): CustNo , 而當(dāng)每移動(dòng)Customer表中的記錄指針,參數(shù):CustNo的值會(huì)隨之改變,而參數(shù):CustNo的值發(fā)生改變時(shí),Orders中的動(dòng)態(tài)SQL語(yǔ)句會(huì)根據(jù)新的參數(shù)值重新查詢(xún),從數(shù)據(jù)庫(kù)表中獲取相應(yīng)的訂單數(shù)據(jù),這樣也變實(shí)現(xiàn)了類(lèi)似于主要--明細(xì)型應(yīng)用。即連接查詢(xún)。 </p><p>17.4.4 Prepare方法的使用 </p><p>在使用動(dòng)態(tài)SQL語(yǔ)句編程時(shí),常常用到一個(gè)很重要的方法prepare,調(diào)用prepare方法之后,Delphi會(huì)將帶參數(shù)的SQL語(yǔ)句傳送給與其對(duì)應(yīng)的數(shù)據(jù)庫(kù)引擎,對(duì)動(dòng)態(tài)SQL語(yǔ)句進(jìn)行語(yǔ)法分析和優(yōu)化。雖然在用動(dòng)態(tài)SQL語(yǔ)句編程時(shí),調(diào)用prepare方法并不是必須的,但是這里我們要極力推薦調(diào)用prepare方法,因?yàn)檎{(diào)用prepare方法后,會(huì)大大提高動(dòng)態(tài)SQL語(yǔ)句的執(zhí)行性能,特別是當(dāng)要反復(fù)多次執(zhí)行同一條動(dòng)態(tài)SQL語(yǔ)句時(shí),其優(yōu)越性會(huì)更加明顯。如果在應(yīng)用程序中執(zhí)行一條SQL語(yǔ)句之前并沒(méi)有顯式地調(diào)用prepare方法,每次在執(zhí)行SQL語(yǔ)句時(shí),Delphi會(huì)隱含地調(diào)用propare方法以準(zhǔn)備這個(gè)查詢(xún)。</p><p>TQuery部件還有一個(gè)prepare屬性,這是一個(gè)布爾型屬性,當(dāng)其屬性值為T(mén)rue時(shí),表明該查詢(xún)已被準(zhǔn)備好了( SQL 語(yǔ)句已被傳送到數(shù)據(jù)庫(kù)引擎中 ) ,當(dāng)我們使用參數(shù)編輯器Parameters Editor來(lái)為動(dòng)態(tài)SQL語(yǔ)句中的參數(shù)賦值時(shí),當(dāng)設(shè)置完相應(yīng)的參數(shù)值并退出參數(shù)編輯器時(shí),Delphi會(huì)隱含地調(diào)用prepare方法以準(zhǔn)備好查詢(xún)。</p><p>當(dāng)SQL語(yǔ)句執(zhí)行完之后,要想準(zhǔn)備下一個(gè)查詢(xún),首先必須調(diào)用close方法,然后才能調(diào)用prepare方法準(zhǔn)備下一個(gè)查詢(xún)。一般來(lái)說(shuō),在一個(gè)應(yīng)用程序中應(yīng)該調(diào)用一次prepare方法,常常在窗體的OnCreate事件處理過(guò)程中調(diào)用prepare方法,然后用上述介紹的方法為參數(shù)賦值,最后調(diào)用Open方法或ExecSQL方法執(zhí)行SQL語(yǔ)句,以完成查詢(xún)。</p><p>當(dāng)然在調(diào)用prepare方法準(zhǔn)備好一個(gè)查詢(xún)時(shí),會(huì)消耗一些數(shù)據(jù)庫(kù)資源,因而每當(dāng)一個(gè)查詢(xún)執(zhí)行完畢之后,要養(yǎng)成調(diào)用Unprepare方法以撤消查詢(xún)的好習(xí)慣。在運(yùn)行程序過(guò)程中,通過(guò)程序改變TQuery部件的SQL屬性值時(shí),Delphi會(huì)自動(dòng)地調(diào)用Close方法和Unprepare方法,以撤消查詢(xún)。</font></p><p> </p><hr width="94%"></TD><TD CLASS="tt3" VALIGN="bottom" width="8%" ><strong><A HREF="042.htm"><FONT style="FONT-SIZE: 9pt">后一頁(yè)</font></A><BR><A HREF="040.htm"><FONT style="FONT-SIZE: 9pt">前一頁(yè)</font></A><BR><A HREF="index.html"><FONT style="FONT-SIZE: 9pt">回目錄</font></A><BR></strong></TD></TR></table></BODY></HTML>
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -