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

如何恢复已被变更的数据?

尚未結案
zzmbeyond01
中階會員


發表:98
回覆:167
積分:53
註冊:2003-09-07

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-12-18 02:13:37 IP:222.183.xxx.xxx 未訂閱
各位大大好: 请问如何恢复已被变更的数据呢,比如我执行了删除、修改、插入等操作,现在想恢复或恢复到到某次操作(10次变更以内)时候的值,就像word一样
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-12-18 03:15:19 IP:61.71.xxx.xxx 未訂閱
引言: 各位大大好: 请问如何恢复已被变更的数据呢,比如我执行了删除、修改、插入等操作,现在想恢复或恢复到到某次操作(10次变更以内)时候的值,就像word一样
利用一個資料庫, 記錄每次異動前的記錄, 這樣就可以還原了!
zzmbeyond01
中階會員


發表:98
回覆:167
積分:53
註冊:2003-09-07

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-12-18 11:27:18 IP:222.183.xxx.xxx 未訂閱
这样的话就要求每个表都要创建一个对应的存储变更记录的表??那是不是数据库有些太大了? 有没有更好些的方法,有没有例子呢? 谢谢您的热心!
elvis1000
一般會員


發表:6
回覆:50
積分:16
註冊:2004-12-18

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-12-18 17:23:18 IP:218.165.xxx.xxx 未訂閱
你可以把所有的動作都變成數據紀錄起來。例如: 增加用「1」代表,刪除用「2」代表,修改用「3」代表。 修改第5筆「名稱」為「xxx」可記為(3,5,1,'xxx') Type TDo=record act:integer; RecNo:integer; FieldNo:integer; Memo1,Memo2,memo3:string[10]; end; PDo=^TDo; Var DoWhat:array[0..99] of PDo; 這樣這可以記錄了,或者你也可以用堆疊的。 ----------------------- God bless you! I am Dark_Angel.
------
-----------------------
God bless you!
I am Dark_Angel.
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-12-18 18:30:46 IP:61.71.xxx.xxx 未訂閱
引言: 利用一個資料庫, 記錄每次異動前的記錄, 這樣就可以還原了!
其實不會, 針對你想要有復原功能的資料庫產生一個對應的資料庫, 建議你可 以用 midas 的 cds結構(即clientdataset), 速度快, 如果怕大太, 因為你提 到回復10次內, 那可以儲存時如果第11筆加入就刪除第1筆, 這樣不就可以永遠 保持10筆以內了!
elvis1000
一般會員


發表:6
回覆:50
積分:16
註冊:2004-12-18

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-12-18 18:42:36 IP:218.165.xxx.xxx 未訂閱
你這麼說,我突然又想到一個方法! 可以利用clientDataSet當作是變更的紀錄資料庫! field 1: RecNo field 2: 變更的動作編號 field 3: 變更的欄位編號 field 4: 變更的欄位值 ----------------------- God bless you! I am Dark_Angel.
------
-----------------------
God bless you!
I am Dark_Angel.
zzmbeyond01
中階會員


發表:98
回覆:167
積分:53
註冊:2003-09-07

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-12-18 23:11:33 IP:222.183.xxx.xxx 未訂閱
引言: 你這麼說,我突然又想到一個方法! 可以利用clientDataSet當作是變更的紀錄資料庫! field 1: RecNo field 2: 變更的動作編號 field 3: 變更的欄位編號 field 4: 變更的欄位值 ----------------------- God bless you! I am Dark_Angel.
大大的方法需要我好好想想,但是我全都用的adodataset数据集作的。
elvis1000
一般會員


發表:6
回覆:50
積分:16
註冊:2004-12-18

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-12-19 00:49:51 IP:218.165.xxx.xxx 未訂閱
使用此法,應該只要是dataset都可以記錄! ----------------------- God bless you! I am Dark_Angel.
------
-----------------------
God bless you!
I am Dark_Angel.
zzmbeyond01
中階會員


發表:98
回覆:167
積分:53
註冊:2003-09-07

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-12-19 13:13:06 IP:222.183.xxx.xxx 未訂閱
引言: 使用此法,應該只要是dataset都可以記錄! ----------------------- God bless you! I am Dark_Angel.
大大可以用数据库的保存点savepoint来实现吗?
elvis1000
一般會員


發表:6
回覆:50
積分:16
註冊:2004-12-18

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-12-19 13:38:23 IP:220.134.xxx.xxx 未訂閱
說起來簡單,做起來很難。如果要記錄動作,就必須監控整個功能按鍵的變化,一開始可能要加入一些監控的變數,例如:
Var
  DoWhat:integer; // 用來記錄動作的類別 
  IsDoing:boolean;  //正在動作
如果要記錄新動作,就先存舊動作。 動作的監控,就落在onClick & OnDataChange上了! 這只是初步構想,應該要實做,才能發現還有什麼問題! ----------------------- God bless you! I am Dark_Angel.
------
-----------------------
God bless you!
I am Dark_Angel.
zzmbeyond01
中階會員


發表:98
回覆:167
積分:53
註冊:2003-09-07

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-12-19 14:25:56 IP:222.183.xxx.xxx 未訂閱
大大帮看看思路对不对: (1) 在数据库创建一个表tmp field 1: RecNo field 2: 變更的動作編號 field 3: 變更的欄位編號 field 4: 變更的欄位值 field 5: 变更的表名 (2) 设置tmpdataset与该表连接,相关字段: field 1: RecNo field 2: 變更的動作編號 field 3: 變更的欄位編號 field 4: 變更的欄位值 这应该用个栏位数组吧,比如一次更改一条记录的好几个字段怎么办 field 5: 变更的表名 (3)在修改的数据集dataset的每个字段的ondatachange事件中将原数据和对应字段的值填入dataset1 (4) 回退操作: if update 更新对应字段的值 if insert 则删除插入的值 if del 则插入对应的值
elvis1000
一般會員


