2. TStoredProc部件的存儲過程編程
TStoredProc Delphi 專門用來使用服務(wù)器存儲過程的部件。CSDEMO 中演示用TStoredProc調(diào)用存儲過程的窗體是TFrmExecPr
在程序運行中,當按下ShipOrder按鈕,要求對ORED_STA_TUS等字段的內(nèi)容作修改以維護數(shù)據(jù)庫的一致性。字段內(nèi)容的修改任務(wù)由服務(wù)器上的存儲過程SHIP_ORDER完成。SHIP_ORDE的程序如下:
PROCEDURE SHIP_ORDER
DECLARE VARIABLE ord_stat CHAR(7);
DECLARE VARIABLE hold_stat CHAR(1);
DECLARE VARIABLE cust_no INTEGER;
DECLARE VARIABLE any_po CHAR(8);
BEGIN
SELECT s.order_status, c.on_hold, c.cust_no
FROM sales s, customer c
WHERE po_number = :po_num
AND s.cust_no = c.cust_no
INTO :ord_stat, :hold_stat, :cust_no;
IF (ord_stat = "shipped") THEN
BEGIN
EXCEPTION order_already_shipped;
SUSPEND;
END
ELSE IF (hold_stat = "*") THEN
BEGIN
EXCEPTION customer_on_hold;
SUSPEND;
END
FOR SELECT po_number
FROM sales
WHERE cust_no = :cust_no
AND order_status = "shipped"
AND paid = "n"
AND ship_date < 'NOW' - 60
INTO :any_po
DO
BEGIN
EXCEPTION customer_check;
UPDATE customer
SET on_hold = "*"
WHERE cust_no = :cust_no;
SUSPEND;
END
UPDATE sales
SET order_status = "shipped", ship_date = 'NOW'
WHERE po_number = :po_num;
SUSPEND;
END
Parameters:
PO_NUM INPUT CHAR(8)
該過程只帶有一個輸入?yún)?shù):PO_NUM,類型是CHAR(8)。
在客戶端使用該過程的TStoreProc部件是ShipOrderProc,其主要屬性如下表:
表18.19 ShipOrderProc部件主要屬性的取值
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
屬性名 屬 性 值
────────────────────────────
DatabaseName EmployeeDemoDB
ParamBindMode pbByName
Params PO_NUM(輸入?yún)?shù),String類型)
StoredProcName SHIP_ORDER
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
客戶端執(zhí)行SHIP_ORDER的程序如下:
procedure TFrmExecProc.BtnShipOrderClick(Sender: TObject);
begin
with DmEmployee do
begin
ShipOrderProc.Params[0].AsString := SalesTable['PO_NUMBER'];
ShipOrderProc.ExecProc;
SalesTable.Refresh;
end;
end;
當用戶按ShipOrder按鈕時,執(zhí)行這段程序。程序中先準備輸入?yún)?shù),用ExecProc方
法執(zhí)行存儲過程。調(diào)用SalesTable.Refresh方法刷新數(shù)據(jù)顯示。
在CSDEMO應(yīng)用程序中另一個使用存儲過程的TStoredProc部件是DeleteEmployeeProc。它完成的任務(wù)是刪除Employee表中的記錄,并修改所有相關(guān)的表, 以維護數(shù)據(jù)的一致性。其屬性如下:
表18.20 DeleteEmployeeProc部件主要屬性的取值
━━━━━━━━━━━━━━━━━━━━━━━━━━
屬性名 屬 性 值
──────────────────────────
DataBaseName EmployeeDemoDB
ParamBindMode PbByName
Params EMP_NUM(輸入?yún)?shù),整型)
StoredProcName DELETE_EMPLOYEE
━━━━━━━━━━━━━━━━━━━━━━━━━━
存儲過程DELETE_EMPLOYEE的程序如下:
PROCEDURE DELETE_EMPLOYEE
DECLARE VARIABLE any_sales INTEGER;
BEGIN
any_sales = 0;
SELECT count(po_number)
FROM sales
WHERE sales_rep = :emp_num
INTO :any_sales;
IF (any_sales > 0) THEN
BEGIN
EXCEPTION reassign_sales;
SUSPEND;
END
UPDATE department
SET mngr_no = NULL
WHERE mngr_no = :emp_num;
UPDATE project
SET team_leader = NULL
WHERE team_leader = :emp_num;
DELETE FROM employee_project
WHERE emp_no = :emp_num;
DELETE FROM salary_history
WHERE emp_no = :emp_num;
DELETE FROM employee
WHERE emp_no = :emp_num;
SUSPEND;
END
Parameters:
EMP_NUM INPUT INTEGER
從上述存儲過程的例子中,我們看到存儲過程在維護服務(wù)器上的數(shù)據(jù)一致性方面有很強的能力,它節(jié)省了系統(tǒng)開銷,提高了客戶端的性能。
18.4.2.5 事務(wù)控制編程
在客戶/服務(wù)器應(yīng)用程序中,事務(wù)控制是一項很重要的技術(shù)。它對于提高系統(tǒng)的可靠性,維護數(shù)據(jù)一致性有著重要的意義。
Delphi中提供了事務(wù)的隱式和顯式兩種控制方法。其中顯式控制的性能較高,下面介紹Delphi事務(wù)顯式控制的編程方法。
Delphi擔(dān)當事務(wù)控制任務(wù)的部件是TDatabase 。TDatabase 用于事務(wù)控制的屬性是TransIsolation,方法有StartTranstion、Commit和Rollback。關(guān)于這些屬性和方法作用和使用方法請參閱客戶/服務(wù)器事務(wù)管理。
在CSDEMO中TDatabase 部件為EMployeeDatabase,其TransIsolation屬性值為tiReadCommitted,意為如果存在多個同時事務(wù)訪問數(shù)據(jù)庫,則其中任一事務(wù)只能讀其它事務(wù)提交的了數(shù)據(jù)。
CSDEMO中演示事務(wù)控制的窗體是TFrmTransDemo。
DBGrid1中顯示EmployeeTable中的內(nèi)容。當窗口顯示時,EmployeeDatabase開始一次事務(wù)控制并激活EmployeeTable:
procedure TFrmTransDemo.FormShow(Sender: TObject);
begin
DmEmployee.EmployeeDatabase.StartTransaction;
DmEmployee.EmployeeTable.Open;
end;
當窗口被關(guān)閉或隱藏時,EmployeeDatabase提交事務(wù):
procedure TFrmTransDemo.FormHide(Sender: TObject);
begin
DmEmployee.EmployeeDatabase.Commit;
end;
窗口中有兩個按鈕BtnCommitEdits和BtnUndoEdits。按下BtnCommitEdits按鈕將提交當前事務(wù),并開始新的事務(wù)控制并刷新數(shù)據(jù)。
procedure TFrmTransDemo.BtnCommitEditsClick(Sender: TObject);
begin
if DmEmployee.EmployeeDatabase.InTransaction and
(MessageDlg('Are you sure you want to commit your changes?',
mtConfirmation, [mbYes, mbNo], 0) = mrYes) then
begin
DmEmployee.EmployeeDatabase.Commit;
DmEmployee.EmployeeDatabase.StartTransaction;
DmEmployee.EmployeeTable.Refresh;
end else
MessageDlg('Can''t Commit Changes: No Transaction Active', mtError, [mbOk], 0);
end;
按下BtnUndoEdits按鈕將返轉(zhuǎn)當前事物,恢復(fù)原來的數(shù)據(jù),開始新的事務(wù)控制,并刷新數(shù)據(jù)的顯示。
procedure TFrmTransDemo.BtnUndoEditsClick(Sender: TObject);
begin
if DmEmployee.EmployeeDatabase.InTransaction and
(MessageDlg('Are you sure you want to undo all changes made during the ' +
'current transaction?', mtConfirmation, [mbYes, mbNo], 0) = mrYes) then
begin
DmEmployee.EmployeeDatabase.Rollback;
DmEmployee.EmployeeDatabase.StartTransaction;
DmEmployee.EmployeeTable.Refresh;
end else
MessageDlg('Can''t Undo Edits: No Transaction Active', mtError, [mbOk], 0);
end;
相關(guān)推薦:2010年9月計算機等級考試試題及答案解析專題北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內(nèi)蒙古 |