4. 解決一般的聯(lián)接問題
如果用SQL Links建立與InterBase服務器的連接有問題可采用下列步驟來分離問題原因:
⑴ 通過Windows ISQL工具測試能否與InterBase服務器聯(lián)接
如果成功,狀態(tài)信息會出現(xiàn),并繼續(xù)步驟⑵。
如果不成功,詢問數(shù)據(jù)庫管理員。
、 檢驗InterBase SQL Links 驅(qū)動程序是否正確安裝。
⑶ 重新安裝SQL Links。
⑷ 檢查SERVICES,文件中應有行:
gds_db 3050/tcp
如果不能正確安裝,就請詢問數(shù)據(jù)庫管理員,否則繼續(xù)步驟⑸。
、 測試底層協(xié)議
① 輸入TELNET命令,確認TCP庫是否正確安裝。
如果TCP庫正確安裝,注冊提示符會出現(xiàn)。注冊入網(wǎng)檢查數(shù)據(jù)庫是否存在。
如果消息是“can't resolve hostname” 出現(xiàn),檢查工作站的HOSTS文件是否有你 的主機名和IP地址的人口。如:
128.127.50.12 mis_server
如果用TELNET是成功的,但仍然無法正確聯(lián)接,則沒有正確安裝InterBase。請尋
求數(shù)據(jù)庫管理員的幫助。
② PING到服務器服務器上,測試InterBase服務器是否正常運行并且為桌面應用可見
(如果PING是成功的,消息“servername is alive”被顯示)。
PING成功但TELNET不成功,則inet daemon可能有問題。
如果PING到服務器上不成功,則有網(wǎng)絡路徑問題,將問題報給網(wǎng)絡管理員。
如果底層協(xié)議不正常,請詢問數(shù)據(jù)庫管理員,否則繼續(xù)幫助⑹。
⑹ 確認是否有InterBase服務器的訪問權,如果有請繼續(xù)步驟⑺。
⑺ 檢查BDE應用程序的InterBase別名是否正確安裝。
如果能夠直接從工作站上聯(lián)接,但不能從BDE應用程序中,那么很有可能你的
IDAPI32.CFG別名設置有問題。運行BDE配置工具檢查InterBase別名。
18.3 Delphi Client/Server編程
本節(jié)介紹如何運用Delphi可視化開發(fā)工具和ObjectPascal語言開發(fā)Client\Server的數(shù)據(jù)庫應用程序,采用的例子是CSDEMOS。這是Delphi2.0自帶的演示Client\Server開發(fā)的例子,它安裝在C:\Program Files\Borland\Delphi 2.0\Demos\DB\CSDemos中(缺省安裝)。
本節(jié)將包含以下內(nèi)容:
● 使用TDatabase部件連接SQL服務器
● 用DataSet部件(又稱數(shù)據(jù)集部件),如TTable和TQuery,聯(lián)接TDatabase部件并訪問數(shù)據(jù)庫以及各種表之間如何切換
● 使用數(shù)據(jù)庫連接
● 觸發(fā)器的使用方法
● TStoredProc部件的使用方法
● 客戶和服務器之間的事務控制
● TStoredProc部件的使用方法
18.3.1 使用TDatabase部件聯(lián)接SQL服務器
18.3.1.1 TDatabase部件概述
TDatabase部件處理應用程序與單個數(shù)據(jù)庫的聯(lián)接。如果不需要控制數(shù)據(jù)庫聯(lián)接,可以不用創(chuàng)建TDatabase部件。當應用程序試圖打開數(shù)據(jù)庫表(Table)時,會自動創(chuàng)建一個臨時的TDatabase部件。但如果你想控制數(shù)據(jù)庫的持續(xù)聯(lián)接、進入數(shù)據(jù)庫服務器的注冊和數(shù)據(jù)庫別名的值或事務控制,那么你就必須為每個所需的聯(lián)接創(chuàng)建一個TDatabase部件。
1. 創(chuàng)建TDatabase部件
TDatabase 部件在Component Palette中的Data Access頁上,你能將其拖放在數(shù)據(jù)模塊(Data module)或窗體中。在設計時創(chuàng)建TDatabase 部件,用戶可以設置初始值和編寫OnLogin事件處理過程(Event Handle)。OnLogin事件給用戶提供了第一次注冊數(shù)據(jù)庫服務器時定制服務器安全參數(shù),如口令,的能力。
2. TDatabase的關鍵屬性
、 DatabaseName屬性
DatabaseName是所要聯(lián)接的數(shù)據(jù)庫名,并且用于DataSet軟件,它將出現(xiàn)在DataSet部件的DatabaseName屬性的下拉式列表框中。設置DataBaseName屬性是定義數(shù)據(jù)庫應用的特定別名。DataSet部件能引用該名字以取代直接使用BDE別名。當TDatabase部件的Connected屬性為True時不能修改該屬性。
⑵ AliaName屬性
AliasName是BDE配置工具定義的BDE別名的名字。TDatabase 從中獲取其缺省的設置。如果設置DriveName屬性,則該屬性將被清除,如果當Connected為True 時強行設置DriveName屬性將引發(fā)異常。
⑶ DriveName屬性
DriveName是BDE驅(qū)動程序,如STANDARD 、ORACLE、SYBASE、INFORMIX或INTERBASE的名字。如果設置AliasName,則該屬性值將被清除。
、 Params屬性
Params屬性包含了打開SQL服務器上數(shù)據(jù)庫時所需的參數(shù)。在缺省情況下,這些參數(shù)由BDE配置工具設置;用戶也可以用數(shù)據(jù)庫參數(shù)編輯器(Database Parameters Editor)修改這些參數(shù)。對于數(shù)據(jù)庫服務器而言,Params將描述一系列的參數(shù),如服務器名、 數(shù)據(jù)庫名、用戶名和口令。
⑸ Connected屬性
Connected屬性指明是否建立數(shù)據(jù)庫的聯(lián)接,當應用程序打開數(shù)據(jù)庫中的一個表時Connected將被置為True;反之,關閉數(shù)據(jù)庫表,Connected將被置為False,除非KeepConnection為True。而將Connected置為True則可不需打開數(shù)據(jù)庫表即可建立數(shù)據(jù)庫聯(lián)接。TDatabase的KeepConnection屬性描述當數(shù)據(jù)庫中沒有表打開時是否維持數(shù)據(jù)庫聯(lián)連。
⑹ KeepConnection屬性
KeepConnection屬性描述當數(shù)據(jù)庫中沒有打開表時是否要保持與服務器的聯(lián)連, 如果數(shù)據(jù)庫應用需要打開和關閉單個數(shù)據(jù)庫中的多個表時,將KeepConnection 設置為True是很有用的,那樣,即使沒有打開任何表,應用仍能保持與數(shù)據(jù)庫的聯(lián)接,它能夠重復地打開和關閉數(shù)據(jù)庫表,而不需要重復執(zhí)行聯(lián)接過程。如果KeepConnection置為False,當每次將Connected置為True,數(shù)據(jù)庫都必須執(zhí)行注冊過程。
、 LoginPrompt屬性
LoginPrompt屬性用于控制如何處理SQL數(shù)據(jù)庫的安全性問題。如置為True,當應用程序試圖建立數(shù)據(jù)庫聯(lián)接時屏幕上將出現(xiàn)標準Delphi注冊對話框。用戶必須輸入正確的用戶名和口令。如果置為False,則應用程序?qū)ふ襎Database部件的Params 屬性中的注冊參數(shù)。下面是USERNAME和PASSWORD參數(shù)的例子:
USERNAME = SYSDBA
PASSWORD = masterkey
⑻ TransIsolation屬性
TransIsolation屬性描述SQL服務器所有的事務控制獨立級別。 tiDirtyRead使所有修改都被返回,而不管記錄是否已被提交。tiReadCommitted將只返回提交的記錄,而提交的修改將不會在結果中反映出來。tiRepeatableRead 將只返回事務過程中最初的記錄,即使另一個應用程序?qū)⑺鞯男薷奶峤弧?/P>
各種數(shù)據(jù)庫服務器可能不同程度地支持這些獨立級別,或者根本不支持。 如果需要的獨立級別不被服務器支持,那么Dephi將使用下一個更高的獨立級別,如下表所示:
表18.10 各類服務器TransIsolation設置
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
獨立級別 Oracle Sybase和 InterBase
Microsoft SQL
──────────────────────────────────────
Dirty Read Read Committed Read Committed Read Committed
Read Committed Read Committed Read Committed Read Committed
Repeatable read Repeatable read Not Supported Repeatable Read
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
各個獨立級別的含義請見表18.12。
3. TDatabase的關鍵方法
⑴ StartTransaction方法
StartTransartion方法在由TaransIsolation屬性指定的獨立級別下開始事務控制。如果在一個事務已被激活的情況下調(diào)用該方法,Delphi將引發(fā)異常。
調(diào)用了該方法后,對數(shù)據(jù)庫所做的修改一直由數(shù)據(jù)庫服務器維持到調(diào)用Commmit方法提交數(shù)據(jù)或調(diào)用Rollback方法取消修改為止。只有當聯(lián)接數(shù)據(jù)庫服務器時,才能調(diào)用該方法。
、 Rollback方法
Rollback方法返轉(zhuǎn)當前事務控制,并且取消自最近一次調(diào)用StartTransaction以來對數(shù)據(jù)庫所做的所有修改。
⑶ Commit方法
Commit方法提交當前事務控制,并且將自最近一次調(diào)用StartTransaction以來所有數(shù)據(jù)修改存入數(shù)據(jù)庫。
4. TDatabase的OnLogin事件的處理
OnLogin事件的觸發(fā)條件是當聯(lián)接SQL數(shù)據(jù)庫的TDatabase部件被打開并且LoginPrompt屬性為True。使用OnLogin事件處理過程可以在運行時設置注冊參數(shù)。OnLogin 事件處理過程得到TDatabase的注冊參數(shù)數(shù)組Params,并且使用Values屬性改變這些參數(shù)。
例如:
LoginParams.Vaiues['SERVER NAME'] := 'MYSERVERNAME';
LoginParams.Values['USER NAME'] := 'MYUSERNAME';
LoginParams.Values[PASSWORD'] := 'MYAPSSWORD';
當控制從OnLogin事件處理過程中返回時,應用程序用這些參數(shù)來建立聯(lián)接。
OnLogin事件處理過程的聲明是這樣的:
TLoginEvent = procedure(Database: TDatabase; LoginParam: TStrings) of Object;
property OnLogin: TLoginEvent;
TLoginEvent類型是處理OnLogin事件的方法頭。Database參數(shù)是要聯(lián)接的數(shù)據(jù)庫。LoginParams是TStrings類型的對象,包含用戶名和口令,以及打開數(shù)據(jù)庫時所用的其它參數(shù)。用戶名是形如USER NAME = John.Doe的字符串,口令是形如PASSWORD = is_Password的字符串。當OnLogin事件處理過程被調(diào)用時應當在LoginParams中加入用戶名和口令。
18.3.1.2 定制數(shù)據(jù)庫服務器的注冊參數(shù)
大多數(shù)數(shù)據(jù)庫服務器都包含限制數(shù)據(jù)庫訪問的安全特征。通常,在用戶能訪問數(shù)據(jù)庫之前,服務器都要求注冊的用戶名和口令。
如果服務器需要注冊,在設計階段,Delphi 會在你試圖聯(lián)接時提示你,諸如在會TTable部件描述數(shù)據(jù)庫表名時。
在缺省情況下,Delphi應用在打開數(shù)據(jù)庫服務器的聯(lián)接時,顯示標準注冊對話框。如果聯(lián)接已建立,則注冊對話框不會出現(xiàn)。
可以用下列方法處理服務器注冊:
1. 將TDatabase部件的LoginPrompt屬性置為True。這樣,當應用程序試圖建立數(shù)據(jù)庫聯(lián)接時,標準注冊對話框會打開。
2. 將LoginPrompt屬性置為False,在TDatabase部件的Params屬性中包含用戶名和口令參數(shù)。例如:
USERNAME = SYSDBA
PASSWORD = mosterkey
但不推薦使用該方法,因為這會危害數(shù)據(jù)庫安全
3. 使用TDatabase部件的OnLogin事件設置注冊參數(shù)。OnLogin事件得到TDatabase 注冊參數(shù)數(shù)組的拷貝,并利用Values屬性改變這些參數(shù)。如:
LoginParams.Values['SERVER NAME'] := 'MYSERVERNAME';
LoginParams.Values['USER NAME'] := 'MYUERNAME';
LoginParams.Values['PASSWORD'] := 'MYPASSWORD';
當控制從數(shù)據(jù)庫注冊事件處理過程中返回時,這些參數(shù)被用來建立聯(lián)接。
18.3.1.3 建立應用程序特定的別名
TDatabase的Aliases描述了數(shù)據(jù)庫表的位置和數(shù)據(jù)庫服務器的聯(lián)接參數(shù)。通常都是在Delphi之外,運用BDE配置工具(BDECFG32.EXE)創(chuàng)建別名,并且別名被存在BDE 配置文件IDAPI32.CFG中。
用戶也可以用TDatabase創(chuàng)建只在應用程序中可用的別名,用TDatabase 創(chuàng)建的別名不會加進BDE配置文件中。任何DataSet部件可通過描述DatabaseName 屬性來使用這些別名。為了定制這些局部別名的參數(shù),用鼠標左鍵雙擊TDatabase部件或從TDatabase部件中選擇Database Editor,Delphi就會打開數(shù)據(jù)庫屬性編輯器(Database Properties Editor)。
18.3.1.4 控制數(shù)據(jù)庫的聯(lián)接
TDatabase部件的Connected屬性,指示TDatabase部件是否建立與數(shù)據(jù)庫服務器的聯(lián)接。當應用程序打開數(shù)據(jù)庫中的表時,Connected被設置為True。將Connected 設為True就建立了數(shù)據(jù)庫的聯(lián)接。
1. 保持數(shù)據(jù)庫聯(lián)接
TDatabase的KeepConnection屬性描述當沒有數(shù)據(jù)庫表打開時是否要與保持數(shù)據(jù)庫的聯(lián)接。
如果應用程序需要在單個數(shù)據(jù)庫中多次打開關閉多個表時,將KeepConnection 置為True能使應用程序具備更好的性能。
當KeepConnection為True時,即使沒有表打開,應用程序也能保持數(shù)據(jù)庫的聯(lián)接。那么就能重復打開和關閉數(shù)據(jù)庫表而不需每次進行聯(lián)接注冊。
2. 使用TSesstion控制聯(lián)接
TSesstion部件有一個面向整個應用程序的KeepConnections屬性。如果Session.KeepConnections為True,那么用于所有TDatabase部件的數(shù)據(jù)庫聯(lián)接都是持久的。
TSession為應用程序提供數(shù)據(jù)庫聯(lián)接的全局控制。TSession中的Databases 屬性是Session中所有活躍數(shù)據(jù)庫組成的數(shù)組,DatabasesCount屬性描述活躍數(shù)據(jù)庫的數(shù)目。
3. 描述Net和Private目錄
TSession的NetFileDir屬性描述BDE網(wǎng)絡控制目錄的路徑。TSession的PrivateDir屬性描述存儲諸述處理局部SQL表達式的臨時文件的目錄的路徑。
18.3.1.5 獲取數(shù)據(jù)庫信息
TSession擁有許多讓用戶獲取數(shù)據(jù)庫有關的信息,每個方法都以TStringList 部件作為傳入?yún)?shù),并將信息返回TStringList中。
1. GetAliasNames方法
聲明:procedure GetAliasNames(List: TStringList);
GetAliasNames方法消除List中的參數(shù),并將所有已定義的BDE別名的名字寫入List。應用程序生成的別名不包括在內(nèi)。
2. GetAliasParams方法
聲明:procedure GetAliasParams(const AliasName: String; List: TStringList);
GetAliasParams方法清除List的內(nèi)容,并將BDE別名為AliaName的參數(shù)寫入List。
3. GetDatabaseNames方法
聲明:procedure GetDatabaseNames(List: TStrings);
GetDatabaseNames方法清除List的內(nèi)容并將所有BDE別名和應用程序定義的別名的名字寫入List。
4. GetDriverNames方法
聲明:procedure GetDriverNames(List: TStrings);
GetDriverNames方法清除List中的內(nèi)容,并將BDE當前安裝的驅(qū)動程序名寫入List。
5. GetDriverParams方法
聲明:procedure GetDriverParams(const DriverName: String; List: TStrings);
GetDriverParams方法消除List中的內(nèi)容,并將名為DriveName驅(qū)動程序缺省參數(shù)寫入List。
6. GetTableNames方法
聲明:procedure GetTableNames(const DatabaseName, Pattern: Strings;
Extensions, SystemTable: Boolean; List: TStrings);
GetTableNames方法消除List中的內(nèi)容,并將名為DatabaseName的數(shù)據(jù)庫中的所有表的名字寫入List。Pattern參數(shù)將限制表名。對于SQL服務器,將SystemeTables設為True將獲取系統(tǒng)表和用戶表。對非SQL數(shù)據(jù)庫,將Extensions設為True將在表名中包含擴展名。
18.3.2 處理Client/Server事務控制
使用隱式控制和顯示控制的數(shù)據(jù)庫應用中有兩種方法管理事務控制:
● 運用TDatabase部件的屬性和方法進行顯式控制
● 運用TQuery部件的傳遞式SQL控制事務
Delphi還支持Paradox和dBASE表的局部事務處理
18.3.2.1 事務控制概述
當用Delphi創(chuàng)建數(shù)據(jù)庫應用時,Delphi提供了用為所有數(shù)據(jù)庫訪問的事務控制。
事務是這樣一組操作,在被提交前,它們對一個或多個數(shù)據(jù)庫的操作,必須全部執(zhí)行成功。如果其中一個操作失敗,則所有操作失敗,即事務具有原子性。
即使發(fā)生硬件失敗,事務也要保證數(shù)據(jù)庫一致性。當允許多用戶并發(fā)訪問時,事務還要維持數(shù)據(jù)完整性。
例如:一個應用程序可能更新ORDERS表以指明接受購買某一項目的定單,那么也要更新INNENTORY表以反映庫存的減少。如果在第一個更新之后,第二個更新之前發(fā)生硬件錯誤,數(shù)據(jù)庫就會處于不一致狀態(tài),因為庫存情況沒有反映定單情況。在事務控制下,兩個表達式將在同一時間提交,如果其中一個表達式失敗,則被返轉(zhuǎn)(Rolled Back)。
18.3.2.2 使用隱式控制
在缺省情況下,Delphi通過BDE為應用程序提供隱式事務控制。當應用程序處于隱式事務控制時Delphi為DataSet中的寫每個記錄進行隱式事務控制。它提交每一個獨立的寫操作,如Post和Append Record。
使用隱式事務控制是容易的,它保證最小的記錄更新沖突和數(shù)據(jù)庫的一致性視圖。另一方面,因為寫入數(shù)據(jù)庫的數(shù)據(jù)的每一行都要進行事務控制, 所以隱式事務控制將導致網(wǎng)絡過忙和應用程序性能下降。
如果采用顯式事務控制,就能選擇最有效的時機來開始、提交和終止事務,特別是在開發(fā)多用戶環(huán)境下的客戶應用程序運行訪問遠程SQL服務器,就更應該采用顯式控制。
18.3.2.3 使用顯式事務控制
有兩種協(xié)作又獨立的方式可運用于Delphi數(shù)據(jù)庫應用的事務控制:
● 使用TDatabase部件的方法和屬性
● 使用TQuery部件中的傳遞式SQL。這種方式只有在Delphi Client/Server Suite版中才有效,SQL Links將SQL表達式直接傳給過程SQL或ODBC服務器
使用TDatabase部件的方法和屬性的好處是提供了清晰的、輕便的、與特定數(shù)據(jù)庫或服務器無關的應用能力。
使用傳遞式SQL的主要好處在于可以運用特定服務器的先進事務管理能力。
相關推薦:2010年9月計算機等級考試試題及答案解析專題北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內(nèi)蒙古 |