I've written a Windows application which uses the Sql Express database server.
How can I programatically backup and restore the database through my application?
You could have your application launch a .sql file that does the backing up or restoring for you. Granted, I've mostly seen this done in a Scheduled Task, but I suppose you could do it from a triggered event inside your app.
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "C:\\path\\to\\backup.sql";
p.Start();
UPDATE:
As pointed out in the comments, this won't work if you don't have SQL Management Studio installed on the server. Alternatively, you could call a stored procedure. Upon reflecting, I'm not sure why I didn't suggest the stored proc first - probably because the other methodology was fresh on my brain due to being forced to implement it that way in a previous project.
You can request a backup from within your app by executing:
#"BACKUP DATABASE [MyDBName] TO DISK = 'c:\somedir\MyDBName.bak' WITH INIT" (ref)
Or use SQL SMO Objects SqlBackup() directly.
You could use SQL Server Management Objects
First add a reference in your project to: Microsoft.SqlServer.Smo.dll, Microsoft.SqlServer.SmoExtended.dll, Microsoft.SqlServer.SqlEnum.dll and Microsoft.SqlServer.SmoEnum.dll.
After that to Backup your Database follow this sample:
//Connect to the server
Server srv = new Server();
//If Sql Server is not local or is a named instance you could do
//Server srv = new Server("SERVERNAME");
Database db = srv.Databases("YourDB");
//Create a backup definition
Backup backup = new Backup();
backup.Action = BackupActionType.Database;
backup.BackupSetDescription = "Full backup of Adventureworks2008R2";
backup.BackupSetName = "My app Backup";
backup.Database = "YourDB";
//Configure the backup device
BackupDeviceItem backupDevice = new BackupDeviceItem("YourDB.bak", DeviceType.File);
backup.Devices.Add(backupDevice);
//Specify wether do a full backup or not
backup.Incremental = false;
//Specify log truncation mode
backup.LogTruncation = BackupTruncateLogType.Truncate;
//Do the backùp
backup.SqlBackup(srv);
Related
I want to backup my remote SQL Server database onto the local computer.
So far I've tried:
using (SqlConnection defaultSqlConnection = new SqlConnection(Constants.Database_Constants.GetConnectionStringFromProfile(Constants.Profiles.Staging)))
{
string pathDatabase = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\backup_production_database"+DateTime.UtcNow.ToString("d_MMM_yyyy_HH_mm_ss", CultureInfo.InvariantCulture)+".bak";
WriteLine("The backup will be stored in " + pathDatabase);
string backupDb = "BACKUP DATABASE DB_Staging TO DISK = '" + pathDatabase+ "' WITH INIT, COMPRESSION";
File.Create(pathDatabase);
using (SqlCommand backupCommand = new SqlCommand(backupDb, defaultSqlConnection))
{
defaultSqlConnection.Open();
backupCommand.ExecuteNonQuery();
}
}
But I get this error :
Cannot open backup device 'XXXX\bin\Debug\backup_production_database22_Mar_2017_08_04_42.bak'.
Operating system error 3(The system cannot find the path specified.).
BACKUP DATABASE is terminating abnormally.
I know that I could generate a script using SQL Server Management Studio but it doesn't help me. I want to backup my database in a powershell script automatically without having to go manually into SQL Server Management Studio
You cannot create a directly backup from a remote server to a local disk.
Please look this link.
I am trying to restore a database backup file (.bak) to a newly created database using C#. I get the following inner exception:
Cannot open backup device '\GC.bak'. Operating system error 5 (Access is denied.).
RESTORE DATABASE is terminating abnormally
My server is a localDB.
void RestoreDB(string name)
{
var connection = new ServerConnection(Properties.Settings.Default.Well);
var sqlServer = new Server(connection);
var rstDatabase = new Restore();
rstDatabase.Database = name;
rstDatabase.Action = RestoreActionType.Database;
rstDatabase.Devices.AddDevice(AppDomain.CurrentDomain.BaseDirectory + "GC.bak", DeviceType.File);
rstDatabase.ReplaceDatabase = true;
rstDatabase.SqlRestore(sqlServer);
}
By default SQL Server only has access to a few specific places on the server drive (i.e. the default database and backup folder locations). It looks like you are probably trying to restore the file from a non-standard location, so you either need to grant permissions to the service account that SQL server is running under to that directory, or even easier, copy the backup file into the regular backup file location and try again.
So I've written a simple exe that will extract sql files from a zipped folder and open them in SQL Server Studio. It works great except that sometimes there will be multiple sql files to open, which then causes multiple SQL Server Instances to open. How can I make the files all open in one instance?
This is what I'm trying so far:
foreach (string sqlFile in files)
{
Process sqlServer;
if (Process.GetProcessesByName("Ssms").Length > 0)
sqlServer = Process.GetProcessesByName("Ssms")[0];
else
sqlServer = new Process();
sqlServer.StartInfo.FileName = sqlFile;
sqlServer.Start();
}
Sometimes a file will magically open in an existing SQL Server window but I haven't figured out why.
I couldn't find any way to use an existing SSMS (sorry!), but fortunately, I found SSMS command line very useful. It can be fed with the name of the server and/or the instance to connect with switch -S. It also logins with Windows Authentication with switch -E. Take a look at its options via SSMS /? and choose what fits your problem best. Anyway I tested the following code with and without a pre-existing SSMS instance connected/disconnected:
string serverName = "myservername";
var sepratedFiles = string.Join(" ", files.Select(p=>"\"" +p +"\"");
Process sqlServer = new Process();
sqlServer.StartInfo.FileName = "SSMS";
sqlServer.StartInfo.Arguments = string.Format("-S {0} {1}", serverName, sepratedFiles );
sqlServer.Start();
It is a follow-up question to my previous question in the same forum.
I would like to take a backup of my SQL Server database. Here is the code, for the backup in C#.
userConn = new SqlConnection(userdatabase);
userConn.Open();
string UserString;
UserString = "BACKUP DATABASE #DBName TO DISK = #FilePath";
String destPath = DestDirectory + "\\UserDataTable.bak";
SqlCommand cmd = new SqlCommand(UserString, userConn);
cmd.Parameters.AddWithValue("#dbName", userConn.Database);
cmd.Parameters.AddWithValue("#FilePath", destPath);
cmd.ExecuteNonQuery();
cmd.Dispose();
However, it throws an SQLException,
"Cannot open backup device
'D:\BookKeeping\Database\11_01_2013_21_15\Database\UserDataTable.bak'.
Operating system error 3(failed to retrieve text for this error.
Reason: 15105). BACKUP DATABASE is terminating abnormally."
Any Idea, what could be wrong ?
Thanks a lot for your time and your help.
"Operating system error 3" means that the directory was not found. SQL will not create the backup directory for you; you have to manually create it before running the backup command.
Make sure your SqlServer and the location where you want to create a backup is the same system. If you are using sqlServer remotely(Not located in your system) then you can not create a backup in your machine or you can not restore the database taking a .bak from your machine also.
I am creating a verification utility that check various parts of an application to ensure they are configured correctly. One of the things I need to check is that the DSN entry in a Web.config file is a functional DSN, and that the DSN is pointing to the correct SQL server and database.
Currently you can run the utility in one of two modes, local or remote. My problem occurs when I am trying to verify a remote systems DSN on my local computer. I know why it doesnt work, I don't have the same DSN on my local computer. So what I need to figure out is how to either retrieve the DSN connection information from a remote machine to which I have administrative access, or to get the remote machine to verify it for me.
Any suggestions? Thanks!
EDIT
So apparenty the DSN info is stored in the registry too!
oRegConn = new ConnectionOptions();
oRegConn.Username = username;
oRegConn.Password = password;
scope = new ManagementScope(#"//" + servername + #"/root/default", oRegConn);
registry = new ManagementClass(scope, new ManagementPath("StdRegProv"), null);
inParams = registry.GetMethodParameters("GetStringValue");
inParams["sSubKeyName"] = "SOFTWARE\\ODBC\\ODBC.INI\\ODBC Data Sources\\" +
dsnName;
inParams["sValueName"] = "Server";
outParams = registry.InvokeMethod("GetStringValue", inParams, null);
server = outParams["sValue"].ToString();
Well I would say that its not really a valid check if you run it on another system (yours). The firewall rules could be different, the driver versions might be off, and a million more things. The first thing I would say is if this is a web application, build in a page that can run these checks, like a status page. If this is an application that you cant do that, you can use WMI to run a remote process and gather the results. Other than that your last option might be to do a self hosting WCF service or a windows service that you connect to for querying info. This isnt too uncommon, and I have done it many times using WMI.
In that case, you may want to investigate PSExec (by Sysinternals). You can run your utility on a remote machine in "local" mode, as long as you have Administrative access to that machine.
Your "DSN Verification" part would have to be a separate executable/command, which can be executed by your main utility using syntax similar to the following:
psexec \\REMOTE-Machine <DSN Verification Utility>.exe
The output can be captured within C# by redirecting stdout/stderr.
Forgive me if I'm mistaken, but wouldn't just opening a connection to remote database server let you know if your connection string/DSN is okay?
So the DSN conn values are stored in the registry as plaintext, which is what I needed.
oRegConn = new ConnectionOptions();
oRegConn.Username = username;
oRegConn.Password = password;
scope = new ManagementScope(#"//" + servername + #"/root/default", oRegConn);
registry = new ManagementClass(scope, new ManagementPath("StdRegProv"), null);
inParams = registry.GetMethodParameters("GetStringValue");
inParams["sSubKeyName"] = "SOFTWARE\\ODBC\\ODBC.INI\\ODBC Data Sources\\" +
dsnName;
inParams["sValueName"] = "Server";
outParams = registry.InvokeMethod("GetStringValue", inParams, null);
server = outParams["sValue"].ToString();