| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1122 人关注过本帖
标题:请求帮忙,数据库的复制
只看楼主 加入收藏
xinyu22
Rank: 1
等 级:新手上路
帖 子:48
专家分:0
注 册:2010-11-5
结帖率:55.56%
收藏
 问题点数:0 回复次数:11 
请求帮忙,数据库的复制
各位老师,请大家帮帮我,看一下我的代码问题出在哪里: 我现在在做一个用VB代码实现数据库的复制(就是把数据库换个名字,内容不变,还是在本地机器上。)时出现错误。我是这样想的,先在本地机器上指定数据库的备份,然后再在本地机器上创建一个新的数据库(当然数据库名称不重复),然后把刚才的数据库备份文件再恢复到这个新建的数据库上,达到复制数据库,并改名的目的。思路就是这样!可是总是出错,    当然我用的是sql server 2000 。

总是报以下错误:

[Microsoft][ODBC SQL Server Driver][SQL Server]无法重写文件 'D:\database\studb_Data.MDF'。数据库 'studb' 正在使用该文件。
[Microsoft][ODBC SQL Server Driver][SQL Server]文件 '连锁销售系统_Data' 无法还原为 'D:\database\studb_Data.MDF'。请使用 WITH MOVE 选项来标识该文件的有效位置。
[Microsoft][ODBC SQL Server Driver][SQL Server]无法重写文件 'D:\database\studb_Log.LDF'。数
据库 'studb' 正在使用该文件。
[Microsoft][ODBC SQL Server Driver][SQL Server]文件 '连锁销售系统_Log' 无法还原为  
'D:\database\studb_Log.LDF'。请使用 WITH MOVE 选项来标识该文件的有效位置。
[Microsoft][ODBC SQL Server Driver][SQL Server] RESTORE DATABASE 操作异常终止
代码如下:
‘下面是备份数据库的代码
            Dim sqlserver As New SQLDMO.SQLServer
            Dim backup As New SQLDMO.Backup
            Try
                sqlserver.LoginSecure = False
                sqlserver.Connect(txtServer.Text.Trim(), txtUsername.Text.Trim(), txtPwd.Text.Trim())
                backup.Action = SQLDMO.SQLDMO_BACKUP_TYPE.SQLDMOBackup_Database
                backup.Database = "studb"
                backup.Files = "c:\database.bak"          ’这里我是写死的。应该没有关系吧!下面还原的时候还是用这个
                backup.BackupSetName = "studb"
                backup.BackupSetDescription = "数据库备份"
                backup.Initialize = True
                backup.SQLBackup(sqlserver)               
            Catch ex As Exception
                MsgBox(ex.Message, MsgBoxStyle.OkOnly, "提示")
            Finally
                sqlserver.DisConnect()
            End Try
上面的备份代码执行起来没有问题,可以备份到c盘里。接下来就是还原:

‘下面是还原的代码:
        Dim tmpserver As New SQLDMO.SQLServer
        Dim conn As New SqlConnection
        Try
            conn.ConnectionString = "server=(local);user id=sa; password=;Initial Catalog="
            Dim command As New SqlCommand
            command.Connection = conn
            ' txtDatabase.Text  是用户输入的新数据库的名称,因为这个数据库不存在,所以我就先把这个数据库 txtDatabase.Text  用代码创建出来,然后再给它还原。
            ’下面是创建新数据库的代码,将主数据库文件和日志文件放在D盘的database 文件夹里
            Dim strsql = "use master     create database " & txtDatabase.Text.Trim() & " on primary  (Name =" & txtDatabase.Text.Trim() & _
                            "_data,filename='D:\database\" & txtDatabase.Text.Trim() & ".mdf',size=10,filegrowth=10%) " & _
                            " log on (name =" & txtDatabase.Text.Trim() & "_log,filename='D:\database\" &  
