代码之家  ›  专栏  ›  技术社区  ›  Mathias F

正在尝试分离附加数据库-无法在之后访问数据库

  •  5
  • Mathias F  · 技术社区  · 15 年前

    我试着做到以下几点:

    • 将文件复制到临时文件夹

    • 再次附加数据库

    “尝试将请求发送到服务器时出现传输级别错误。(提供程序:共享内存提供程序,错误:0-管道的另一端没有进程。)”,当我尝试从新连接的数据库的sys.database_文件中读取数据时。

    该错误翻译自德语“Fehler auf bertragungsebene beim Senden der anfordung an den Server”

    它发生在“cmdGetDBFileName.ExecuteReader”之后。我仍然可以打开连接,但查询sys.database_文件失败。

    源代码相当长,但我想您可以跳过开头的部分,在那里我可以分离数据库的文件名。你看到我的错误了吗?或者你知道我可以检查什么吗?

    public bool DetachB2CPrepare()
            {
                _log.Debug("DetachB2CPrepare");
                SqlConnection prepareDBConnection = null;
                SqlConnection prepareMasterDBConnection = null;
                SqlDataReader readerDbFiles = null;
    
                bool result = true;
                try
                {
                    //rc_b2c_product_prepare.mdf    
                    string prepareDBPysicalFileName = "";
                    //rc_b2c_product_prepare    
                    string prepareDBFileName = "";
                    //D:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\rc_b2c_product_prepare.mdf
                    string prepareDBFileNameComplete = "";
    
                    //rc_b2c_product_prepare_1.ldf  
                    string prepareTransactionLogPhysicalFileName = "";
                    //rc_b2c_product_prepare_log    
                    string prepareTransactionLogFileName = "";
                    //D:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\rc_b2c_product_prepare_1.ldf
                    string prepareTransactionLogFileNameComplete = "";
                    _log.DebugFormat("Try to open B2CPrepare");
                    prepareDBConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["B2CPrepare"].ConnectionString);
                    prepareDBConnection.Open();
    
    
    
                    //Get the file names  of DB
                    SqlCommand cmdGetDBFileName = new SqlCommand("select name , physical_name, type from sys.database_files where type= 0");
                    cmdGetDBFileName.Connection = prepareDBConnection;
                    readerDbFiles = cmdGetDBFileName.ExecuteReader();
                    if (readerDbFiles.Read())
                    {
                        prepareDBFileName = (string)readerDbFiles["name"];
                        prepareDBFileNameComplete = (string)readerDbFiles["physical_name"];
                        int lastSlash = prepareDBFileNameComplete.LastIndexOf(@"\");
                        prepareDBPysicalFileName = prepareDBFileNameComplete.Substring(lastSlash + 1, prepareDBFileNameComplete.Length - lastSlash - 1);
                        readerDbFiles.Close();
                    }
                     else{
                         return false;
                     }
    
                    cmdGetDBFileName.CommandText = "select name , physical_name, type from sys.database_files where type= 1";
                    readerDbFiles = cmdGetDBFileName.ExecuteReader();
                    if (readerDbFiles.Read())
                    {
                        prepareTransactionLogFileName = (string)readerDbFiles["name"];
                        prepareTransactionLogFileNameComplete = (string)readerDbFiles["physical_name"];
                        int lastSlash = prepareTransactionLogFileNameComplete.LastIndexOf(@"\");
                        prepareTransactionLogPhysicalFileName = prepareTransactionLogFileNameComplete.Substring(lastSlash + 1, prepareTransactionLogFileNameComplete.Length - lastSlash - 1);
                        readerDbFiles.Close();
                    }
                    else
                    {
                        return false;
                    }
    
                    _log.DebugFormat("shrink transactionlog {0}", prepareTransactionLogFileName);
    
                    SqlCommand cmdShrinkPrepare = new SqlCommand(string.Format(@"DBCC Shrinkfile('{0}',100) ", prepareTransactionLogFileName));
                    cmdShrinkPrepare.Connection = prepareDBConnection;
                    cmdShrinkPrepare.ExecuteNonQuery();
    
                    //master auf MyProductName
                    prepareMasterDBConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyProductNameMaster"].ConnectionString);
                    prepareMasterDBConnection.Open();
    
                    _log.Debug("cmdOffline");
    
                    //Datenbank verbindunge löschen 
                    SqlCommand cmdOffline = new SqlCommand(@"ALTER DATABASE rc_b2c_product_prepare SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
                    cmdOffline.Connection = prepareMasterDBConnection;
                    cmdOffline.ExecuteNonQuery();
    
                    _log.Debug("cmdDetach: rc_b2c_product_prepare"  );
    
                    SqlCommand cmdDetach = new SqlCommand(@"dbo.sp_detach_db @dbname = N'rc_b2c_product_prepare',@keepfulltextindexfile = N'false'");
                    cmdDetach.Connection = prepareMasterDBConnection;
                    cmdDetach.ExecuteNonQuery();
    
                    string pathForCopies = MyProductName.Backend.settings.B2CPrepareDBBackupPath;
    
                    //copy files to temp folder
                    string tempFileDB = pathForCopies + "\\" + prepareDBPysicalFileName;
                    string tempFileLog = pathForCopies + "\\" + prepareTransactionLogPhysicalFileName;
    
                    _log.DebugFormat("Copy: {0} TO: {1}", prepareDBFileNameComplete, tempFileDB);
    
                    System.IO.File.Copy(prepareDBFileNameComplete, tempFileDB, true);
    
                    _log.DebugFormat("Copy: {0} TO: {1}", prepareTransactionLogFileNameComplete, tempFileLog);
    
                    System.IO.File.Copy(prepareTransactionLogFileNameComplete, tempFileLog, true);
    
                    _log.DebugFormat("cmdAttach: db {0} log {1}", prepareDBFileNameComplete, prepareTransactionLogFileNameComplete);
    
                    SqlCommand cmdAttach = new SqlCommand( 
                            string.Format(@"
                            CREATE DATABASE rc_b2c_product_prepare ON
                            ( FILENAME = N'{0}' ),
                            ( FILENAME = N'{1}' )
                            FOR ATTACH", prepareDBFileNameComplete, prepareTransactionLogFileNameComplete));
    
                    cmdAttach.Connection = prepareMasterDBConnection;
                    cmdAttach.ExecuteNonQuery();
    
                    _log.Debug("ALTER DATABASE rc_b2c_product_prepare SET MULTI_USER ");
    
                    //set multi user 
                    SqlCommand cmdOnline = new SqlCommand(@"ALTER DATABASE rc_b2c_product_prepare SET MULTI_USER WITH ROLLBACK IMMEDIATE");
                    cmdOnline.Connection = prepareMasterDBConnection;
                    cmdOnline.ExecuteNonQuery();
    
                    return result;
                }
                catch (Exception e)
                {
                    _log.Error(e);
                    return false;
                }
                finally
                {
                    if (prepareDBConnection != null)
                    {
                        prepareDBConnection.Close();
                    }
                    if (prepareMasterDBConnection != null)
                    {
                        prepareMasterDBConnection.Close();
                    }
                    if (readerDbFiles != null)
                    {
                        readerDbFiles.Close();
                    }
                }
            }
    
    3 回复  |  直到 15 年前
        1
  •  1
  •   Moe Sisko    15 年前

    您可以尝试关闭连接池,看看这是否是问题所在。为此,在配置文件中的SQL连接字符串中添加“Pooling=false”。

        2
  •  1
  •   AxelEckenberger    15 年前

    连接池可能有问题,您是否尝试关闭连接池 prepareDBConnection 在执行分离/连接之前?

    SMO )-这是一个 example for the detach/attach

    第三,当您只想创建备份副本时,不必分离数据库,您可以将其设置为脱机。 Using SMO using SQL ( sp_dboption doc ).

        3
  •  0
  •   Pranesh Janarthanan    9 年前

    USE master;
    GO
    ALTER DATABASE [AdventureWorks2012] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    EXEC sp_detach_db @dbname = N'AdventureWorks2012';
    GO
    

    附加分离的数据库的步骤

    USE master;
    GO
    CREATE DATABASE MyAdventureWorks
    ON (FILENAME = 'C:\MySQLServer\AdventureWorks2012_Data.mdf'),
    (FILENAME = 'C:\MySQLServer\AdventureWorks2012_Log.ldf')
    FOR ATTACH;
    GO
    

    我在多个数据库中尝试了这段代码,效果很好。