C#实现SQL数据库备份和还原,请高手解答,在线等,谢谢(分不够再加)

时间:2021-07-29 19:04:16
在论坛查了很多资料.用论坛里面介绍的备份的方法我已经成功实现了备份,但还原时候就出问题了,下面是我的代码,请高手帮忙检查.
private void menuItem_huifu_Click(object sender, System.EventArgs e)
{
if(FPara.CheckLogin())
{
SQLDMO.SQLServer oSQLServer = new SQLDMO.SQLServerClass(); 
try 

oSQLServer.LoginSecure = false; 
oSQLServer.Connect("(local)", "sa", "123456");
SQLDMO.QueryResults qr = oSQLServer.EnumProcesses(-1); 
int iColPIDNum = -1 ; 
int iColDbName = -1 ; 
for(int i=1;i<=qr.Columns;i++) 

string strName = qr.get_ColumnName(i) ; 
if (strName.ToUpper().Trim() == "SPID") 

iColPIDNum = i ; 

else if (strName.ToUpper().Trim() == "DBNAME") 

iColDbName = i ; 

if (iColPIDNum != -1 && iColDbName != -1) 
break ; 

for(int i=1;i<=qr.Rows;i++) 

int lPID = qr.GetColumnLong(i,iColPIDNum) ; 
string strDBName = qr.GetColumnString(i,iColDbName) ; 
if (strDBName.ToUpper() == strDBName.ToUpper()) 
oSQLServer.KillProcess(lPID) ; 

SQLDMO.Restore oRestore = new SQLDMO.RestoreClass();
oRestore.Action = SQLDMO.SQLDMO_RESTORE_TYPE.SQLDMORestore_Database; 
oRestore.Database = "goods"; 
oRestore.Files = @"d:\TrafficSellForm.bak"; 
oRestore.FileNumber = 1; 
oRestore.ReplaceDatabase = true; 
oRestore.SQLRestore(oSQLServer); 
MessageBox.Show("数据库恢复成功!");

catch(Exception err) 

throw(new Exception("备份数据库失败!"+err.Message)); 

finally 

oSQLServer.DisConnect(); 

}
}
给出的出错提示是:
还原数据库失败![Microsoft][ODBC SQL Server Driver][SQL Server]只能取消用户进程。

求高手解答,在线等,谢谢

33 个解决方案

#1


if(FPara.CheckLogin())
是实现登陆检验的部分,意思是只有特定用户才可以使用这项还原功能.

#2


把try catch注释掉,把进程的相关部分也注释掉,单纯的还原,看能不能还原,如果不能还原那就是还原的部分有问题,如果可以还原那就是进程部分有问题,这样问题就好找多了

#3


在还原时,如果数据库进在运行进程,要杀掉进程,不然不能还原.我在SQL里试过

#4


单纯还原时候提示排它错误
估计是我在验证用户时使用了数据库,怎样在程序中关闭之前的线程呢?

#5


顶!!!

#6


还原的时候,如果数据库正在连接状态中,那就会提示失败的(在SQL SERVER 中手动还原也会失败)
而备份的时候,就不会出现这样的情况
建议确认将所有的客户端连接断开,再还原~~

#7


请问如何将所有的客户端连接断开用程序实现?
还有,因为我在验证登陆时候用到了数据库,就是上面的if(FPara.CheckLogin())
这个是不是没办法结束掉?
我整得实在没辙了.

#8


mark

#9


mark

#10


mark

#11


在恢复中,需要与原有的数据库的MDF和LDF的文件名和路径名一致才可以

我取消了使用备份和恢复的做法,而是采用附加数据库的模式

也就是调用sp_attatch_db存储过程

这个存储过程在master数据库中

#12


你可以在函数FPara.CheckLogin()的末尾断开与数据库的连接,试试

#13


单纯还原时候提示排它错误
估计是我在验证用户时使用了数据库,怎样在程序中关闭之前的线程呢?

//---------------------------
是不是你在查询分析器里使用了数据库连接,或者别的程序,前几天刚做了备份还原,代码相似,执行成功,建议用断点进行跟踪,看是不是在杀掉进程时出了什么问题。
因为你给的出错提示是:
还原数据库失败![Microsoft][ODBC SQL Server Driver][SQL Server]只能取消用户进程
第二次因为没有取消进程,所以排它

#14


学习中

#15


学习中

#16


留名,关注中

#17


up

#18


到SQL版相关的备份、还原的角本;然后在程序中直接用就OK了。

#19


SFeel(简单感觉)
能否贴出你的代码看看,学习一下你没出错的还原思路

#20


进入master,然后用存储过程杀掉所有连接要恢复数据库的进程;
****杀掉所有连接某数据库的进程:
create  proc  killspid  (@dbname  varchar(20))  
as  
begin  
declare  @sql  nvarchar(500)  
declare  @spid  int  
set  @sql='declare  getspid  cursor  for    
select  spid  from  sysprocesses  where  dbid=db_id('''+@dbname+''')'  
exec  (@sql)  
open  getspid  
fetch  next  from  getspid  into  @spid  
while  @@fetch_status  <  >-1  
begin  
exec('kill  '+@spid)  
fetch  next  from  getspid  into  @spid  
end  
close  getspid  
deallocate  getspid  
end  

--用法  
use  master  
exec  killspid  '数据库名'
小心使用,可能造成数据丢失