txtDatabase.Text.Trim() & ".ldf',size=3,filegrowth=1)"
             = strsql
            conn.Open()
            command.ExecuteNonQuery()
            conn.Close()
            '执行上面的创建数据库代码也是没有问题  可以创建  txtDatabase.Text 数据库
            
            ‘下面是还原数据库代码
            Dim tmprestore As New SQLDMO.Restore
            tmprestore.Action = SQLDMO.SQLDMO_RESTORE_TYPE.SQLDMORestore_Database
            Dim qr As SQLDMO.QueryResults
            qr = tmpserver.EnumProcesses(-1)
            Dim iColPIDNum As Integer = -1
            Dim iColDbName As Integer = -1
            Dim i As Integer
            '杀死其它的连接进程
            For i = 1 To qr.Columns  
                Dim strName As String = qr.ColumnName(i)
                If (strName.ToUpper().Trim() = "SPID") Then
                    iColPIDNum = i
                ElseIf (strName.ToUpper().Trim() = "DBNAME") Then
                    iColDbName = i
                End If
                If (iColPIDNum <> -1 And iColDbName <> -1) Then
                    Exit For
                End If
            Next
            For i = 1 To qr.Rows

                Dim lPID As Integer = qr.GetColumnLong(i, iColPIDNum)
                Dim strDBName As String = qr.GetColumnString(i, iColDbName)
                If (strDBName.ToUpper() = txtDatabase.Text.ToUpper()) Then     ‘杀 txtDatabase.Text  数据库进程,这里我测试过如果将 txtDatabase.Text替换为studb  也是不可以 ,程序根本就不走这段 tmpserver.KillProcess(lPID)。郁闷。。。
                    tmpserver.KillProcess(lPID)
                End If
            Next
            tmprestore.Files = "c:\database.bak"     ’这里是之前备份的文件
            tmprestore.FileNumber = 1
            tmprestore.Database = txtDatabase.Text.Trim()   ‘设置数据库的名称为用户输入的
            tmprestore.ReplaceDatabase = True
            tmprestore.SQLRestore(tmpserver)      ‘ 每次执行到里,总是会报错。???????
            MsgBox("数据恢复成功。", MsgBoxStyle.OkOnly, "系统提示")            
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.OkOnly, "提示")
        Finally
            tmpserver.DisConnect()
        End Try

总是报以下错误:

[Microsoft][ODBC SQL Server Driver][SQL Server]无法重写文件 'D:\database\studb_Data.MDF'。数据库 'studb' 正在使用该文件。
[Microsoft][ODBC SQL Server Driver][SQL Server]文件 '连锁销售系统_Data' 无法还原为 'D:\database\studb_Data.MDF'。请使用 WITH MOVE 选项来标识该文件的有效位置。
[Microsoft][ODBC SQL Server Driver][SQL Server]无法重写文件 'D:\database\studb_Log.LDF'。数
据库 'studb' 正在使用该文件。
[Microsoft][ODBC SQL Server Driver][SQL Server]文件 '连锁销售系统_Log' 无法还原为  
'D:\database\studb_Log.LDF'。请使用 WITH MOVE 选项来标识该文件的有效位置。
[Microsoft][ODBC SQL Server Driver][SQL Server] RESTORE DATABASE 操作异常终止。

先谢谢大家了。。。
搜索更多相关主题的帖子: 请求 数据库 
2010-12-02 11:22
kevintang
Rank: 4
等 级:业余侠客
威 望:9
帖 子:799
专家分:236
注 册:2008-2-14
收藏
得分:0 
晕!你数据库正连接! 你怎么复制! 一定要分离后才能复制!

你自己到 mdf 文件所在的文件夹里面去试试!

编程少年基地——少年编程者的练兵场
http://bcsn.    招聘版主中

2010-12-02 12:34
xinyu22
Rank: 1
等 级:新手上路
帖 子:48
专家分:0
注 册:2010-11-5
收藏
得分:0 
楼上的你没有看懂我的意思。我不是直接去复制数据库的。
是这样的:
1. sql server 2000 没有打开,也没有启动任何的程序在用studb 这个数据库。  
2. 连接数据库后,用上面的备份代码先将studb这个数据库备份到c:\database.bak 后,
3. 然后我再用上面的创建数据库代码中的Dim strsql = "use master     create database " & txtDatabase.Text (后面的不写了)   新建一个 新 的数据库 即  txtDatabase.Text为新的数据库名,这个数据库不重名。(看好了,这是新建的数据库)
4. 然后将刚才的备份database.bak 还原到刚才新建的 这个新的数据库txtDatabase.Text上  (根本就没有用到studb )
   
 到这里 跟studb 已经没有关系了吧。。。。。我用的是database.bak 这个文件啊!
 就是在还原的时候,出错的。。。。。。

谢谢楼上的,再帮帮我吧 !!!!我真的是快晕了 。。。

其实我经过备份,再还原,只是起到一个修改数据库名称的作用。

