線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1484
推到 Plurk!
推到 Facebook!

用Delphi的Tquery控制項充分發揮資料庫系統SQL功能

 
jackkcg
站務副站長


發表:891
回覆:1050
積分:848
註冊:2002-03-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-10-25 12:44:04 IP:61.221.xxx.xxx 未訂閱
此為轉貼資料 用Delphi的Tquery控制項充分發揮資料庫系統SQL功能 綜觀現有的RAD工具——Microsoft的Visual Basic、Sybase的PowerBuilder及Inprise的Delphi,它們都提供了相應的資料庫控制項。軟體發展人員利用這些控制項可以有效、方便地實施資料庫編程,但編寫高效及功能強大的資料庫應用軟體應該直接、動態地利用資料庫管理系統的SQL功能。 下例的程式是在Delphi 4.0上開發的一個相對簡單的人事管理軟體的一部分,它能夠滿足複雜的動態查詢、條件列印,實現全活動的工資欄位管理和複雜計算功能。 Delphi訪問資料庫,一般通過Borland資料庫引驚(BDE,Borland DataBase Engine),通過BDE可以訪問客戶機/伺服器資料庫,如Microsoft SQL、Oracle、Sybase、DB2等,及本地資料庫,如Access、Paradox、dBase等。本例採用的資料庫是Sybase SQL Anywhere5.0。但應該指出的是,由於各個資料庫系統的功能不一樣,在編程考慮軟體移植性的時候應注意使用標準isql,還要利用當前資料庫的特殊功能。 在Delphi裏,可以直接發揮資料庫SQL語句功能的控制項除了Tquery,還有TupdateSQL、TstoredSQL等,利用這些控制項可以實現查詢、計算外,還可以建立、修改資料庫表等等。本文以Delphi的Tquery控制項?例,通過下面兩段程式實現動態查詢、複雜計算的方法,闡述資料庫編程應充分發揮資料庫系統功能這一概念。 程式中用到的兩個控制項說明: * Tquery控制項:name屬性?DynamicQuery,如果用以查詢,RequestLive屬性?False,如果用以更改則要求RequestLive屬性?True。 * TdataSource控制項:name屬性?DynamicSource,DataSet屬性?DynamicQuery。 一、 動態查詢的實現 圖一 {下面程式是“執行查詢”按鈕被按下後的回應程式。它首先根據上圖複合條件對話方塊生成的條件生成複雜的連接兩表的SQL語句,然後利用Tquery控制項將結果回應在顯示視窗上。生成列印報表原理也一樣} procedure TMainFrm.ExcuteQueryBtnClick(Sender: TObject); var condition:String; begin { MergeConditionDlg就是上圖所示的對話方塊} if MergeConditionDlg.ShowModal = mrOK then begin { MainCondition.Text?上圖“編輯主設限條件”顯示的內容} if MergeConditionDlg.MainCondition.Text = '' then begin { SubCondition.Text?上圖進入“子條件構造”對話方塊生成的內容 } if MergeConditionDlg.SubCondition.Text = '' then condition := '' else condition := '身份證 IN (SELECT 身份證 FROM 人員基本情況 WHERE ' MergeConditionDlg.SubCondition.Text ') '; end else begin if MergeConditionDlg.SubCondition.Text = '' then condition := MergeConditionDlg.MainCondition.Text else condition := '(' MergeConditionDlg.MainCondition.Text ') AND (身份證 IN (SELECT 身份證 FROM 人員基本情況 WHERE ' MergeConditionDlg.SubCondition.Text ')) '; end; with DataFrm do begin DynamicQuery.Close; DynamicQuery.SQL.Clear; DynamicQuery.SQL.Add('SELECT * FROM gzdaView '); if (condition〈〉 '') then DynamicQuery.SQL.Add('WHERE 身份證 IN (SELECT 身份證 FROM 人員基本情況 WHERE ' condition ') '); DynamicQuery.SQL.Add(' ORDER BY 單位編號,部門編號,行政級別編號,工作時間,出生日期,發放日期'); DynamicQuery.Open; {DbgridDlg對話方塊根據DBGrid資料源的不同顯示不同的結果} DBgridDlg.DBGrid.DataSource := DataFrm.DynamicSource; if DBgridDlg.ShowModal = mrOK then begin Tryjbqk.DisableControls; Tryjbqk.Locate('身份證',DynamicQuery.FieldByName('身份證').Value,[]); Tryjbqk.EnableControls; end; end; end; end; 二、動態計算、修改資料庫記錄的實現 圖二 {下面的過程是在用戶按下“?生複合條件”按鈕後執行的,它的任務是調用生成複 合條件的對話方塊,並將結果返回給工資項計算定義表(下面有解釋)的SubQuery欄位, 並顯示到如圖上“#3> =0”顯示的Memo框上 } procedure TGzxFzjsDlg.GeneratingComplexBtnClick(Sender: TObject); begin { 調用生成複雜運算式的對話方塊,即(一)圖 所示的對話方塊 } if MergeConditionDlg.ShowModal = mrOK then begin { Tgzxjs ? Class(Ttable),是一個存放工資項欄位計算運算式的表, 它由gzx(對應工資表中的工資項)、bh(計算定義的編號,同時也決定批量計算的順序 )、isCurrent(在批量處理時是否被計算)、SingleExp(簡單的計算運算式,實際的 運算式由於在該版本的Delphi中不能正常處理Text欄位,而以文件形式被存放在硬碟上)、 SubQuery(執行的限制條件,即該項定義的計算只對符合條件的工資表記錄進行計算) 等5欄位組成,該表的SubQuery欄位被修改後,自動調用一個過程,將對應的計算運算式 刪除 } DataFrm.Tgzxjs.Edit; if MergeConditionDlg.MainCondition.Text = '' then begin if MergeConditionDlg.SubCondition.Text = '' then DataFrm.TgzxjsSubQuery.AsString := '' else DataFrm.TgzxjsSubQuery.AsString := '身份證 IN (SELECT 身份證 FROM 人員基 本情況 WHERE ' MergeConditionDlg.SubCondition.Text ') '; end else begin if MergeConditionDlg.SubCondition.Text = '' then DataFrm.TgzxjsSubQuery.AsString := MergeConditionDlg.MainCondition.Text else DataFrm.TgzxjsSubQuery.AsString := '(' MergeConditionDlg.MainCondition.Text ') AND (身份證 IN (SELECT 身份證 FROM 人員基本情況 WHERE ' MergeConditionDlg.SubCondition.Text ')) '; end; end; end; {下面的過程是在用戶按下“加單一工資項值運算式”按鈕後執行的, 它的任務是調用標準的輸入的對話方塊,並將用戶輸入的簡單算術運算式加到工資項計算表 達式上} procedure TGzxFzjsDlg.AddSingleExpClick(Sender: TObject); var InputValue :String; begin InputValue := InputBox('工資項值運算運算式輸入框','#1,#2--#40、數位、 運算符組成,如#3、(#3 #8)*0.15、#4-#6 #40 18等等:',''); DataFrm.Tgzxjs.Edit; GzxFzjsDlg.Expression.Text := GzxFzjsDlg.Expression.Text InputValue; DataFrm.TgzxjsSingleExp.Value := DataFrm.TgzxjsSingleExp.Value InputValue; DataFrm.Tgzxjs.Post; end; {下面的過程是在用戶按下“清空計算運算式”按鈕後執行的,它的任務是計算表達 式清空} procedure TGzxFzjsDlg.SpeedButton4Click(Sender: TObject); begin DataFrm.Tgzxjs.Edit; GzxFzjsDlg.Expression.Text := ''; DataFrm.TgzxjsSingleExp.AsString := ''; DataFrm.Tgzxjs.Post; end; {下面的過程是在用戶按下“加合計函數運算式”按鈕後執行的,它的任務是調用生 成合計函數運算式的的SUMExpressionDlg對話方塊,這裏使用的合計函數有合計值(SUM) 、平均值(AVG)、最大值(MAX)、最小值(MIN)、記錄數(COUNT)等5種,並將結果 加到計算運算式} procedure TGzxFzjsDlg.AddSumExpClick(Sender: TObject); begin with SUMExpressionDlg do begin if ShowModal = mrOK then begin DataFrm.Tgzxjs.Edit; case CalStyle.ItemIndex of {CalStyle是包括上述5種合計運算式的選項控制項} 0: //即SUM begin GzxFzjsDlg.Expression.Text := GzxFzjsDlg.Expression.Text '(SELECT SUM(' SumExpression.Text ') FROM 工資表 WHERE ' DataFrm.TgzxjsSubQuery.AsString ')'; DataFrm.TgzxjsSingleExp.AsString := DataFrm.TgzxjsSingleExp.AsString 'SUM(' SumExpression.Text ')'; end; 1: //即AVG begin GzxFzjsDlg.Expression.Text := GzxFzjsDlg.Expression.Text '(SELECT AVG(' SumExpression.Text ') FROM 工資表 WHERE ' DataFrm.TgzxjsSubQuery.AsString ')'; DataFrm.TgzxjsSingleExp.AsString := DataFrm.TgzxjsSingleExp.AsString 'AVG(' SumExpression.Text ')'; end; 2: //即MAX begin GzxFzjsDlg.Expression.Text := GzxFzjsDlg.Expression.Text '(SELECT MAX(' SumExpression.Text ') FROM 工資表 WHERE ' DataFrm.TgzxjsSubQuery.AsString ')'; DataFrm.TgzxjsSingleExp.AsString := DataFrm.TgzxjsSingleExp.AsString 'MAX(' SumExpression.Text ')'; end; 3: //即MIN begin GzxFzjsDlg.Expression.Text := GzxFzjsDlg.Expression.Text '(SELECT MIN(' SumExpression.Text ') FROM 工資表 WHERE ' DataFrm.TgzxjsSubQuery.AsString ')'; DataFrm.TgzxjsSingleExp.AsString := DataFrm.TgzxjsSingleExp.AsString 'MIN(' SumExpression.Text ')'; end; 4: //即COUNT begin GzxFzjsDlg.Expression.Text := GzxFzjsDlg.Expression.Text '(SELECT COUNT(' SumExpression.Text ') FROM 工資表 WHERE ' DataFrm.TgzxjsSubQuery.AsString ')'; DataFrm.TgzxjsSingleExp.AsString := DataFrm.TgzxjsSingleExp.AsString 'COUNT(' SumExpression.Text ')'; end; end; DataFrm.Tgzxjs.Post; end; end; end; {下面過程通過回應雙擊滑鼠將對應的算術運算符 、-、X、/、(、)加到計算表 達式 } procedure TGzxFzjsDlg.AddOperationalCharacterDblClick(Sender: TObject); begin DataFrm.Tgzxjs.Edit; GzxFzjsDlg.Expression.Text := GzxFzjsDlg.Expression.Text ListBox2.Items[ListBox2.ItemIndex]; DataFrm.TgzxjsSingleExp.AsString := DataFrm.TgzxjsSingleExp.AsString ListBox2.Items[ListBox2.ItemIndex]; DataFrm.Tgzxjs.Post; end; {下面的過程是在用戶按下“執行當前工資項計算”按鈕後執行的,它的任務是對話 框顯示的被定義工資項,對工資表中的該欄位根據條件運算式和計算運算式進行重新計 算} procedure TGzxFzjsDlg.OKBtnClick(Sender: TObject); begin if DataFrm.Sgzxjs.State IN [dsEdit,dsInsert] then ShowMessage('記錄正在編輯或插入狀態,現退回!') else begin if Data.Confirm('真的需要根據條件和運算式對工資項 ' DataFrm.TgzxjsGzx.Value ' 執行工資項賦值嗎?') then begin MyPromptFrm.Show; //顯示進度和圖片 MyPromptFrm.Update; try DataFrm.DynamicQuery.Close; DataFrm.DynamicQuery.SQL.Clear; DataFrm.DynamicQuery.SQL.Add('UPDATE 工資表 SET ' DataFrm.TgzxjsGzx.Value ' = ' GzxFzjsDlg.Expression.Text); if DataFrm.TgzxjsSubQuery.AsString 〈〉 '' then DataFrm.DynamicQuery.SQL.Add(' Where ' DataFrm.TgzxjsSubQuery.AsString) ; DataFrm.DynamicQuery.ExecSQL; finally MyPromptFrm.Close; end; DataFrm.Tgz.Refresh; end; end; end; {下面的過程是在用戶按下“執行批量計算”按鈕後執行的,它的任務是對工資項 計算定義表中所定義的、並且批量處理標誌?真的所有工資欄位根據批量處理順序、 條件運算式和計算運算式進行重新計算} procedure TGzxFzjsDlg.Button1Click(Sender: TObject); begin if DataFrm.Sgzxjs.State IN [dsEdit,dsInsert] then ShowMessage('記錄正在編輯或插入狀態,現退回!') else begin if Data.Confirm('真的需要執行批量工資項賦值嗎?') then begin MyPromptFrm.Show; MyPromptFrm.Update; try DataFrm.Tgzxjs.First; while not DataFrm.Tgzxjs.Eof do begin if DataFrm.TgzxjsIsCurrent.Value = 1 then begin DataFrm.DynamicQuery.Close; DataFrm.DynamicQuery.SQL.Clear; DataFrm.DynamicQuery.SQL.Add('UPDATE 工資表 SET ' DataFrm.TgzxjsGzx.Value ' = ' GzxFzjsDlg.Expression.Text); if DataFrm.TgzxjsSubQuery.AsString 〈〉 '' then DataFrm.DynamicQuery.SQL.Add(' Where ' DataFrm.TgzxjsSubQuery.AsString) ; DataFrm.DynamicQuery.ExecSQL; end; if DataFrm.TgzxjsGzx.Value = '#37' then Gz.JsSds; DataFrm.Tgzxjs.Next; end; finally MyPromptFrm.Close; end; DataFrm.Tgz.Refresh; end; end; end; end.
------
**********************************************************
哈哈&兵燹
最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好

Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知
K.表Knowlege 知識,就是本站的標語:Open our mind
系統時間:2024-05-15 7:17:00
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!