在日常開發中,經常會需要進行數據庫操作,如執行一些 SQL 查詢、或者執行一些 SQL 命令等,如果每次執行操作都按照 Delphi 數據庫操作的步驟一步一步地組織語句去執行的話,又顯得比較繁瑣,所以,有必要對數據庫的操作進行封裝,以便于在進行數據庫操作時,通過簡單地調用即可實現。
在本節中,我們通過 Zeos 的數據庫組件來實現一個簡單的數據庫操作封裝。代碼如下:
unit sqlunit; {$mode ObjFPC}{$H+} interface uses Classes, SysUtils, ZConnection, ZDataset, DB, Dialogs; type TSqlStatment = class private sSql: String; public Query: TZQuery; // 構造函數 Constructor Create(Conn: TZConnection); procedure SetSQL(sql: String); procedure Execute; procedure Open; // 析構函數 Destructor Free; end; implementation Constructor TSqlStatment.Create(Conn: TZConnection); begin Query:=TZQuery.Create(nil); Query.Connection:=Conn; end; procedure TSqlStatment.SetSQL(sql: String); begin // 設置 SQL 語句,可以包含參數 sSql:=sql; try Query.Close; Query.SQL.Clear; Query.SQL.Text := sSql; Query.Prepare; except on E: EDatabaseError do MessageDlg('提示', 'DB ERROR: '+sSql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message, mtInformation, [mbOk], ''); on E: Exception do MessageDlg('提示', 'ERROR: '+sSql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message, mtInformation, [mbOk], ''); end; end; procedure TSqlStatment.Execute; begin // 執行 SQL 語句,適合除 SELECT 語句之外的所有語句 try Query.ExecSQL; except on E: EDatabaseError do MessageDlg('提示', 'DB ERROR: '+sSql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message, mtInformation, [mbOk], ''); on E: Exception do MessageDlg('提示', 'ERROR: '+sSql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message, mtInformation, [mbOk], ''); end; end; procedure TSqlStatment.Open; begin // 執行 SQL 查詢,即 Select 語句 try Query.Open; except on E: EDatabaseError do MessageDlg('提示', 'DB ERROR: '+sSql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message, mtInformation, [mbOk], ''); on E: Exception do MessageDlg('提示', 'ERROR: '+sSql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message, mtInformation, [mbOk], ''); end; end; Destructor TSqlStatment.Free; begin Query.Destroy; end; end.
通過一段更改用戶密碼的操作,來看一下通過 TSqlStatment 實例執行 SQL 語句的調用,代碼如下:
procedure TPasswordForm.OkButtonClick(Sender: TObject); var SqlStatment: TSqlStatment; Salt, SavedPassword, HashPassword: String; begin // 檢查密碼的輸入情況 if Length(OldEdit.Text) <= 0 then begin MessageDlg('提示', '請輸入舊密碼!', mtInformation, [mbOk], ''); Exit; end; if Length(NewEdit.Text) <= 0 then begin MessageDlg('提示', '請輸入新密碼!', mtInformation, [mbOk], ''); Exit; end; if Length(OkEdit.Text) <= 0 then begin MessageDlg('提示', '請輸入確認密碼!', mtInformation, [mbOk], ''); Exit; end; // 檢查舊密碼是否正確 SqlStatment:=TSqlStatment.Create(DBDataModule.DBConnection); SqlStatment.SetSQL('select pwd, salt from c_usrs where usr_id = :USR_ID'); SqlStatment.Query.Params.ParamByName('USR_ID').AsString:=CurrentUser.usr_id; SqlStatment.Open; if SqlStatment.Query.RecordCount <= 0 then begin MessageDlg('提示', '找不到用戶,無法修改密碼!', mtInformation, [mbOk], ''); SqlStatment.Free; Exit; end; SqlStatment.Query.First; Salt:=SqlStatment.Query.FieldByName('salt').AsString; SavedPassword:=SqlStatment.Query.FieldByName('pwd').AsString; HashPassword := MD5Print(MD5String(Salt+OldEdit.Text)); if HashPassword <> SavedPassword then begin MessageDlg('提示', '舊密碼不正確, 請重新設置!', mtInformation, [mbOk], ''); SqlStatment.Free; Exit; end; // 檢查新密碼與確認密碼是否相同,如不相同則提示 if NewEdit.Text <> OkEdit.Text then begin MessageDlg('提示', '新密碼與確認密碼不符, 請重新設置!', mtInformation, [mbOk], ''); Exit; end; // 檢查新密碼與舊密碼是否相同,如相同則沒有必要去修改 if OldEdit.Text = NewEdit.Text then begin MessageDlg('提示', '新密碼與舊密碼相同, 沒有必要修改!', mtInformation, [mbOk], ''); Exit; end; // 產生新的 SALT Salt:=GenGUID; // 計算新密碼的 MD5 值 HashPassword := MD5Print(MD5String(Salt+NewEdit.Text)); // 更改密碼 SqlStatment.SetSQL('update c_usrs set pwd=:PWD, salt=:SALT where usr_id = :USR_ID'); SqlStatment.Query.Params.ParamByName('PWD').AsString:=HashPassword; SqlStatment.Query.Params.ParamByName('SALT').AsString:=Salt; SqlStatment.Query.Params.ParamByName('USR_ID').AsString:=CurrentUser.usr_id; SqlStatment.Execute; SqlStatment.Free; MessageDlg('提示', '密碼已更新!', mtInformation, [mbOk], ''); ModalResult:=mrOk; end;