/// <summary>
/// 数据库恢复
/// </summary>
public static bool DbRestore(string dbname,string filename)
{
SQLDMO.Restore oRestore = new SQLDMO.RestoreClass();
SQLDMO.SQLServer oSQLServer = new SQLDMO.SQLServerClass();

try
{

oSQLServer.LoginSecure = false;
oSQLServer.Connect("bobo", "sa", "123");

oRestore.Action = 0 ; 
oRestore.Action = SQLDMO.SQLDMO_RESTORE_TYPE.SQLDMORestore_Database;
oRestore.Database = dbname;
oRestore.Files = filename;
oRestore.FileNumber = 1;
oRestore.ReplaceDatabase = true;
oRestore.SQLRestore(oSQLServer);
return true;
}
catch
{
return false;
}
finally
{
oSQLServer.DisConnect();
}
}

private void button2_Click(object sender, System.EventArgs e)
{
sqlconn.Open();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "use master exec killspid LibraryDataBase";
cmd.Connection = this.sqlconn;
cmd.ExecuteNonQuery();
sqlconn.Close();
if(DBService.DbRestore("LibraryDataBase",this.textBox1.Text))
MessageBox.Show("还原成功");
else MessageBox.Show("请检查路径名是否正确!");

}

#21


先还原,其他的注释掉,别忘了了先截断数据库日志看能不能还原,如果不能还原那就是还原的部分有问题,如果可以还原那就是进程部分有问题,这样问题就可以慢慢解决。

#22


先还原,其他的注释掉,别忘了了先截断数据库日志看能不能还原,如果不能还原那就是还原的部分有问题,如果可以还原那就是进程部分有问题,这样问题就可以慢慢解决。

#23


using System;
using System.Data.SqlClient;
using System.Data;
using System.Runtime.InteropServices;
using System.Text;

