Is it possible to backup a remote bd sql server via c#?

Asked

Viewed 1,608 times

4

I am using Assembly Microsoft.SqlServer.Management.Smo to back up an Sql Server database to c#. The problem is that the way it is implemented I can only perform the action if I am running the application on the same database server.

I was wondering if it is possible to perform the backup remotely?

My example is based on this msdn link. Follow the code below:

    using Microsoft.SqlServer.Management.Common;
    using Microsoft.SqlServer.Management.Smo;

class A {
   public static void Main() {
      // Connect to the local, default instance of SQL Server. 
      Server srv = new Server();
      // Reference the AdventureWorks2012 database. 
      Database db = default(Database);
      db = srv.Databases["AdventureWorks2012"];

      // Store the current recovery model in a variable. 
      int recoverymod;
      recoverymod = (int)db.DatabaseOptions.RecoveryModel;

      // Define a Backup object variable. 
      Backup bk = new Backup();

      // Specify the type of backup, the description, the name, and the database to be backed up. 
      bk.Action = BackupActionType.Database;
      bk.BackupSetDescription = "Full backup of Adventureworks2012";
      bk.BackupSetName = "AdventureWorks2012 Backup";
      bk.Database = "AdventureWorks2012";

      // Declare a BackupDeviceItem by supplying the backup device file name in the constructor, and the type of device is a file. 
      BackupDeviceItem bdi = default(BackupDeviceItem);
      bdi = new BackupDeviceItem("Test_Full_Backup1", DeviceType.File);

      // Add the device to the Backup object. 
      bk.Devices.Add(bdi);
      // Set the Incremental property to False to specify that this is a full database backup. 
      bk.Incremental = false;

      // Set the expiration date. 
      System.DateTime backupdate = new System.DateTime();
      backupdate = new System.DateTime(2006, 10, 5);
      bk.ExpirationDate = backupdate;

      // Specify that the log must be truncated after the backup is complete. 
      bk.LogTruncation = BackupTruncateLogType.Truncate;

      // Run SqlBackup to perform the full database backup on the instance of SQL Server. 
      bk.SqlBackup(srv);

      // Inform the user that the backup has been completed. 
      System.Console.WriteLine("Full Backup complete.");

      // Remove the backup device from the Backup object. 
      bk.Devices.Remove(bdi);

      // Make a change to the database, in this case, add a table called test_table. 
      Table t = default(Table);
      t = new Table(db, "test_table");
      Column c = default(Column);
      c = new Column(t, "col", DataType.Int);
      t.Columns.Add(c);
      t.Create();

      // Create another file device for the differential backup and add the Backup object. 
      BackupDeviceItem bdid = default(BackupDeviceItem);
      bdid = new BackupDeviceItem("Test_Differential_Backup1", DeviceType.File);

      // Add the device to the Backup object. 
      bk.Devices.Add(bdid);

      // Set the Incremental property to True for a differential backup. 
      bk.Incremental = true;

      // Run SqlBackup to perform the incremental database backup on the instance of SQL Server. 
      bk.SqlBackup(srv);

      // Inform the user that the differential backup is complete. 
      System.Console.WriteLine("Differential Backup complete.");

      // Remove the device from the Backup object. 
      bk.Devices.Remove(bdid);

      // Delete the AdventureWorks2012 database before restoring it
      // db.Drop();

      // Define a Restore object variable.
      Restore rs = new Restore();

      // Set the NoRecovery property to true, so the transactions are not recovered. 
      rs.NoRecovery = true;

      // Add the device that contains the full database backup to the Restore object. 
      rs.Devices.Add(bdi);

      // Specify the database name. 
      rs.Database = "AdventureWorks2012";

      // Restore the full database backup with no recovery. 
      rs.SqlRestore(srv);

      // Inform the user that the Full Database Restore is complete. 
      Console.WriteLine("Full Database Restore complete.");

      // reacquire a reference to the database
      db = srv.Databases["AdventureWorks2012"];

      // Remove the device from the Restore object.
      rs.Devices.Remove(bdi);

      // Set the NoRecovery property to False. 
      rs.NoRecovery = false;

      // Add the device that contains the differential backup to the Restore object. 
      rs.Devices.Add(bdid);

      // Restore the differential database backup with recovery. 
      rs.SqlRestore(srv);

      // Inform the user that the differential database restore is complete. 
      System.Console.WriteLine("Differential Database Restore complete.");

      // Remove the device. 
      rs.Devices.Remove(bdid);

      // Set the database recovery mode back to its original value.
      db.RecoveryModel = (RecoveryModel)recoverymod;

      // Drop the table that was added. 
      db.Tables["test_table"].Drop();
      db.Alter();

      // Remove the backup files from the hard disk.
      // This location is dependent on the installation of SQL Server
      System.IO.File.Delete("C:\\Program Files\\Microsoft SQL Server\\MSSQL12.MSSQLSERVER\\MSSQL\\Backup\\Test_Full_Backup1");
      System.IO.File.Delete("C:\\Program Files\\Microsoft SQL Server\\MSSQL12.MSSQLSERVER\\MSSQL\\Backup\\Test_Differential_Backup1");
   }
}

