How to backup MS SQL using SMO and Virtual Device - c#

Currently i am backing up a remote database via SMO. I am able to backup with DeviceType.File
I want to be able to use VirtualDevice:
Backup dbBackup = new Backup();
dbBackup.Action = BackupActionType.Database;
dbBackup.Database = "DevTarget";
BackupDeviceItem dbBackupItem = new BackupDeviceItem();
dbBackupItem.DeviceType = DeviceType.VirtualDevice;
dbBackupItem.Name = "Full_Backup_test2";
dbBackup.Devices.Add(dbBackupItem);
Has anybody ever used DeviceType.VirtualDevice if so please help as to how to use it and its features.

Related

C# - Generate Database Backup Script In-Memory

In a C# application, I know using ADO.NET we can execute a backup command like this:
BACKUP DATABASE MyDb TO DISK='C:\\MyDb.bak'
and take a database backup and store it at some given location.
I want to take backup of database in-memory i.e. return the backup script content (schema and data) which I can later save as .sql file at some location.
Is this possible?
I achieved it using SQL Server Management Objects (SMO). Thanks to all the friends who helped in comments.
First, install Microsoft.SqlServer.SqlManagementObjects from nuget package manager.
The working code:
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
var script = new StringBuilder();
Server server = new Server(new ServerConnection(new SqlConnection(connectionString)));
Database database = server.Databases[databaseName];
ScriptingOptions options = new ScriptingOptions
{
ScriptData = true,
ScriptSchema = true,
ScriptDrops = false,
Indexes = true,
IncludeHeaders = true
};
foreach (Table table in database.Tables)
{
foreach (var statement in table.EnumScript(options))
{
script.Append(statement);
script.Append(Environment.NewLine);
}
}
File.WriteAllText(backupPath + databaseName + ".sql", script.ToString());

SQL Server database restore with CDC using SQL Management Objects in C#

I am restoring a full database backup from our production server to our staging server using the Restore class in SQL Management Objects, via a C# script task in SSIS. The database I am restoring is a CDC enabled database with a number of change tables - however these tables are being dropped once the restore has completed. I know that there is a KEEP_CDC option in the TSQL Restore command but I can't seem to find an equivalent property in SMO. Is there a way that I can do the restore using SMO whilst retaining the CDC capture instance? This is my code:
Server srv;
srv = new Server();
//kill all connections to the database prior to restore
srv.KillAllProcesses(databaseName);
Restore res = new Restore();
res.Database = databaseName;
res.Action = RestoreActionType.Database;
res.Devices.AddDevice(filePath, DeviceType.File);
res.ReplaceDatabase = true;
res.ReadFileList(srv);
DataTable filelist = res.ReadFileList(srv);
foreach (DataRow row in filelist.Rows)
{
string logicalFileName = Path.GetFileName(row["LogicalName"].ToString());
string physicalFileName = Path.GetFileName(row["PhysicalName"].ToString());
switch (Path.GetFileName(row["Type"].ToString()))
{
case "D":
res.RelocateFiles.Add(new RelocateFile(logicalFileName, Path.Combine(DataFilePath, physicalFileName)));
break;
case "L":
res.RelocateFiles.Add(new RelocateFile(logicalFileName, Path.Combine(LogFilePath, physicalFileName)));
break;
}
}
res.SqlRestore(srv);

Trying to restore remote database

I'm trying to restore a .bak file on a remote sql server but i'm getting
Cannot open backup device .bak Operating system error 21(The device is not ready.). RESTORE DATABASE is terminating abnormally.
This is what i tried
var restore = new Restore();
restore.Database = databaseName;
restore.Action = RestoreActionType.Database;
restore.Devices.AddDevice(backUpFilePath, DeviceType.File);
restore.ReplaceDatabase = true;
restore.NoRecovery = false;
var sqlConnection = new SqlConnection(ConnectionString);
var serverConnection = new ServerConnection(sqlConnection);
var sqlServer = new Server(serverConnection);
restore.SqlRestore(sqlServer);
I believe the error message is quite vague, in that it can mean a number of different things.
Are you able to restore that .bak outside of your application in SQL Server? Do the SQL Error logs give any more specific information?