namespace UpTool
{
#region 处理SQL SERVER 专用类...
public class SqlLocator 
{
[DllImport("odbc32.dll")]
private static extern short SQLAllocHandle(short hType, IntPtr inputHandle, out IntPtr outputHandle);
[DllImport("odbc32.dll")]
private static extern short SQLSetEnvAttr(IntPtr henv, int attribute, IntPtr valuePtr, int strLength);
[DllImport("odbc32.dll")]
private static extern short SQLFreeHandle(short hType, IntPtr handle); 
[DllImport("odbc32.dll",CharSet=CharSet.Ansi)]
private static extern short SQLBrowseConnect(IntPtr hconn, StringBuilder inString, 
short inStringLength, StringBuilder outString, short outStringLength,
out short outLengthNeeded);

private const short SQL_HANDLE_ENV = 1;
private const short SQL_HANDLE_DBC = 2;
private const int SQL_ATTR_ODBC_VERSION = 200;
private const int SQL_OV_ODBC3 = 3;
private const short SQL_SUCCESS = 0;
  
private const short SQL_NEED_DATA = 99;
private const short DEFAULT_RESULT_SIZE = 1024;
private const string SQL_DRIVER_STR = "DRIVER=SQL SERVER";
 
private SqlLocator(){}

public static string[] GetServers() 
{
string[] retval = null;
string txt = string.Empty;
IntPtr henv = IntPtr.Zero;
IntPtr hconn = IntPtr.Zero;
StringBuilder inString = new StringBuilder(SQL_DRIVER_STR);
StringBuilder outString = new StringBuilder(DEFAULT_RESULT_SIZE);
short inStringLength = (short) inString.Length;
short lenNeeded = 0;

try 
{
if (SQL_SUCCESS == SQLAllocHandle(SQL_HANDLE_ENV, henv, out henv)) 
{
if (SQL_SUCCESS == SQLSetEnvAttr(henv,SQL_ATTR_ODBC_VERSION,(IntPtr)SQL_OV_ODBC3,0)) 
{
if (SQL_SUCCESS == SQLAllocHandle(SQL_HANDLE_DBC, henv, out hconn)) 
{
if (SQL_NEED_DATA ==  SQLBrowseConnect(hconn, inString, inStringLength, outString, 
DEFAULT_RESULT_SIZE, out lenNeeded)) 
{
if (DEFAULT_RESULT_SIZE < lenNeeded) 
{
outString.Capacity = lenNeeded;
if (SQL_NEED_DATA != SQLBrowseConnect(hconn, inString, inStringLength, outString, 
lenNeeded,out lenNeeded)) 
{
throw new ApplicationException("Unabled to aquire SQL Servers from ODBC driver.");

}
txt = outString.ToString();
int start = txt.IndexOf("{") + 1;
int len = txt.IndexOf("}") - start;
if ((start > 0) && (len > 0)) 
{
txt = txt.Substring(start,len);
}
else 
{
txt = string.Empty;
}
}      
}
}
}
}
catch 
{
//Throw away any error if we are not in debug mode
 
txt = string.Empty;
}
finally 
{
if (hconn != IntPtr.Zero) 
{
SQLFreeHandle(SQL_HANDLE_DBC,hconn);
}
if (henv != IntPtr.Zero) 
{
SQLFreeHandle(SQL_HANDLE_ENV,hconn);
}
}
 
if (txt.Length > 0) 
{
retval = txt.Split(",".ToCharArray());
}

return retval;
}
}
#endregion 处理SQL SERVER 专用类...
}

#24


using System;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Data;
using Jh.Database;
using HQDF.BaseCommons;


namespace UpTool
{
/// <summary>
///完成数据库的备份和恢复的功能
///确点:不能更改数据库的名字
/// </summary>
public class SqlRestore : System.Windows.Forms.Form 
{
string _temPath = "";
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.ComboBox cobServer;
private System.Windows.Forms.TextBox txtPass;
private System.Windows.Forms.TextBox txtUserID;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label labServer;
private System.Windows.Forms.Button butTestConn;
private System.Windows.Forms.ProgressBar pBar;
private System.Windows.Forms.Button butRestore;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.ComboBox cobDb;
private System.Windows.Forms.ListBox lbBackup;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.TreeView tvDir;
private System.Windows.Forms.Button btnExit;
#region system auto create...

/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;

public SqlRestore() 
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();

//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
_temPath = Application.StartupPath + "\\";
}

/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing ) 
{
if( disposing ) 
{
if (components != null) 
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#25


#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent() 
{
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.label4 = new System.Windows.Forms.Label();
this.tvDir = new System.Windows.Forms.TreeView();
this.lbBackup = new System.Windows.Forms.ListBox();
this.label5 = new System.Windows.Forms.Label();
this.pBar = new System.Windows.Forms.ProgressBar();
this.butRestore = new System.Windows.Forms.Button();
this.label3 = new System.Windows.Forms.Label();
this.cobDb = new System.Windows.Forms.ComboBox();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.cobServer = new System.Windows.Forms.ComboBox();
this.txtPass = new System.Windows.Forms.TextBox();
this.txtUserID = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.labServer = new System.Windows.Forms.Label();
this.butTestConn = new System.Windows.Forms.Button();
this.btnExit = new System.Windows.Forms.Button();
this.tabControl1.SuspendLayout();
this.tabPage1.SuspendLayout();
this.tabPage2.SuspendLayout();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
// 
// tabControl1
// 
this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
| System.Windows.Forms.AnchorStyles.Left) 
| System.Windows.Forms.AnchorStyles.Right)));
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Location = new System.Drawing.Point(7, 7);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(637, 478);
this.tabControl1.TabIndex = 27;
this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabControl1_SelectedIndexChanged);
// 
// tabPage1
// 
this.tabPage1.Controls.Add(this.label4);
this.tabPage1.Controls.Add(this.tvDir);
this.tabPage1.Controls.Add(this.lbBackup);
this.tabPage1.Controls.Add(this.label5);
this.tabPage1.Controls.Add(this.pBar);
this.tabPage1.Controls.Add(this.butRestore);
this.tabPage1.Controls.Add(this.label3);
this.tabPage1.Controls.Add(this.cobDb);
this.tabPage1.Location = new System.Drawing.Point(4, 23);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Size = new System.Drawing.Size(629, 451);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "还原数据库备份";
// 
// label4
// 
this.label4.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.label4.Location = new System.Drawing.Point(11, 8);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(126, 16);
this.label4.TabIndex = 33;
this.label4.Text = "数据库服务器目录:";
// 
// tvDir
// 
this.tvDir.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
| System.Windows.Forms.AnchorStyles.Left) 
| System.Windows.Forms.AnchorStyles.Right)));
this.tvDir.ImageIndex = -1;
this.tvDir.Location = new System.Drawing.Point(9, 29);
this.tvDir.Name = "tvDir";
this.tvDir.SelectedImageIndex = -1;
this.tvDir.Size = new System.Drawing.Size(350, 340);
this.tvDir.TabIndex = 32;
this.tvDir.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvDir_AfterSelect);
// 
// lbBackup
// 
this.lbBackup.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
| System.Windows.Forms.AnchorStyles.Right)));
this.lbBackup.Font = new System.Drawing.Font("宋体", 12F);
this.lbBackup.ItemHeight = 16;
this.lbBackup.Location = new System.Drawing.Point(364, 29);
this.lbBackup.Name = "lbBackup";
this.lbBackup.Size = new System.Drawing.Size(254, 340);
this.lbBackup.Sorted = true;
this.lbBackup.TabIndex = 31;
// 
// label5
// 
this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.label5.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.label5.Location = new System.Drawing.Point(364, 8);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(126, 16);
this.label5.TabIndex = 30;
this.label5.Text = "数据库备份列表:";
// 
// pBar
// 
this.pBar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.pBar.Location = new System.Drawing.Point(98, 415);
this.pBar.Name = "pBar";
this.pBar.Size = new System.Drawing.Size(521, 24);
this.pBar.TabIndex = 29;
// 
// butRestore
// 
this.butRestore.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.butRestore.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.butRestore.Location = new System.Drawing.Point(12, 415);
this.butRestore.Name = "butRestore";
this.butRestore.Size = new System.Drawing.Size(80, 24);
this.butRestore.TabIndex = 26;
this.butRestore.Text = "Restore";
this.butRestore.Click += new System.EventHandler(this.butRestore_Click);
// 
// label3
// 
this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.label3.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.label3.Location = new System.Drawing.Point(11, 383);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(88, 16);
this.label3.TabIndex = 28;
this.label3.Text = "目的数据库:";

#26


public bool RestoreDB(string strDbName,string strFileName,string strServerName,string strUserName,string strPwd ) 

