在DELPHI程式中使用ADO物件存取ODBC數
-------------------------------------------------- ------------------------------
身為asp愛好者,筆者常在ASP頁面中使用ADO物件操作ODBC資料庫,覺得用ASP創建Web應用系統確實是挺方便的。雖然在程式設計生涯中,筆者更喜歡Borland系列產品,對微軟產品有點排斥,但對ASP卻是例外。某天,忽然想到,ADO對像是一個標準OLE對象,如果在Delphi應用程式中能利用ADO操作資料庫,應該還挺不錯。尤其在用DELPHI做網路資料庫應用程式時,如果所在的Web網站是WINNT網站並且支援ASP頁面,那就可以用ADO物件存取ODBC資料庫,而不用把那麼大的BDE再上載到網站上去。這樣就可充分利用DELPHI和ASP的程式設計優勢,做出更好的ISAPI/NSAPI/CGI。經過程式設計與測試,在Delphi中可以成功地用ADO物件存取ODBC資料庫,現將本人的使用經驗寫出來,與大家分享,讓我們多一個存取ODBC資料庫的方法。
在32位元的Delphi中,可以宣告一個variant變數(如AVariant),然後透過CreateOleObject建立一個OLE對象,如AVariant:=CreateOleObject ('ADODB.Connection')可以獲得一個資料庫連接對象的實例,然後就可以利用該物件的方法和屬性來操作ODBC資料庫了。
以下簡單介紹一下存取ODBC資料庫所用到的ADO物件及其方法與屬性。
1、資料庫連線對象(ADODB. Connection)
此物件用於與ODBC資料庫建立連接,所有對資料庫的操作均透過此連接進行。
資料庫連接物件ADODB. Connection的作用象Delphi中的TDatabase物件。
建立一個連線物件的方法為(AConnection為Variant類型變數):
AConnection:=CreateOleObject('A DODB.Connection')
用來建立連線的方法為Open,使用語法為(以物件AConnection為例):
AConnection.Open( ConnectionString, UserId, PassWord )
三個參數都是字串類型,其中UserId和Password為使用者名稱和使用者密碼,用於存取資料庫使用時可以省略,因為在ConnectionString同樣可以指定使用者名稱和使用者密碼。 ConnectionString是用來說明ODBC資料來源資訊的字串,其格式為:
'PRovider=ProviderName; DSN=DSNName; DRIVER=driver; SERVER=server; DATABASE=database; UID=user; PWD=password'
其中:
Provider:資料提供者,預設狀態下為MSDASQL,為微軟OLEDB,通常省略;
DSN:要開啟的資料庫對應的OBDC系統資料來源(DSN),是可選參數;
DRIVER:要開啟的資料庫所使用的驅動程式名稱,例如access對應Microsoft Access Driver (*.mdb),是選用參數;
SERVER:要開啟的資料庫所在的伺服器名稱,本機可用(local),是可選參數;
DATABASE:要開啟的資料庫名稱,是可選參數;
UID:使用者名稱,用來存取資料庫,是可選參數;
PWD:使用者密碼,用來存取資料庫,是可選參數。
以上參數均為可選參數,但必須提供足夠的資訊來描述一個系統資料來源。
假如已經定義了一個ODBC的系統DSN,名稱為MyDsn,那麼就可用以下語句建立一個資料庫連線:
AConnection.Open('DSN=MyDsn');
為了防止DSN不存在或其設定被他人修改時造成應用程式執行錯誤,可以用ADODB.Connection 建立一個臨時ODBC資料來源,這樣可以保證我們使用的系統DSN的參數設定是正確的。下面的語句可以建立一個臨時ODBC系統DSN,對應一個ACCESS資料庫,路徑為C:Inetpub wwwroot test.mdb:
AConnection.open('Driver= {Microsoft Access Driver (*.mdb)};DBQ=C:inetpub wwwroot est.mdb')
建立一個ADODB.Connection後,如果不需要回傳操作結果(如刪除,修改,更新等操作)就可以對資料庫進行正常的SQL操作了,此時應用ADODB.Connection的另外一個方法Execute,使用語法為:
AConnection.Execute( strSQL );
其中strSQL為執行操作的SQL語句,如刪除操作可以為:delete from wfjcommu。用AConnection.Close關閉一個資料庫連線。
2、資料集物件(ADODB. RecordSet)
如果要執行查詢操作並傳回查詢結果,或者要更方便地操作資料表,那就需要用到資料集物件了。
資料集物件ADODB.RecordSet的作用象Delphi中的TTable或TQuery物件。
建立一個資料集物件的方法為(ARecordSet為Variant類型變數):
ARecordSet:=CreateOleObject ('ADODB.RecordSet')
從資料表取得資料的方法為Open方法,具體使用方法為:
ARecordSet.Open( strCommand,ActiveConnection,int CursorType,intLockType, intCommandType );
其中:
strCommand:字串,為指令參數,可以是一個Table名稱,可以是一個SQL語句,也可以是一個伺服器上的預存程序(StoredProc)名稱,所以需要一個後面的參數intCommandType來指定。
ActiveConnection:要使用的資料庫連接,是一個ADODB. Connection物件。
intCursorType:長整數,資料集的Cursor類型,可選參數,請參考程式中註解。
intLockType:長整數,對資料表的加鎖類型,可選參數,請參閱程式中註解。
intCommandType:長整數,指令參數的類型,用來指明strCommand的作用,可以指定strCommand為指令(如SQL語句)或資料表(TTable)或儲存程序(StoredProc),可選參數,請參考程式中註解。
如執行一個SQL查詢,可以採用以下語句:
ARecordSet.Open('Select * from wfjcommu',adOpenStatic,ad LockOptimistic,adCmdText);
其它常見屬性和方法與TTable和TQuery比較如下(請參閱ASP幫助文件):
eof,bof: eof,bof. MoveFirst, MoveLast: First, LastMovePrevious, MoveNext: Prior, NextMove: MoveByAddNew: appendUpdate: PostClose: close
Delete加Update:delete,所有資料表的修改均須用Update使操作有效,這與Delphi不同。
Fields[FieldNo]: Fields[FieldNo]
Fields['FieldName']: FieldByName('FieldName')
3.其他常見物件(與Delphi對應的物件):
ADODB.Field: TField ADODB.Parameter: TPara ADODB.Error: EDBEngineError
ADODB.Command:無ADODB.Property:無
下面來看一個應用範例:
procedure TForm1.Button1Click(Sender: TObject);
{************************************************* ****
用ADO操作ODBC資料庫
本程式中,將建立一個臨時的ODBC系統資料來源,指向MsAccess資料庫,然後對其中的資料表進行顯示、增加、修改、刪除和查詢操作
注意:請在Uses語句中包含ComObj單元
************************************************** ***}
const{一些常數聲明,詳細請參閱adovbs.inc}
{---- CommandType的常數說明----}
adCmdUnknown = 0008;//未知,需要係統來判斷,速度慢,為預設值
adCmdText = 0001;//指令語句如SQL語句
adCmdTable = 0002;//資料表名稱
adCmdStoredProc = 0004;//預存程序名稱
{---- CursorType的常數說明----}
adOpenForwardOnly = 0;//只能由前向後單向訪問,為預設值
adOpenKeyset = 1;//可見其他使用者對資料的修改,但對其它使用者的增加和刪除不可見
adOpenDynamic = 2;//其他使用者對資料的增加修改和刪除均可見
adOpenStatic = 3;//其他使用者對資料增加的修改和刪除均不可見
{---- LockType的常數說明---}
adLockReadOnly = 1;//唯讀,為預設值
adLockPessimistic = 2;//在修改時,按單一記錄鎖定
adLockOptimistic = 3;//在修改後更新時,按單一記錄鎖定
adLockBatchOptimistic = 4;//在成批更新時記錄鎖定
var
AConnection, ARecordSet : variant;
longintTemp : integer;
strTemp : string;
intIndex : integer;
begin
{建立一個暫時的ODBC資料來源,指向一個MsAccess資料庫,並利用此DSN建立一個資料庫連線}
AConnection := CreateOleObject('ADODB.Connection');
AConnection.Open('Driver={Microsoft Access Driver (*.mdb)};DBQ=C:inetpubwwwroot est');
{建立一個資料集物件,並從資料表中擷取資料}
ARecordSet := CreateOleObject('ADODB.RecordSet');
ARecordSet.open( 'wfjcommu',AConnection,adOpenStatic,adLockOptimistic,adCmdTable );
memo1.lines.clear;
memo1.lines.add('********資料表原有的內容如下********');
{顯示各個網域的網域名稱}
strTemp := '';
for intIndex := 0 to ARecordSet.Fields.count - 1 do
strTemp := strTemp + ARecordSet.Fields[intIndex].name+';';
memo1.lines.add( strTemp );
{顯示各網域的內容}
while not ARecordSet.eof do
begin
strTemp := '';
for intIndex := 0 to ARecordSet.Fields.count - 1 do
strTemp := strTemp + ARecordSet.Fields[intIndex].value+';';
memo1.lines.add( strTemp );
ARecordSet.MoveNext;//移到下條,Next
end;
{增加一個記錄}
ARecordSet.AddNew;//增加,Append
ARecordSet.Fields['AName'] := '1';//以FieldByName的方式存取
ARecordSet.Fields['Portable'] := '2';
ARecordSet.Fields(2) := '3';//以Fields[index]的方式存取
ARecordSet.Fields(3) := '4';
ARecordSet.Fields(4) := '5';
ARecordSet.Update;//更新,Post
ARecordSet.MoveFirst;//移到首條,First
memo1.lines.add('********增加了一筆記錄後的資料表的內容如下********');
{顯示各網域的內容}
while not ARecordSet.eof do
begin
strTemp := '';
for intIndex := 0 to ARecordSet.Fields.count - 1 do
strTemp := strTemp + ARecordSet.Fields[intIndex].value+';';
memo1.lines.add( strTemp );
ARecordSet.MoveNext;//移到下條,Next
end;
{修改最後一筆記錄}
ARecordSet.MoveLast;
ARecordSet.Fields['AName'] := '11';//以FieldByName的方式訪問
ARecordSet.Fields['Portable'] := '22';
ARecordSet.Fields(2) := '33';//以Fields[index]的方式存取
ARecordSet.Fields(3) := '44';
ARecordSet.Fields(4) := '55';
ARecordSet.Update;//更新,Post
ARecordSet.MoveFirst;//移到首條,First
memo1.lines.add('********修改了最後一筆記錄後的資料表的內容如下********');
{顯示各網域的內容}
while not ARecordSet.eof do
begin
strTemp := '';
for intIndex := 0 to ARecordSet.Fields.count - 1 do
strTemp := strTemp + ARecordSet.Fields[intIndex].value+';';
memo1.lines.add( strTemp );
ARecordSet.MoveNext;//移到下條,Next
end;
{刪除最後一筆記錄}
ARecordSet.MoveLast;//移到末條,Last
ARecordSet.delete;//刪除,delete
ARecordSet.Update;//更新,在Delphi不需要
ARecordSet.MoveFirst;//移到首條,First
memo1.lines.add('********刪除了最後一筆記錄後的資料表的內容如下********');
{顯示各網域的內容}
while not ARecordSet.eof do
begin
strTemp := '';
for intIndex := 0 to ARecordSet.Fields.count - 1 do
strTemp := strTemp + ARecordSet.Fields[intIndex].value+';';
memo1.lines.add( strTemp );
ARecordSet.MoveNext;//移到下條,Next
end;
ARecordSet.Close;{關閉資料集}
{以SQL語句進行查詢,查詢姓名為「張三」的記錄}
{注意,在SQL語句中,字串應該用單引號來包含}
ARecordSet.open( 'select * from wfjcommu where AName = ''張三''',
AConnection,adOpenStatic,adLockOptimistic,adCmdText );
memo1.lines.add('********張三的內容如下********');
memo1.lines.add( '共有' + IntToStr( ARecordSet.RecordCount ) + '筆符合的記錄' );
{顯示各網域的內容}
while not ARecordSet.eof do
begin
strTemp := '';
for intIndex := 0 to ARecordSet.Fields.count - 1 do
strTemp := strTemp + ARecordSet.Fields[intIndex].value+';';
memo1.lines.add( strTemp );
ARecordSet.MoveNext;//移到下條,Next
end;
{關閉資料集與資料庫連線}
ARecordSet.close;
AConnection.close;
end;
聽別人說總不如自己看實際的例子來體會。在這個範例中,將示範如何利用ADO物件來對一個資料表進行查詢、增加記錄、修改記錄和刪除記錄操作。具體的用法請參考程式中的註釋,如果有點Delphi資料庫程式設計經驗,相信不難理解。
在我們的範例使用的資料庫為Test.MDB,其中有一個資料表為wfjcommu,有五個欄位AName、Portable、Tel、BP、PostAddress,分別表示姓名、手機號碼、電話號碼、呼機號碼和通訊地址。
以上程式在PWIN98+ Delphi 3.0+PWS(Personal Web Server)4.0下除錯通過.