發表:6
回覆:50
積分:16
註冊:2004-12-18

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-12-19 14:51:39 IP:220.134.xxx.xxx 未訂閱
經過一番實驗,已經達成下列功能: 1. 抓到按鍵改變 2. 抓到資料編輯的值(雖然是編輯後的值,編輯前的值應該不難) 3. 記錄下動作 (暫時記錄在ListBox)    
unit MainU;    interface    uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  MyLib, Grids, DBGrids, ExtCtrls, DB, DBClient, Buttons, StdCtrls;    type
  TMainForm = class(TForm)
    Table: TClientDataSet;
    DataSource: TDataSource;
    Panel1: TPanel;
    DBGrid: TDBGrid;
    BuAdd: TSpeedButton;
    BuDel: TSpeedButton;
    Panel2: TPanel;
    ListBox: TListBox;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure BuAddClick(Sender: TObject);
    procedure BuDelClick(Sender: TObject);
    procedure DataSourceStateChange(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure SaveAct;
  end;    type
  TAct=(aNone,aAdd,aDel,aModify);
  TState=(sNone,sDoing,sSave);
  TActRec=Record
    ActKind:TAct;
    RecNo:integer;
    Field:string[20];
    memo:string[20];
  end;    var
  MainForm: TMainForm;    Const
  MyName='Elvis Tsai';
  MyCoName='Dark Angel';
  ProgName='Test';    Var
  ProgPath, TempPath:string;
  Act:TAct;
  State:TState;
  ActRec:TActRec;    implementation    {$R *.DFM}    procedure TMainForm.FormCreate(Sender: TObject);
begin
  Application.Title:=ProgName;
  ProgPath:=ExtractFilePath(Application.ExeName);
  TempPath:=GetTemporaryPath;
  //OBJ
  //Const
  Act:=aNone;
  State:=sNone;
  ListBox.Clear;
  //Others
  Table.LoadFromFile('Data.cds');
end;    procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  //OBJ
  //Others
  //Table.SaveToFile('Data.cds');
end;    procedure TMainForm.BuAddClick(Sender: TObject);
begin
  //Save Old
  if State<>sNone then SaveAct;
  //Do Insert
  State:=sDoing;
  Act:=aAdd;
  Table.Insert;
  Table.FieldByName('RecNo').AsInteger:=Table.RecordCount 1;
  Table.UpdateRecord;
  ActRec.ActKind:=Act;
  ActRec.RecNo:=Table.FieldByName('RecNo').AsInteger;
  ActRec.Field:='-';
  ActRec.memo:='-';
  //Save Old
  SaveAct;
  State:=sNone;
 Act:=aNone;
end;    procedure TMainForm.SaveAct;
var
  s:string;
begin
  s:='';
  case Act of
    aNone:
      begin
        s:='0,-,-';
      end;
    aAdd:
      begin
        s:='1,' intToStr(ActRec.RecNo) ',' ActRec.Field ',' ActRec.memo;
      end;
    aDel:
      begin
        s:='2,' intToStr(ActRec.RecNo) ',' ActRec.Field ',' ActRec.memo;
      end;
    aModify:
      begin
        s:='3,' intToStr(ActRec.RecNo) ',' ActRec.Field ',' ActRec.memo;
      end;
  end;//case
  ListBox.Items.Add(s);
  State:=sNone;
  Act:=aNone;
end;    procedure TMainForm.BuDelClick(Sender: TObject);
begin
  //Save Old
  if State<>sNone then SaveAct;
  //Do Insert
  State:=sDoing;
  Act:=aDel;
  ActRec.ActKind:=Act;
  ActRec.RecNo:=Table.FieldByName('RecNo').AsInteger;
  ActRec.Field:=Table.FieldByName('Name').DisplayName;
  ActRec.memo:=Table.FieldByName('Name').AsString;;
  Table.Delete;
  //Save Old
  SaveAct;
  State:=sNone;
  Act:=aNone;
end;    procedure TMainForm.DataSourceStateChange(Sender: TObject);
begin
  if (State=sNone) and (Table.State=dsEdit) then
    begin
      State:=sDoing;
      Act:=aModify;
      ActRec.ActKind:=Act;
      ActRec.RecNo:=Table.FieldByName('RecNo').AsInteger;
      ActRec.Field:=DbGrid.SelectedField.DisplayName;
      ActRec.memo:=DbGrid.SelectedField.AsString;
      SaveAct;
    end;//if
end;    end.
----------------------- God bless you! I am Dark_Angel.
------
-----------------------
God bless you!
I am Dark_Angel.
elvis1000
一般會員


發表:6
回覆:50
積分:16
註冊:2004-12-18

發送簡訊給我
#13 引用回覆 回覆 發表時間:2004-12-19 15:02:59 IP:220.134.xxx.xxx 未訂閱
我剛剛上面說錯了!其實已經抓到變動前的資料了。 簡單說:就是完全成功了 ----------------------- God bless you! I am Dark_Angel.
------
-----------------------
God bless you!
I am Dark_Angel.
zzmbeyond01
中階會員


發表:98
回覆:167
積分:53
註冊:2003-09-07

發送簡訊給我
#14 引用回覆 回覆 發表時間:2004-12-19 21:58:36 IP:222.183.xxx.xxx 未訂閱
多谢elvis1000大大的热心!< >< > 我正在测试
系統時間:2024-11-25 6:58:03
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!