SQLDMO.SQLServer svr = new SQLDMO.SQLServerClass() ; 
try 

ServerName = strServerName ; 
UserName = strUserName ; 
Password = strPwd ; 
svr.Connect(ServerName,UserName,Password) ; 
SQLDMO.QueryResults qr = svr.EnumProcesses(-1) ; 
int iColPIDNum = -1 ; 
int iColDbName = -1 ; 
for(int i=1;i<=qr.Columns;i++) 

string strName = qr.get_ColumnName(i) ; 
if (strName.ToUpper().Trim() == "SPID") 

iColPIDNum = i ; 

else if (strName.ToUpper().Trim() == "DBNAME") 

iColDbName = i ; 

if (iColPIDNum != -1 && iColDbName != -1) 
break ; 


for(int i=1;i<=qr.Rows;i++) 

int lPID = qr.GetColumnLong(i,iColPIDNum) ; 
string strDBName = qr.GetColumnString(i,iColDbName) ; 
if (strDBName.ToUpper() == strDbName.ToUpper()) 
svr.KillProcess(lPID) ; 


SQLDMO.Restore res = new SQLDMO.RestoreClass() ; 
res.Action = 0 ; 
res.Files = strFileName ; 
res.Database = strDbName ; 
res.ReplaceDatabase = true ; 
res.SQLRestore(svr) ; 
return true ; 

catch(Exception err) 

message = "恢复数据库失败,请关闭所有和该数据库连接的程序!" +err.Message;
MessageBox.Show(message ,"提示");
return false;

finally 

svr.DisConnect() ;


}

#27


兄弟能不能对代码做简单描述??

#28


mark

#29


都牛的很呀!

#30


可以采用采用附加数据库的模式 调用系统存储过程

#31


private void BackupDB(string strDbName)//数据库备份  需要在窗体中放Label,ProgrssBar控件用来显示提示信息和进度条,还有OpenFileDialog,和SaveFileDialog控件
{
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{

this.Cursor = Cursors.WaitCursor;
this.label1.Text = "正在进行数据备份,这可能需要几秒或更长时间,请稍候...";
this.label1.Visible = true; 
this.label1.Refresh();
this.pBar1.Visible = true;
//------------------------------------------------------------------------------------

   
string selfName = saveFileDialog1.FileName.Trim();
//string deviceName = "bozhaobeifen";
//string remark = "备份测试";
   
//◆数据备份:
SQLDMO.Backup oBackup = new SQLDMO.BackupClass();
SQLDMO.SQLServer oSQLServer = new SQLDMO.SQLServerClass();
oBackup.Action = 0 ; 
oBackup.Initialize = true ; 
SQLDMO.BackupSink_PercentCompleteEventHandler pceh = new SQLDMO.BackupSink_PercentCompleteEventHandler(Step); 
oBackup.PercentComplete += pceh; 

try
{
oSQLServer.LoginSecure = false;
oSQLServer.Connect(gb.GetJQName(), "sa", "sa");
oBackup.Action = SQLDMO.SQLDMO_BACKUP_TYPE.SQLDMOBackup_Database;
oBackup.Database = strDbName;//数据库名
oBackup.Files = selfName;//文件路径
//oBackup.BackupSetName = deviceName;//备份名称
//oBackup.BackupSetDescription = remark;//备份描述
oBackup.Initialize = true;
oBackup.SQLBackup(oSQLServer);
MessageBox.Show("数据库备份成功!","系统提示!",MessageBoxButtons.OK,MessageBoxIcon.Warning);
}
catch(System.Exception ex)
{
MessageBox.Show("数据库备份失败!请不要选择备份到桌面!\n\n"+ ex.ToString());
}
finally
{
oSQLServer.DisConnect();
}

//------------------------------------------------------------------------------------
this.label1.Text = "";
this.label1.Visible = false;
this.pBar1.Visible = false;
this.Cursor = Cursors.Default;

}
}

/// <summary>
/// 显示进度条
/// </summary>
private void Step(string message,int percent) 

this.pBar1.Value = percent ; 
}
public void RestoreDB(string strDbName)//数据恢复

if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
this.label1.Visible = true;
this.label1.Refresh();
this.pBar1.Visible = true;
this.label1.Text = "进行数据库恢复,这可能需要几秒或更长时间,请稍候...";
SQLDMO.SQLServer svr = new SQLDMO.SQLServerClass() ; 
try 

svr.Connect(gb.GetJQName(),"sa","sa") ; 
//杀死所有有关的进程
SQLDMO.QueryResults qr = svr.EnumProcesses(-1) ; 
int iColPIDNum = -1 ; 
int iColDbName = -1 ; 
for(int i=1;i<=qr.Columns;i++) 

string strName = qr.get_ColumnName(i) ; 
if (strName.ToUpper().Trim() == "SPID") 

iColPIDNum = i ; 

else if (strName.ToUpper().Trim() == "DBNAME") 

iColDbName = i ; 

if (iColPIDNum != -1 && iColDbName != -1) 
break ; 


for(int i=1;i<=qr.Rows;i++) 

int lPID = qr.GetColumnLong(i,iColPIDNum) ; 
string strDBName = qr.GetColumnString(i,iColDbName) ; 
if (strDBName.ToUpper() == strDbName.ToUpper()) 
svr.KillProcess(lPID) ; 