3 answers

5

If you want to back up a base on MS-Sql Server remotely so that the backup files are created on your computer, I am sorry to inform you that this is not possible. You can perform a remote backup by script but the files will only be created locally (in the location of the database, ie on the server).

There are other ways to accomplish this by creating scripts that reflect the database you are trying to back up, follow the Soen link on the same issue: How can I backup a remote SQL Server database to a local drive?

@Edit: To back up an SQL base remotely via C# you can connect to the base and run a script containing the backup routine you need. One way to generate this script is by manually backing up, but before clicking the backup screen OK, click the "Script" button on the top bar of the backup window. This will open a script with all the syntax needed to perform the backup as you want. To illustrate, here is an example I use:

C#:

public static void FazerBackup(string dataBase, string diretorio, string nomeAquivo)
{
    string connectionString = WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
    using (SqlConnection conexao = new SqlConnection(connectionString))
    using (SqlCommand comando = new SqlCommand("RealizaBackup", conexao))
    {
        comando.Parameters.AddWithValue("@DATABASE", dataBase);
        comando.Parameters.AddWithValue("@DIRETORIO", diretorio);
        comando.Parameters.AddWithValue("@NOMEARQUIVO", nomeAquivo);
        if (conexao.State != ConnectionState.Open)
            conexao.Open();
        comando.ExecuteNonQuery();
    }
}

Procedure "Realizabackup":

CREATE PROCEDURE [dbo].[RealizaBackup]
    @database           VARCHAR(MAX) = NULL,
    @diretorio          VARCHAR(MAX) = NULL,
    @nomeArquivo        VARCHAR(MAX) = NULL
AS
BEGIN
    DECLARE  @sqlCommand NVARCHAR(MAX)
    IF RIGHT(@diretorio,1) != '\'
      SET @diretorio = @diretorio + '\'
    SELECT @sqlCommand = 'BACKUP DATABASE ' + @database + ' TO DISK = ' +
        CHAR(39) + @diretorio + @nomeArquivo + CHAR(39) + 'WITH NOFORMAT, NOINIT, NAME = N' + 
        CHAR(39) + @database + '-FULL DATABASE BACKUP' + CHAR(39) + ', SKIP, NOREWIND, NOUNLOAD, STATS = 10'
    PRINT @SQLCOMMAND
    EXEC SP_EXECUTESQL @sqlCommand 
END
  • thanks for the answer, but I need to perform this backup in a c#application. In fact I was wondering if it is possible to carry out the action that today I am doing remotely.

  • If I just create the backup, I can update the response and include the script I use to back up the database from C#, but as I said before this backup will only be created on the database server.

  • I think it’s interesting, but it’s outside the scope of the question.

  • Do not run away no, after all it is the implementation of what you want, carry out the backup of a database mssql by C#. I will update the reply soon.

  • When I spoke flees is that the question refers to performing the backup remotely. But I believe that would be an option more. Thank you!

  • @psNytrancez Do you want to save Backup to a machine other than the server? " Backup remotely" can be interpreted in many ways, I understood that you want to backup from another machine, and the files will be saved on the server.

  • 1

    @Hstackoverflow That’s right, at first I understood that he wanted to create the files on the computer that was running the program, but by the way he just wants to run a backup. For this I updated my reply and added a method to perform such backup.

  • Actually I want to be able to backup and restore the backup remotely, the file and backup can get on the same bank machine.

  • @psNytrancez with my answer is already possible to backup the database, to do the Restore just change the Procedure script so that it reflects your Restore script, understood? Is there anything else I can help you with? It didn’t work?

Show 4 more comments

3

Alternative without Procedure
Obs: Change NOMEBD of command SQL to the name of the bank.

