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
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());
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);
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?
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
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.