studb 只是一个源文件,备份到database.bak 。
2010-12-02 16:21
yms123
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:209
帖 子:12488
专家分:19042
注 册:2004-7-17
收藏
得分:0 
[Microsoft][ODBC SQL Server Driver][SQL Server]无法重写文件 'D:\database\studb_Data.MDF'。数据库 'studb' 正在使用该文件。
[Microsoft][ODBC SQL Server Driver][SQL Server]文件 '连锁销售系统_Data' 无法还原为 'D:\database\studb_Data.MDF'。请使用 WITH MOVE 选项来标识该文件的有效位置。
[Microsoft][ODBC SQL Server Driver][SQL Server]无法重写文件 'D:\database\studb_Log.LDF'。数
据库 'studb' 正在使用该文件。
这几个错误证明你的sdudb_Data.MDF已经存在并且正在被使用
2010-12-02 16:54
xinyu22
Rank: 1
等 级:新手上路
帖 子:48
专家分:0
注 册:2010-11-5
收藏
得分:0 
版主, 我没有打开其他程序使用studb这个数据库。 如果说studb正在使用,那就是备份完了之后 ,sql server 2000 还在使用 studb  ???? 是这样的吗?   可是我已经断开连接了啊! 在备份代码的finally 块中 断开了啊。还是不是很明白,望多指点。  谢谢喽。  难不成我在杀掉进程的时候,应该杀死的是 studb 的进程????我也做过测试 ,

Dim strDBName As String = qr.GetColumnString(i, iColDbName)
If (strDBName.ToUpper() = txtDatabase.Text.ToUpper()) Then   
改为
Dim strDBName As String = qr.GetColumnString(i, iColDbName)
If (strDBName.ToUpper() = “studb”Then

 也是不可以啊。。
我的杀掉进程代码有问题吗?

  
2010-12-02 17:19
yms123
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:209
帖 子:12488
专家分:19042
注 册:2004-7-17
收藏
得分:0 
还有另一种办法就是不用备份恢复法
直接在目标服务器上创建数据库,然后直接获得数据库的所有表,遍历表将数据导入
    public  ArrayList GetTables_ADOX(string ConStr)
        {
            //ADO的数据库连接
            ArrayList tables=new ArrayList();
            ADODB.ConnectionClass cn = new ADODB.ConnectionClass();
            string ConnectionString = ConStr;
            cn.Open(ConnectionString);
            //操作ADOX的Catalog对象
            CatalogClass cat = new CatalogClass();
            cat.ActiveConnection = cn;
            for (int i = 0; i < cat.Tables.Count; i++)
            {
                //过滤系统表
                if(cat.Tables[i].Type.IndexOf("SYSTEM")==-1)
                   tables.Add(cat.Tables[i].Name);
            }
            return tables;
        }
获得指定数据库的所有表名,参数是连接字符串
需要引用ADODB和ADOX
然后
using ADODB;
using ADOX;
用SqlCommand直接创建数据库
循环创建表
public static System.Data.DbType GetDBTypeByFullName(string strTypeFullName)

        {

            switch (strTypeFullName)

            {

                case "System.Byte":

                    return System.Data.DbType.Byte;

                case "System.Boolean":

                    return System.Data.DbType.Boolean;

                case "System.Char":

                    return System.Data.DbType.Byte;

                case "System.DateTime":

                    return System.Data.DbType.DateTime;

                case "System.Decimal":

                    return System.Data.DbType.Decimal;

                 ……

                default:

                    return System.Data.DbType.Object;

            }

        }
获得字段的数据库里的数据类型
这样循环用的方式将数据全导入
2010-12-02 17:39
xinyu22
Rank: 1
等 级:新手上路
帖 子:48
专家分:0
注 册:2010-11-5
收藏
得分:0 
嗯,版主,这是办法。那我的那个方法就真的行不通吗?  


谢谢版主啦。。。。。。

大家再帮俺看看吧。。
2010-12-02 18:01
yms123
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:209
帖 子:12488
专家分:19042
注 册:2004-7-17
收藏
得分:0 
不一定备份恢复,就是直接在目标服务器上创建一个与源数据库一模一样的数据库和表,然后将数据用导入到目标数据库即可。
2010-12-02 21:25
xinyu22
Rank: 1
等 级:新手上路
帖 子:48
专家分:0
注 册:2010-11-5
收藏
得分:0 
版主,能给我你的QQ号码吗?或者你加我也可以。我的QQ号:849318643  我再试一下。
2010-12-03 08:44
xinyu22
Rank: 1
等 级:新手上路
帖 子:48
专家分:0
注 册:2010-11-5
收藏
得分:0 
最近又测试了一下,发现用sqldmo 还原的时候,只能是你在那个数据库上做的备份,然后还在这个数据库上还原,这样是没有问题的。如果数据库改名了,就不行了。   不知道我的总结对不对,有关sqldmo还原的问题  大家有别的意见和想法,可以贴出来讨论一下。分享一下。。。。。。。。。
2010-12-13 16:13
快速回复:请求帮忙,数据库的复制
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.030688 second(s), 7 queries.
Copyright©2004-2025, BCCN.NET, All Rights Reserved