using System;
using System.Data.SqlClient;

namespace teste
{
    class Program
    {
        private const string Sqlconnection = @"Server=192.168.0.1;DataBase=master;user id=sa;password=xxx;Connection Timeout=0";

        static void Main(string[] args)
        {
            BackupFullDIff();
        }

        public static void BackupFullDIff()
        {
            var localPastaCopia = @"c:\copia";
            var sqlConn = new SqlConnection(Sqlconnection);
            sqlConn.Open();

            //BACKUP FULL
            var comandoSql =
                string.Format("BACKUP DATABASE NOMEBD TO DISK='{0}' WITH  INIT ,  " +
                              "NOUNLOAD ,  NAME = N'NOMEBD backup',  " +
                              "NOSKIP ,  STATS = 10,  NOFORMAT ", localPastaCopia + @"\minhaCopiaFull.BAK");
            var sqlComm = new SqlCommand { Connection = sqlConn, CommandText = comandoSql, CommandTimeout = 0 };
            sqlComm.ExecuteNonQuery();

            //BAKUP DIFERENCIAL
            comandoSql =
            string.Format("BACKUP DATABASE NOMEBD TO DISK='{0}' WITH  INIT ,  " +
                      "NOUNLOAD ,  DIFFERENTIAL ,  NAME = N'NOMEBD backup',  " +
                      "NOSKIP ,  STATS = 10,  NOFORMAT ", localPastaCopia + @"\minhaCopiaDIFF.BAK");
            sqlComm = new SqlCommand { Connection = sqlConn, CommandText = comandoSql, CommandTimeout = 0 };
            sqlComm.ExecuteNonQuery();

            var localPastaRestauraBd = @"c:\dados_restaura";
            //RESTORE FULL
            comandoSql =
                String.Format("RESTORE DATABASE {0} " +
                "FROM DISK='{1}' " +
                "WITH RECOVERY, " +
                "MOVE 'NOMEBD_data' TO '{2}\\NOMEBD_Data.MDF', " +
                "MOVE 'NOMEBD_log'  TO '{2}\\NOMEBD_Log.LDF'", "NOMEBD", localPastaCopia + @"\minhaCopiaFull.BAK", localPastaRestauraBd);
            sqlComm = new SqlCommand { Connection = sqlConn, CommandText = comandoSql, CommandTimeout = 0 };
            sqlComm.ExecuteNonQuery();

            //RESTORE FULL e DIFF
            /*
            comandoSql =
                String.Format("RESTORE DATABASE {0} " +
                "FROM DISK='{1}' " +
                "WITH NORECOVERY, " +
                "MOVE 'NOMEBD_data' TO '{2}\\NOMEBD_Data.MDF', " +
                "MOVE 'NOMEBD_log'  TO '{2}\\NOMEBD_Log.LDF'", "NOMEBD", localPastaCopia + @"\minhaCopiaFull.BAK", localPastaRestauraBd);
            sqlComm = new SqlCommand { Connection = sqlConn, CommandText = comandoSql, CommandTimeout = 0 };
            sqlComm.ExecuteNonQuery();

            comandoSql =
            String.Format("RESTORE DATABASE {0} " +
            "FROM DISK='{1}' " +
            "WITH RECOVERY, " +
            "MOVE 'NOMEBD_data' TO '{2}\\NOMEBD_Data.MDF', " +
            "MOVE 'NOMEBD_log'  TO '{2}\\NOMEBD_Log.LDF'", "NOMEBD", localPastaCopia + @"\minhaCopiaDiff.BAK", localPastaRestauraBd);
            sqlComm = new SqlCommand { Connection = sqlConn, CommandText = comandoSql, CommandTimeout = 0 };
            sqlComm.ExecuteNonQuery();
            */

        }
    }
}

1


I thank @Hstackoverflow and @Marciano.Andrade for the alternative solutions, but I managed to solve it with the code I had posted.

The only part I changed was in the Server instance having added a connection. Below is how it looked.

String connectionString = "Data Source=127.0.0.0;Initial Catalog=minhaBase;User Id=sa;Password=12344567;";
SqlConnection sqlConnection = new SqlConnection(connectionString);
ServerConnection conn = new ServerConnection(sqlConnection);
// Connect to the local, default instance of SQL Server. 
Server srv = new Server(conn);

Browser other questions tagged

You are not signed in. Login or sign up in order to post.