四百分全给!请大家多多关注!很急呀!! (200分)

  • 主题发起人 thefirstdz
  • 开始时间
T

thefirstdz

Unregistered / Unconfirmed
GUEST, unregistred user!
代码:
[:)] var
s,s1,s2,s3,s4:string;
begin
    openDialog1.Execute;
if OpenDialog1.FileName <> '' then
begin
s3:=OpenDialog1.FileName;
s4:=trim(Form1.ComboBox1.Text);
s:='restore database '+s4+' from disk='''+s3+'''';
s1:='with move '+s4+' to 'c:/Data/'''+s4+'.mdf',';
s2:='move '+s4+'_log to 'c:/Data/'''+s4+'_log.ldf'';
    query1.SQL.Clear;
query1.SQL.Add(s);
query1.SQL.Add(s1);
query1.SQL.Add(s2);
query1.ExecSQL;
query1.Close;
showmessage('您已经成功恢复!');
end;
运行不了请问什么地方出错了?
 
一定是引号出错了,你在query.ExecSQL之前用
showmessage看看SQL的内容,确定有没有错误
 
对呀,是引号错了,可是怎么改呀,我怎么改都还是错!!
 
加断点或单步调试运行(F7),并跟踪监视变量s,s1,s2,s3,s4[red]和Query1.Sql.text[/red]。
方法:
Run->Add watch->在"expression"中填入"s"->回车确认->右键点"Watch list"窗口,选"Add watch"
加第二个跟踪变量s1->依次类推,把4个变量都加到"Watch List"->为了观察方便,建议点右键选
"Stay On top",让窗口始终在上。
 
'''+s3+'''';
 
s:='restore database '+s4+' from disk='+QuotedStr(s3);
s1:=' with move '+s4+' to '+QuotedStr('c:/Data/'+s4+'.mdf,');
s2:='move '+s4+'_log to '+QuotedStr('c:/Data/'+s4+'_log.ldf');
 
可以运行但出现General SQL error 这个错误
 
function TForm1.ReadSqlPath:string;
var
Reg: TRegistry;
begin
Result:='';
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
try
//从注册表中取参数
if Reg.OpenKey('/Software/microsoft/mssqlserver/setup',True) then
begin
Result:=Reg.ReadString('sqlpath');
end;
except
//取参数出错
Result:='';
end;
finally
Reg.CloseKey;
Reg.Free;
end;
end;
下面用到的strSqlPath是上面函数的返回值
procedure TForm1.RestoreDatabase(a_edt:TEdit;a_strDatabase:string);
var
bError:boolean;
strDataName,
strLogName:string;
begin
bError:=False;
AddLog(Log,'开始处理'+a_strDatabase+'任务',clBlack);
if FileExists(a_edt.text) then
begin
AddLog(Log,a_strDatabase+'数据库文件存在,开始取文件信息',clBlack);
end
else
begin
AddLog(Log,a_strDatabase+'数据库文件不存在,请重新选择',clRed);
bError:=True;
end;
if not bError then
begin
Query.Close;
Query.SQL.Clear;
Query.SQL.Add('restore FileListOnly from disk='+
QuotedStr(a_edt.text));
try
Query.Open;
except
bError:=True;
AddLog(Log,'恢复'+a_strDatabase+'数据库失败,请检查文件是否正确,再重试',clRed);
Application.ProcessMessages;
end;
if not bError then
begin
strDataName:=Query.FieldByName('LogicalName').asstring;
Query.Next;
strLogName:=Query.FieldByName('LogicalName').asstring;
AddLog(Log,'取文件信息成功,开始恢复数据库,请稍候。。。',clBlack);
Application.ProcessMessages;
Query.Close;
Query.SQL.Clear;
Query.SQL.Add('restore database '+a_strDatabase+' from disk='+
QuotedStr(a_edt.text)+
' with move '+QuotedStr(strDataName)+
' to '+Quotedstr(strSqlPath+'/data/'+a_strDatabase+'.mdf')+
',move '+QuotedStr(strLogName)+
' to '+QuotedStr(strSqlPath+'/data/'+a_strDatabase+'.ldf')+','+
'replace');
try
Query.ExecSQL;
except
bError:=True;
AddLog(Log,'恢复'+a_strDatabase+'数据库失败,请检查文件是否正确,再重试',clRed);
Application.ProcessMessages;
end;
end;
if Not bError then
AddLog(Log,'恢复'+a_strDatabase+'数据库成功',clBlue);
Application.ProcessMessages;
end;
AddLog(Log,'********************',clGreen);
Application.ProcessMessages;
end;
 
改成下面这样应该就行了:
s3:=OpenDialog1.FileName;
s4:=trim(Form1.ComboBox1.Text);
s:='restore database '+s4+' from disk="'+s3+'"';
s1:='with move '+s4+' to '"c:/Data/'+s4+'.mdf",';
s2:='move '+s4+'_log to '"c:/Data/'+s4+'_log.ldf"';
 
引号的问题,多使用QuotedStr,就不用考虑SQL语句中的引号了
 
跟踪是最好的办法,尤其是跟踪到最后执行之前SQL语句是什么样的。
 
因为数据库正在使用,所以未能获得对数据库的排它访问权,
  这怎么做呀!先断开SQL数据库吗?
 
>>未能获得对数据库的排它访问权
要断开其它应用程序的连接才行
或者重新启动一下数据库
 
这个在程序里怎么实现呢?
 
Please try it.


var
s,s1,s2,s3,s4,[red]s5[/red]:string;
begin
    openDialog1.Execute;
if OpenDialog1.FileName <> '' then
begin
s3:=OpenDialog1.FileName;
s4:=trim(Form1.ComboBox1.Text);
s:='restore database '+s4+' from disk='''+s3+'''';
s1:='with move '+s4+' to 'c:/Data/'''+s4+'.mdf',';
s2:='move '+s4+'_log to 'c:/Data/'''+s4+'_log.ldf'';
[blue]s5:=s+s1+s2[/blue];
    query1.SQL.Clear;
query1.SQL.Add([red]s5[/red]);

query1.ExecSQL;
query1.Close;
showmessage('您已经成功恢复!');
end;
 
>>这个在程序里怎么实现呢?
可以通过重新启动Sql Server的服务来实现
但这并不一定安全,假如别的用户正在操作数据呢?让他的数据丢失、做的工作白做?
所以并不是说所有东西都可以用程序自动完成的。
 
这个问题是数据库的独占问题, 以前我们已经有讨论,可参考
如下方法.

来自:dirk, 时间:2002-9-23 22:33:00, ID:1341985
这样啊,我的方法就是sp_who和kill,前面出错是因为我的程序只使用了一个ADOConnection,
将它与原先的业务数据库断开,再连上master,再sp_who、kill,再restore,最后再连接上
业务数据库,结果出现了上面的错误,实际上,避免错误的方法很简单,create一个新的
ADOConnection,连接上master,用这个ADOConnection去kill和restore,完成后,在将原先
的ADOConnection连接上业务数据库,什么问题都没有,代码和我上面贴的差不多,只是新建
一个ADOConnection,做完后Free掉,就ok!
诸葛白痴(呵呵呵,好像骂你一样),你说的“不能杀死自己的进程”的情况可能是你kill
的进程是master的进程,kill master的进程才会出现这样错误,我的程序中:
ADOQ_1.Filter :='dbname=''数据库名''';
ADOQ_1.Filtered :=true;
就是将需要kill连接的数据库名上的进程过滤出来,这个方法绝对不会错,我现在已经只用自
己做的程序来做备份、恢复的操作了,很好用,不出错!

 
顶部