2009-09-23 23 views
14

Tengo un SQL 2008 DB. Estoy ejecutando un formulario que respalda ese DB, luego intenta actualizarlo. Si la actualización falla, la idea es restaurar esa copia de seguridad. Aquí está el código que estoy usando para restaurar la copia de seguridad.Cómo restaurar una base de datos desde C#

public void RestoreDatabase(String databaseName, String backUpFile, String serverName, String userName, String password) 
{ 
    Restore sqlRestore = new Restore(); 
    BackupDeviceItem deviceItem = new BackupDeviceItem(backUpFile, DeviceType.File); 
    sqlRestore.Devices.Add(deviceItem); 
    sqlRestore.Database = databaseName; 
    ServerConnection connection = new ServerConnection(serverName, userName, password); 
    Server sqlServer = new Server(connection); 
    sqlRestore.Action = RestoreActionType.Database; 

    string logFile = System.IO.Path.GetDirectoryName(backUpFile); 
    logFile = System.IO.Path.Combine(logFile, databaseName + "_Log.ldf"); 

    string dataFile = System.IO.Path.GetDirectoryName(backUpFile); 
    dataFile = System.IO.Path.Combine(dataFile, databaseName + ".mdf"); 

    Database db = sqlServer.Databases[databaseName]; 
    RelocateFile rf = new RelocateFile(databaseName, dataFile); 
    sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName, dataFile)); 
    sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName + "_log", logFile)); 
    sqlRestore.SqlRestore(sqlServer); 
    db = sqlServer.Databases[databaseName]; 
    db.SetOnline(); 
    sqlServer.Refresh(); 
} 

El problema parece ser que los nombres de archivo que selecciono son diferentes a los de la base de datos en línea. Básicamente, quiero reemplazar la base de datos en el servidor con la copia de seguridad. Obtengo una excepción cuando llamo a SqlRestore.

La principal excepción dice

{ "Error en la restauración para el servidor 'localhost'."}

Excavando en las excepciones internas muestra estos errores

ha producido una excepción al ejecutar una instrucción o lote de Transact-SQL.

y luego

archivo lógico 'DB' no es parte de la base de datos 'DB'. Utilice RESTORE FILELISTONLY para listar el archivo lógico nombres. \ R \ nRESTORE DATABASE es terminando anormalmente.

Supongo que hay alguna manera de decir que simplemente use reemplazar el DB existente como está.

Utilizo este código para que la ruta del archivo del DB tenga un directorio para volcar la copia de seguridad. Tal vez esto podría usarse para hacer que los nombres de los archivos se vuelvan a crear.

public string GetDBFilePath(String databaseName, String userName, String password, String serverName) 
{ 
    ServerConnection connection = new ServerConnection(serverName, userName, password); 
    Server sqlServer = new Server(connection); 
    Database db = sqlServer.Databases[databaseName]; 
    return sqlServer.Databases[databaseName].PrimaryFilePath; 
} 

Respuesta

18

he cambiado de copia de seguridad y restaurar las funciones a tener este aspecto:

public void BackupDatabase(SqlConnectionStringBuilder csb, string destinationPath) 
{ 
    ServerConnection connection = new ServerConnection(csb.DataSource, csb.UserID, csb.Password); 
    Server sqlServer = new Server(connection); 

    Backup bkpDatabase = new Backup(); 
    bkpDatabase.Action = BackupActionType.Database; 
    bkpDatabase.Database = csb.InitialCatalog; 
    BackupDeviceItem bkpDevice = new BackupDeviceItem(destinationPath, DeviceType.File); 
    bkpDatabase.Devices.Add(bkpDevice); 
    bkpDatabase.SqlBackup(sqlServer); 
    connection.Disconnect(); 

} 

public void RestoreDatabase(String databaseName, String backUpFile, String serverName, String userName, String password) 
{ 
    ServerConnection connection = new ServerConnection(serverName, userName, password); 
    Server sqlServer = new Server(connection); 
    Restore rstDatabase = new Restore(); 
    rstDatabase.Action = RestoreActionType.Database; 
    rstDatabase.Database = databaseName; 
    BackupDeviceItem bkpDevice = new BackupDeviceItem(backUpFile, DeviceType.File); 
    rstDatabase.Devices.Add(bkpDevice); 
    rstDatabase.ReplaceDatabase = true; 
    rstDatabase.SqlRestore(sqlServer); 
} 

De esa manera sólo tiene que utilizar cualquier archivos están ahí. Ya no hay más y las directivas para reubicar los archivos.

+3

No necesita reubicar archivos si restaura desde una copia de seguridad de la misma base de datos en la misma máquina.La reubicación solo es necesaria cuando se mueven y copian bases de datos a través de una copia de seguridad/restauración. –

+3

Ok, aquí algunos consejos: con respecto a la ruta del archivo de copia de seguridad, siempre preste atención si el archivo realmente existe en su carpeta de origen. Con respecto a la reubicación, podría ser un problema de permiso para escribir un archivo mdf. Preste atención si su aplicación tiene permiso para leer el archivo .bak, en este caso, consulte el Administrador de configuración SQL: el servicio MSSQLServer debe ejecutarse bajo el usuario LocalSystem. –

4

Está añadiendo RelocateFile opciones basándose en el nombre de base de datos, esto es incorrecto. Debe agregarlos en función del nombre del archivo lógico para cada archivo reubicado. Use Restore.ReadFileList para recuperar la lista de nombres de archivos lógicos.

+0

Parece que no puedo agregar todas estas opciones. –

12

¡Gracias Remus por su respuesta!

he modificado

sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName, dataFileLocation)); 
sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName + "_log", logFileLocation)); 

estas dos líneas a

System.Data.DataTable logicalRestoreFiles = sqlRestore.ReadFileList(sqlServer); 
sqlRestore.RelocateFiles.Add(new RelocateFile(logicalRestoreFiles.Rows[0][0].ToString(), dataFileLocation)); 
sqlRestore.RelocateFiles.Add(new RelocateFile(logicalRestoreFiles.Rows[1][0].ToString(), logFileLocation)); 

y mi código se ejecuta con éxito.

¡Gracias por el apoyo!

+0

@Pallavi Tu solución funcionó de inmediato para mí ... Pero no puedo entender la solución. ¿Podrías informar tu respuesta de solución? –

+1

Esta solución fue perfecta para mí también. Para aquellos que desean más, lo que localRestoreFiles contiene es la base de datos de origen "Lista de archivos". La lista de archivos de esa base de datos, como todos los MDF, los registros y los archivos de índice que se crearon. Sin embargo, estos números de Filas [X] suponen que tiene una base de datos normal con solo 1 MDF y 1 LDF (por ejemplo, sin registros adicionales ni archivos de índice). Si ese es el caso, Filas [0] contiene el primer archivo MDF, Filas [1] será el archivo de registro. Y Filas [0] [0] y Filas [1] [0] contendrán el nombre de la base de datos lógica (que es el caso sensorial!) Que puede usar para "mover". – eduncan911

Cuestiones relacionadas