SQLDMO.Restore res = new SQLDMO.RestoreClass() ; 
res.Action = 0 ; 
SQLDMO.RestoreSink_PercentCompleteEventHandler pceh = new SQLDMO.RestoreSink_PercentCompleteEventHandler(Step); 
res.PercentComplete += pceh; 
res.Files = openFileDialog1.FileName.Trim() ; 
res.Database = strDbName ; 
res.ReplaceDatabase = true ; 
res.SQLRestore(svr) ; 
MessageBox.Show("数据库恢复成功!","系统提示!",MessageBoxButtons.OK,MessageBoxIcon.Warning);

catch(Exception err) 

throw(new Exception("恢复数据库失败,请关闭所有和该数据库连接的程序!\n如果在桌面进行恢复请改变路径!\n\n"+err.Message)) ; 

finally 

svr.DisConnect() ; 

this.label1.Visible = false;
this.pBar1.Visible = false;
}

#32


上面代码copy即可运行,我也是刚做相同的东西,然后自己整理了一下,已经测试多次,唯一不足的是不能备份到桌面。试试吧!!

#33


放在单击事件下即可,把gb.GetJQName 换成你的数据库服务器名就行了

#1


if(FPara.CheckLogin())
是实现登陆检验的部分,意思是只有特定用户才可以使用这项还原功能.

#2


把try catch注释掉,把进程的相关部分也注释掉,单纯的还原,看能不能还原,如果不能还原那就是还原的部分有问题,如果可以还原那就是进程部分有问题,这样问题就好找多了

#3


在还原时,如果数据库进在运行进程,要杀掉进程,不然不能还原.我在SQL里试过

#4


单纯还原时候提示排它错误
估计是我在验证用户时使用了数据库,怎样在程序中关闭之前的线程呢?

#5


顶!!!

#6


还原的时候,如果数据库正在连接状态中,那就会提示失败的(在SQL SERVER 中手动还原也会失败)
而备份的时候,就不会出现这样的情况
建议确认将所有的客户端连接断开,再还原~~

#7


请问如何将所有的客户端连接断开用程序实现?
还有,因为我在验证登陆时候用到了数据库,就是上面的if(FPara.CheckLogin())
这个是不是没办法结束掉?
我整得实在没辙了.

#8


mark

#9


mark

#10


mark

#11


在恢复中,需要与原有的数据库的MDF和LDF的文件名和路径名一致才可以

我取消了使用备份和恢复的做法,而是采用附加数据库的模式

也就是调用sp_attatch_db存储过程

这个存储过程在master数据库中

#12


你可以在函数FPara.CheckLogin()的末尾断开与数据库的连接,试试

#13


单纯还原时候提示排它错误
估计是我在验证用户时使用了数据库,怎样在程序中关闭之前的线程呢?

//---------------------------
是不是你在查询分析器里使用了数据库连接,或者别的程序,前几天刚做了备份还原,代码相似,执行成功,建议用断点进行跟踪,看是不是在杀掉进程时出了什么问题。
因为你给的出错提示是:
还原数据库失败![Microsoft][ODBC SQL Server Driver][SQL Server]只能取消用户进程
第二次因为没有取消进程,所以排它

#14


学习中

#15


学习中

#16


留名,关注中

#17


up

#18


到SQL版相关的备份、还原的角本;然后在程序中直接用就OK了。

#19


SFeel(简单感觉)
能否贴出你的代码看看,学习一下你没出错的还原思路

#20


进入master,然后用存储过程杀掉所有连接要恢复数据库的进程;
****杀掉所有连接某数据库的进程:
create  proc  killspid  (@dbname  varchar(20))  
as  
begin  
declare  @sql  nvarchar(500)  
declare  @spid  int  
set  @sql='declare  getspid  cursor  for    
select  spid  from  sysprocesses  where  dbid=db_id('''+@dbname+''')'  
exec  (@sql)  
open  getspid  
fetch  next  from  getspid  into  @spid  
while  @@fetch_status  <  >-1  
begin  
exec('kill  '+@spid)  
fetch  next  from  getspid  into  @spid  
end  
close  getspid  
deallocate  getspid  
end  

--用法  
use  master  
exec  killspid  '数据库名'
小心使用,可能造成数据丢失

/// <summary>
/// 数据库恢复
/// </summary>
public static bool DbRestore(string dbname,string filename)
{
SQLDMO.Restore oRestore = new SQLDMO.RestoreClass();
SQLDMO.SQLServer oSQLServer = new SQLDMO.SQLServerClass();

try
{

oSQLServer.LoginSecure = false;
oSQLServer.Connect("bobo", "sa", "123");

oRestore.Action = 0 ; 
oRestore.Action = SQLDMO.SQLDMO_RESTORE_TYPE.SQLDMORestore_Database;
oRestore.Database = dbname;
oRestore.Files = filename;
oRestore.FileNumber = 1;
oRestore.ReplaceDatabase = true;
oRestore.SQLRestore(oSQLServer);
return true;
}
catch
{
return false;
}
finally
{
oSQLServer.DisConnect();
}
}

private void button2_Click(object sender, System.EventArgs e)
{
sqlconn.Open();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "use master exec killspid LibraryDataBase";
cmd.Connection = this.sqlconn;
cmd.ExecuteNonQuery();
sqlconn.Close();
if(DBService.DbRestore("LibraryDataBase",this.textBox1.Text))
MessageBox.Show("还原成功");
else MessageBox.Show("请检查路径名是否正确!");

}

