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

SQL数据库还原代码

答題得分者是:malanlk
ntjrr
高階會員


發表:240
回覆:312
積分:110
註冊:2005-04-24

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-09-06 12:06:33 IP:222.184.xxx.xxx 未訂閱
日前在网上找了一个SQL数据自动备份源程序,试用了一下不错,只可惜少一个还原功能,哪位前辈能看一下源程序,再加个备份功能上去,谢谢!http://delphi.ktop.com.tw/loadfile.php?TOPICID=24396485&CC=545615
------
我的编程起步于ktop,我将永远支持ktop
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-09-07 09:32:22 IP:203.69.xxx.xxx 未訂閱
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/howtosql/ht_7_backpc_61x5.asp ntjrr 兄可以模仿源碼中的 BackupBase, 把 SQL 改為 Sql.Text:='Restore Database ' Trim(CmbDatabaseName.Text) ' from Disk=''' FileName ''' '; 試試看哦...
ntjrr
高階會員


發表:240
回覆:312
積分:110
註冊:2005-04-24

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-09-07 16:18:13 IP:222.184.xxx.xxx 未訂閱
试着将还原的代码都写进去了,但遇到一个问题,执行时提示,因为数据正在使用,所以无法获得排它的访问权”还原也就失败了,如何能解决这问题呢?
------
我的编程起步于ktop,我将永远支持ktop
timhuang
尊榮會員


發表:78
回覆:1815
積分:1608
註冊:2002-07-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-09-07 18:08:48 IP:203.95.xxx.xxx 未訂閱
Hi, 要先將連結在該 database 的 connection 都 kill 掉以取得獨占才能進行 restore, 做法如下,    
use master    declare @spid int, @dbid int, @cmd nvarchar(200)
declare c_processes cursor  for
  select spid, dbid from sysprocesses where dbid = db_id('database_name')
open c_processes    fetch next from c_processes into @spid, @dbid
while @@fetch_status=0
begin
  set @cmd = 'kill ' convert(nvarchar, @spid)
  exec sp_executesql @cmd
  fetch next from c_processes into @spid, @dbid
end    close c_processes
deallocate c_processes    restore database database_name from disk='xxxx.bak'
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-09-07 22:57:58 IP:61.219.xxx.xxx 未訂閱
http://delphi.ktop.com.tw/topic.php?topic_id=77532    借花獻佛...    TFrmBackup 裡面加幾個元件  TADOConnection ==> connAdo_res connAdo_res.DefaultDatabase 設為 'master'; TButton ==> btnRestore TADODataSet ==> ADODataSetWho ADODataSetWho.Connection 設為 'connAdo_res'    
function TFrmBackup.RestoreDB(strDBName,strFileName: string): boolean;
var
  strSQL: string;
begin
  Result := false;
  strSQL := 'RESTORE DATABASE ['   strDBName   '] FROM  DISK = N'''   strFileName   ''' WITH  FILE = 1,  NOUNLOAD ,  STATS = 10,  RECOVERY,  REPLACE';      try
    ADODataSetWho.Recordset := connAdo_res.Execute('sp_who');
    ADODataSetWho.First;
    while not ADODataSetWho.Eof do
    begin
      if ADODataSetWho.FieldByName('dbname').AsString = strDBName then
      begin
        MessageBox(Application.Handle,Pchar('Database '  strDBName  'is in use by '   ADODataSetWho.FieldByName('loginame').AsString   '!'),'Restore Error',MB_OK   MB_ICONERROR);
        Exit;
      end;
      ADODataSetWho.Next;
    end;        connAdo_res.Execute(strSQL);
  except
    MessageBox(Application.Handle,'Restore Database Error!','It Is Error',MB_OK   MB_ICONERROR);
    Exit;
  end;
  Result := true;
end;    procedure TFrmBackup.btnRestordClick(Sender: TObject);
var
  FilePath: String;
begin
  connAdo_res.Close;
  connAdo_res.ConnectionString := 
    'Provider=SQLOLEDB.1;Password=''' Trim(Password.Text) ''';Persist Security Info=True;User ID=''' Trim(UserName.Text) ''';Data Source=''' Trim(ServerName.Text) '''';
  try
    connAdo.Close;
    connAdo_res.Open;
    if connAdo_res.Connected  then
    begin
      if Show=1 then begin
        application.CreateForm(tfrmDlg,frmDlg);
        frmDlg.Show;
      end;
      BackFileName:=Trim(CmbDatabaseName.Text) FormatDateTime('yyyymmddhhmmss',Now);
      if RightStr(EdtPath.text,1)='\' then
        FilePath:=EdtPath.Text
      else
        FilePath:=EdtPath.Text '\';          FilePath:=FilePath BackFileName;          if RestoreDB(Trim(CmbDatabaseName.Text),Trim(FilePath)) then
         MessageBox(handle,'Database Sestore Successfully!','It Is Ok!',mb_ok);
    end;
  except
    on ex:Exception do
      raise Exception.Create('Error:' #13#10 ex.Message);
  end;
  connAdo.Open;
end;
這樣試試, 沒 Debug.... 過 發表人 - malanlk 於 2005/09/07 23:03:31
timhuang
尊榮會員


發表:78
回覆:1815
積分:1608
註冊:2002-07-15

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-09-07 23:14:26 IP:220.132.xxx.xxx 未訂閱
Hi, malanlk 兄, 你貼的這篇是存取權限的解決方法, 並非是 exclusive (獨佔, 或稱排他)的存取, 由於 ntjrr 兄遇到的問題是仍有 connection 存在於他要 restore 的 database, 所以必需先將相關的 connection kill 後, 再行 restore 即可!
ntjrr
高階會員


發表:240
回覆:312
積分:110
註冊:2005-04-24

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-09-08 08:14:21 IP:222.184.xxx.xxx 未訂閱
malanlk前辈,确实如此,执行还原后就会提示数据正在被使用。但timhuang前辈的代码小弟尚未能够理解,也不知道放到哪个地方执行,malanlk前辈的代码拷到我的电脑就好执行了。 發表人 - ntjrr 於 2005/09/08 08:15:02
------
我的编程起步于ktop,我将永远支持ktop
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-09-08 08:41:43 IP:203.69.xxx.xxx 未訂閱
timhuang 大大 的程式要到 Server 端 用Query Analyzer 或 Enterprise Manager 去實現, 如果数据正在被使用, 可以先將所有 Client 端程式停止再去做還原...
timhuang
尊榮會員


發表:78
回覆:1815
積分:1608
註冊:2002-07-15

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-09-08 10:03:39 IP:203.95.xxx.xxx 未訂閱
不一定要用 Query Analyzer 執行啊, 一樣可以在 delphi 中執行啊. 只是 kill 指令的執行權限, 身份需有 sysadmin and processadmin restore database 指令的執行權限, 身份需有 sysadmin and dbcreator 因此要帶著正確的身份執行即可, 一樣利用 TADOQuery 的 SQL.Text 將我寫的那段 code 放進去執行即可, 記得是使用 ExecSQL function 不是 open.
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-09-08 10:18:11 IP:203.69.xxx.xxx 未訂閱
是哦.... 又學ㄧ招... 謝謝 timhuang 大大啦
ntjrr
高階會員


發表:240
回覆:312
積分:110
註冊:2005-04-24

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-09-08 21:51:26 IP:222.184.xxx.xxx 未訂閱
我发现了两个新问题,一是不好在现有数据库上强制还原,就是删掉现有的,就还原正确,如不删掉,就覆盖不掉现有。二,无论是选什么文件,哪怕选一个文本文件,再点还原后,它也会提示还原成功,呵呵!
------
我的编程起步于ktop,我将永远支持ktop
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#12 引用回覆 回覆 發表時間:2005-09-09 00:39:39 IP:61.219.xxx.xxx 未訂閱
1. 之前貼出的程式碼中有一段是 'RESTORE DATABASE [' + strDBName + '] FROM  DISK = N''' + strFileName + ''' WITH FILE = 1, NOUNLOAD , STATS = 10, RECOVERY, REPLACE'; 參考 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_ra-rz_25rm.asp FILE=1 就是說, 還原檔有一個, 你本來就只有1個檔, 所以可以拿掉 NOUNLAD 沒用, 可以拿掉 (由磁帶還原才有用) STATS=10 每還原 10% 更新進度表, 因為是透過 Query 下指令, 所以也沒用 RECOVERY 還原後將所有尚未COMMIT 的 交易 RollBack, 是預設值, 所以也可以不加 REPLACE 這就是關鍵了... 會將已存在同名的 Database 刪除, 另存新的..... 所以可以在 timhuang 大大那段最後加上 '... with replace' 蓋掉原資料庫... 2. 應該是 這個Query沒有回應, 所以無法判斷是否執行成功 發表人 - malanlk 於 2005/09/09 00:43:36
ntjrr
高階會員


發表:240
回覆:312
積分:110
註冊:2005-04-24

發送簡訊給我
#13 引用回覆 回覆 發表時間:2005-09-09 07:04:09 IP:222.184.xxx.xxx 未訂閱
本问题是由timhuang大大指点了关键之处,由malanlk大大花费了大量时间一步一步帮助我一起调试好的。不知道网站能否有个一次能给多人分的的功能。
------
我的编程起步于ktop,我将永远支持ktop
系統時間:2024-06-24 20:16:57
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!