Sql server SMO partial backup

I have a database in SQL Server 2008 R2, that uses the Simple recovery model.
The database contains a filegroup, where the bulk of the data resides (>20GB of images). These images are not critical for the application.
I want to backup the database from C# using Sql Server SMO. But I only want to backup the database structure (the PRIMARY filegroup; everything except the non-essential images). I want to do this in order to keep the backup size small.
In my C# code, I am setting the backup action to BackupActionType.Files, and I am only including the PRIMARY filegroup inside the DatabaseFileGroups collection, so it should only backup the database structure, and not the images.
But when I run the backup, I get this exception:
System.Data.SqlClient.SqlError: The primary filegroup cannot be backed up as a file backup because the database is using the SIMPLE recovery model. Consider taking a partial backup by specifying READ_WRITE_FILEGROUPS.
My question is, how can I specify READ_WRITE_FILEGROUPS from inside C# code, using Sql Server SMO? The exception shows me how to do so in T-SQL, but I want to do the same thing in C#.
Here is the code I am using:
class Program
{
static string DbName = PATH_TO_DATABASE;
static string connString = CONNECTION_STRING;
static void Main(string[] args)
{
ServerConnection serverConn = new ServerConnection();
serverConn.ConnectionString = connString;
Server server = new Server(serverConn);
Backup backup = new Backup() { Database = DbName };
backup.Action = BackupActionType.Files;
backup.DatabaseFileGroups.Add("PRIMARY");
backup.Devices.AddDevice("D:\\backup.bak", DeviceType.File);
backup.Initialize = true;
backup.ContinueAfterError = false;
backup.Incremental = false;
backup.Complete += (snd, e) => { Console.WriteLine("Complete"); };
backup.PercentComplete += (snd, e) => { Console.WriteLine("Percent " + e.Percent); };
backup.SqlBackup(server);
serverConn.Disconnect();
}
}
solution is very simple.
Just in SQLSERVER rigth-click on database and in Properties Window in Option tab change Recovery Mode To Bulk-logged
secound Solution by T-SQL:
USE [master]
GO
ALTER DATABASE [databasename] SET RECOVERY BULK_LOGGED WITH NO_WAIT
GO

How to do backup in C# application?

I will try to do a backup database from C# application. I found more tutorials how do that. In the new project copy some solution and run. All the time I got one connection error like:
"backup failed for server ".
In this line:
source.SqlBackup(server);
Do you know how I resolve this? I think that problem concerns connection to server (it's broken?).
Below you can see a Backup method:
public static void BackupDatabase(string backUpFile)
{
ServerConnection con = new ServerConnection(#".\SQLEXPRESS");
Server server = new Server(con);
Backup source = new Backup();
source.Action = BackupActionType.Database;
source.Database = "DB";
BackupDeviceItem destination = new BackupDeviceItem(backUpFile, DeviceType.File);
source.Devices.Add(destination);
source.SqlBackup(server);
con.Disconnect();
MessageBox.Show("Kopia wykonana!");
}
Couple of things for you to try.
Make sure your database name is correct
source.Database = "DB"; // Check the database name is actually 'DB'.
I had some issues in the past using ServerConnection with a connection string, even though the syntax allows you to do so. What i did was to create an SqlConnection from the connection string and then give that to ServerConnection.
string connectionString = "Your connection string goes here";
SqlConnection sqlCon = new SqlConnection(connectionString);
ServerConnection connection = new ServerConnection(sqlCon);
I would also try initializing the backup object.
source.Initialize = true;
Added full control for PC Users to the backup folder on C:\ drive helped! Thanks all for help! But just I have one question: how I can modify above C# code that program should be yourself create backup folder on C:\ and do a copy database? Currently I must do it manually.

Categories