#21


先还原,其他的注释掉,别忘了了先截断数据库日志看能不能还原,如果不能还原那就是还原的部分有问题,如果可以还原那就是进程部分有问题,这样问题就可以慢慢解决。

#22


先还原,其他的注释掉,别忘了了先截断数据库日志看能不能还原,如果不能还原那就是还原的部分有问题,如果可以还原那就是进程部分有问题,这样问题就可以慢慢解决。

#23


using System;
using System.Data.SqlClient;
using System.Data;
using System.Runtime.InteropServices;
using System.Text;

namespace UpTool
{
#region 处理SQL SERVER 专用类...
public class SqlLocator 
{
[DllImport("odbc32.dll")]
private static extern short SQLAllocHandle(short hType, IntPtr inputHandle, out IntPtr outputHandle);
[DllImport("odbc32.dll")]
private static extern short SQLSetEnvAttr(IntPtr henv, int attribute, IntPtr valuePtr, int strLength);
[DllImport("odbc32.dll")]
private static extern short SQLFreeHandle(short hType, IntPtr handle); 
[DllImport("odbc32.dll",CharSet=CharSet.Ansi)]
private static extern short SQLBrowseConnect(IntPtr hconn, StringBuilder inString, 
short inStringLength, StringBuilder outString, short outStringLength,
out short outLengthNeeded);

private const short SQL_HANDLE_ENV = 1;
private const short SQL_HANDLE_DBC = 2;
private const int SQL_ATTR_ODBC_VERSION = 200;
private const int SQL_OV_ODBC3 = 3;
private const short SQL_SUCCESS = 0;
  
private const short SQL_NEED_DATA = 99;
private const short DEFAULT_RESULT_SIZE = 1024;
private const string SQL_DRIVER_STR = "DRIVER=SQL SERVER";
 
private SqlLocator(){}

public static string[] GetServers() 
{
string[] retval = null;
string txt = string.Empty;
IntPtr henv = IntPtr.Zero;
IntPtr hconn = IntPtr.Zero;
StringBuilder inString = new StringBuilder(SQL_DRIVER_STR);
StringBuilder outString = new StringBuilder(DEFAULT_RESULT_SIZE);
short inStringLength = (short) inString.Length;
short lenNeeded = 0;

try 
{
if (SQL_SUCCESS == SQLAllocHandle(SQL_HANDLE_ENV, henv, out henv)) 
{
if (SQL_SUCCESS == SQLSetEnvAttr(henv,SQL_ATTR_ODBC_VERSION,(IntPtr)SQL_OV_ODBC3,0)) 
{
if (SQL_SUCCESS == SQLAllocHandle(SQL_HANDLE_DBC, henv, out hconn)) 
{
if (SQL_NEED_DATA ==  SQLBrowseConnect(hconn, inString, inStringLength, outString, 
DEFAULT_RESULT_SIZE, out lenNeeded)) 
{
if (DEFAULT_RESULT_SIZE < lenNeeded) 
{
outString.Capacity = lenNeeded;
if (SQL_NEED_DATA != SQLBrowseConnect(hconn, inString, inStringLength, outString, 
lenNeeded,out lenNeeded)) 
{
throw new ApplicationException("Unabled to aquire SQL Servers from ODBC driver.");

}
txt = outString.ToString();
int start = txt.IndexOf("{") + 1;
int len = txt.IndexOf("}") - start;
if ((start > 0) && (len > 0)) 
{
txt = txt.Substring(start,len);
}
else 
{
txt = string.Empty;
}
}      
}
}
}
}
catch 
{
//Throw away any error if we are not in debug mode
 
txt = string.Empty;
}
finally 
{
if (hconn != IntPtr.Zero) 
{
SQLFreeHandle(SQL_HANDLE_DBC,hconn);
}
if (henv != IntPtr.Zero) 
{
SQLFreeHandle(SQL_HANDLE_ENV,hconn);
}
}
 
if (txt.Length > 0) 
{
retval = txt.Split(",".ToCharArray());
}

return retval;
}
}
#endregion 处理SQL SERVER 专用类...
}

#24


using System;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Data;
using Jh.Database;
using HQDF.BaseCommons;


namespace UpTool
{
/// <summary>
///完成数据库的备份和恢复的功能
///确点:不能更改数据库的名字
/// </summary>
public class SqlRestore : System.Windows.Forms.Form 
{
string _temPath = "";
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.ComboBox cobServer;
private System.Windows.Forms.TextBox txtPass;
private System.Windows.Forms.TextBox txtUserID;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label labServer;
private System.Windows.Forms.Button butTestConn;
private System.Windows.Forms.ProgressBar pBar;
private System.Windows.Forms.Button butRestore;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.ComboBox cobDb;
private System.Windows.Forms.ListBox lbBackup;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.TreeView tvDir;
private System.Windows.Forms.Button btnExit;
#region system auto create...

/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;

public SqlRestore() 
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();

//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
_temPath = Application.StartupPath + "\\";
}

/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing ) 
{
if( disposing ) 
{
if (components != null) 
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#25


#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent() 
{
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.label4 = new System.Windows.Forms.Label();
this.tvDir = new System.Windows.Forms.TreeView();
this.lbBackup = new System.Windows.Forms.ListBox();
this.label5 = new System.Windows.Forms.Label();
this.pBar = new System.Windows.Forms.ProgressBar();
this.butRestore = new System.Windows.Forms.Button();
this.label3 = new System.Windows.Forms.Label();
this.cobDb = new System.Windows.Forms.ComboBox();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.cobServer = new System.Windows.Forms.ComboBox();
this.txtPass = new System.Windows.Forms.TextBox();
this.txtUserID = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.labServer = new System.Windows.Forms.Label();
this.butTestConn = new System.Windows.Forms.Button();
this.btnExit = new System.Windows.Forms.Button();
this.tabControl1.SuspendLayout();
this.tabPage1.SuspendLayout();
this.tabPage2.SuspendLayout();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
// 
// tabControl1
// 
this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
| System.Windows.Forms.AnchorStyles.Left) 
| System.Windows.Forms.AnchorStyles.Right)));
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Location = new System.Drawing.Point(7, 7);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(637, 478);
this.tabControl1.TabIndex = 27;
this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabControl1_SelectedIndexChanged);
// 
// tabPage1
// 
this.tabPage1.Controls.Add(this.label4);
this.tabPage1.Controls.Add(this.tvDir);
this.tabPage1.Controls.Add(this.lbBackup);
this.tabPage1.Controls.Add(this.label5);
this.tabPage1.Controls.Add(this.pBar);
this.tabPage1.Controls.Add(this.butRestore);
this.tabPage1.Controls.Add(this.label3);
this.tabPage1.Controls.Add(this.cobDb);
this.tabPage1.Location = new System.Drawing.Point(4, 23);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Size = new System.Drawing.Size(629, 451);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "还原数据库备份";
// 
// label4
// 
this.label4.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.label4.Location = new System.Drawing.Point(11, 8);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(126, 16);
this.label4.TabIndex = 33;
this.label4.Text = "数据库服务器目录:";
// 
// tvDir
// 
this.tvDir.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
| System.Windows.Forms.AnchorStyles.Left) 
| System.Windows.Forms.AnchorStyles.Right)));
this.tvDir.ImageIndex = -1;
this.tvDir.Location = new System.Drawing.Point(9, 29);
this.tvDir.Name = "tvDir";
this.tvDir.SelectedImageIndex = -1;
this.tvDir.Size = new System.Drawing.Size(350, 340);
this.tvDir.TabIndex = 32;
this.tvDir.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvDir_AfterSelect);
// 
// lbBackup
// 
this.lbBackup.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
| System.Windows.Forms.AnchorStyles.Right)));
this.lbBackup.Font = new System.Drawing.Font("宋体", 12F);
this.lbBackup.ItemHeight = 16;
this.lbBackup.Location = new System.Drawing.Point(364, 29);
this.lbBackup.Name = "lbBackup";
this.lbBackup.Size = new System.Drawing.Size(254, 340);
this.lbBackup.Sorted = true;
this.lbBackup.TabIndex = 31;
// 
// label5
// 
this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.label5.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.label5.Location = new System.Drawing.Point(364, 8);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(126, 16);
this.label5.TabIndex = 30;
this.label5.Text = "数据库备份列表:";
// 
// pBar
// 
this.pBar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.pBar.Location = new System.Drawing.Point(98, 415);
this.pBar.Name = "pBar";
this.pBar.Size = new System.Drawing.Size(521, 24);
this.pBar.TabIndex = 29;
// 
// butRestore
// 
this.butRestore.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.butRestore.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.butRestore.Location = new System.Drawing.Point(12, 415);
this.butRestore.Name = "butRestore";
this.butRestore.Size = new System.Drawing.Size(80, 24);
this.butRestore.TabIndex = 26;
this.butRestore.Text = "Restore";
this.butRestore.Click += new System.EventHandler(this.butRestore_Click);
// 
// label3
// 
this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.label3.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.label3.Location = new System.Drawing.Point(11, 383);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(88, 16);
this.label3.TabIndex = 28;
this.label3.Text = "目的数据库:";

#26


public bool RestoreDB(string strDbName,string strFileName,string strServerName,string strUserName,string strPwd ) 

SQLDMO.SQLServer svr = new SQLDMO.SQLServerClass() ; 
try 

ServerName = strServerName ; 
UserName = strUserName ; 
Password = strPwd ; 
svr.Connect(ServerName,UserName,Password) ; 
SQLDMO.QueryResults qr = svr.EnumProcesses(-1) ; 
int iColPIDNum = -1 ; 
int iColDbName = -1 ; 
for(int i=1;i<=qr.Columns;i++) 

string strName = qr.get_ColumnName(i) ; 
if (strName.ToUpper().Trim() == "SPID") 

iColPIDNum = i ; 

else if (strName.ToUpper().Trim() == "DBNAME") 

iColDbName = i ; 

if (iColPIDNum != -1 && iColDbName != -1) 
break ; 


for(int i=1;i<=qr.Rows;i++) 

int lPID = qr.GetColumnLong(i,iColPIDNum) ; 
string strDBName = qr.GetColumnString(i,iColDbName) ; 
if (strDBName.ToUpper() == strDbName.ToUpper()) 
svr.KillProcess(lPID) ; 


SQLDMO.Restore res = new SQLDMO.RestoreClass() ; 
res.Action = 0 ; 
res.Files = strFileName ; 
res.Database = strDbName ; 
res.ReplaceDatabase = true ; 
res.SQLRestore(svr) ; 
return true ; 

catch(Exception err) 

message = "恢复数据库失败,请关闭所有和该数据库连接的程序!" +err.Message;
MessageBox.Show(message ,"提示");
return false;

finally 

svr.DisConnect() ;


}

#27


兄弟能不能对代码做简单描述??

#28


mark

#29


都牛的很呀!

#30


可以采用采用附加数据库的模式 调用系统存储过程

#31


private void BackupDB(string strDbName)//数据库备份  需要在窗体中放Label,ProgrssBar控件用来显示提示信息和进度条,还有OpenFileDialog,和SaveFileDialog控件
{
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{

this.Cursor = Cursors.WaitCursor;
this.label1.Text = "正在进行数据备份,这可能需要几秒或更长时间,请稍候...";
this.label1.Visible = true; 
this.label1.Refresh();
this.pBar1.Visible = true;
//------------------------------------------------------------------------------------

   
string selfName = saveFileDialog1.FileName.Trim();
//string deviceName = "bozhaobeifen";
//string remark = "备份测试";
   
//◆数据备份:
SQLDMO.Backup oBackup = new SQLDMO.BackupClass();
SQLDMO.SQLServer oSQLServer = new SQLDMO.SQLServerClass();
oBackup.Action = 0 ; 
oBackup.Initialize = true ; 
SQLDMO.BackupSink_PercentCompleteEventHandler pceh = new SQLDMO.BackupSink_PercentCompleteEventHandler(Step); 
oBackup.PercentComplete += pceh; 

try
{
oSQLServer.LoginSecure = false;
oSQLServer.Connect(gb.GetJQName(), "sa", "sa");
oBackup.Action = SQLDMO.SQLDMO_BACKUP_TYPE.SQLDMOBackup_Database;
oBackup.Database = strDbName;//数据库名
oBackup.Files = selfName;//文件路径
//oBackup.BackupSetName = deviceName;//备份名称
//oBackup.BackupSetDescription = remark;//备份描述
oBackup.Initialize = true;
oBackup.SQLBackup(oSQLServer);
MessageBox.Show("数据库备份成功!","系统提示!",MessageBoxButtons.OK,MessageBoxIcon.Warning);
}
catch(System.Exception ex)
{
MessageBox.Show("数据库备份失败!请不要选择备份到桌面!\n\n"+ ex.ToString());
}
finally
{
oSQLServer.DisConnect();
}

//------------------------------------------------------------------------------------
this.label1.Text = "";
this.label1.Visible = false;
this.pBar1.Visible = false;
this.Cursor = Cursors.Default;

}
}

/// <summary>
/// 显示进度条
/// </summary>
private void Step(string message,int percent) 

this.pBar1.Value = percent ; 
}
public void RestoreDB(string strDbName)//数据恢复

if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
this.label1.Visible = true;
this.label1.Refresh();
this.pBar1.Visible = true;
this.label1.Text = "进行数据库恢复,这可能需要几秒或更长时间,请稍候...";
SQLDMO.SQLServer svr = new SQLDMO.SQLServerClass() ; 
try 

svr.Connect(gb.GetJQName(),"sa","sa") ; 
//杀死所有有关的进程
SQLDMO.QueryResults qr = svr.EnumProcesses(-1) ; 
int iColPIDNum = -1 ; 
int iColDbName = -1 ; 
for(int i=1;i<=qr.Columns;i++) 

string strName = qr.get_ColumnName(i) ; 
if (strName.ToUpper().Trim() == "SPID") 

iColPIDNum = i ; 

else if (strName.ToUpper().Trim() == "DBNAME") 

iColDbName = i ; 

if (iColPIDNum != -1 && iColDbName != -1) 
break ; 


for(int i=1;i<=qr.Rows;i++) 

int lPID = qr.GetColumnLong(i,iColPIDNum) ; 
string strDBName = qr.GetColumnString(i,iColDbName) ; 
if (strDBName.ToUpper() == strDbName.ToUpper()) 
svr.KillProcess(lPID) ; 


SQLDMO.Restore res = new SQLDMO.RestoreClass() ; 
res.Action = 0 ; 
SQLDMO.RestoreSink_PercentCompleteEventHandler pceh = new SQLDMO.RestoreSink_PercentCompleteEventHandler(Step); 
res.PercentComplete += pceh; 
res.Files = openFileDialog1.FileName.Trim() ; 
res.Database = strDbName ; 
res.ReplaceDatabase = true ; 
res.SQLRestore(svr) ; 
MessageBox.Show("数据库恢复成功!","系统提示!",MessageBoxButtons.OK,MessageBoxIcon.Warning);

catch(Exception err) 

throw(new Exception("恢复数据库失败,请关闭所有和该数据库连接的程序!\n如果在桌面进行恢复请改变路径!\n\n"+err.Message)) ; 

finally 

svr.DisConnect() ; 

this.label1.Visible = false;
this.pBar1.Visible = false;
}

#32


上面代码copy即可运行,我也是刚做相同的东西,然后自己整理了一下,已经测试多次,唯一不足的是不能备份到桌面。试试吧!!

#33


放在单击事件下即可,把gb.GetJQName 换成你的数据库服务器名就行了