I have create a C# application that allows a database to be backed up and restored. It does this by first backing the database up to a local file on the Sql server using:
Backup backup = new Backup();
backup.Devices.AddDevice(Path.GetFullPath(backupFilePath), DeviceType.File);
...
backup.SqlBackup(server);
And then I create the new database by restoring from the backup file using:
Restore restore = new Restore();
restore.Devices.AddDevice(Path.GetFullPath(backupFileToRestoreFrom), DeviceType.File);
...
restore.SqlRestore(server);
After the new database has been created I want to delete the temp backup file that we created. Because I have admin rights on the Sql server box, I can delete the file on the remote server using:
File.Delete("\\SqlServer\C$\Backups\BackupFileToDelete.bak")
and it works. However, if somebody else who doesn't have rights on the Sql server box runs the app, it will throw an exception about not having permissions.
So is there a Sql SMO function that I can call to delete the backup file that was created on the remote Sql server?
If you delete the file using the xp_cmdshell then it will use the rights of the sql server instead of the rights of the person.
For example:
EXEC master..xp_cmdshell 'Del \\SqlServer\C$\Backups\BackupFileToDelete.bak', NO_OUTPUT
Here's the reference on xp_cmdshell
The important thing to note from that article is:
Because malicious users sometimes attempt to elevate their privileges
by using xp_cmdshell, xp_cmdshell is disabled by default. Use
sp_configure or Policy Based Management to enable it. For more
information, see xp_cmdshell Server Configuration Option.
Another possibility is to use SQLCLR, which is more secure than using xp_cmdshell. There's even a CodePlex project call SQLCLR File Functions that has the functionality written as stored procs for me. I think I'm going to see if I can convince our DBAs to go this route. The downside is that I believe the sprocs that this creates would need to be installed on every existing and new SQL Server that gets created; not much different than having to enable xp_cmdshell on every server though I guess.
Related
I am working on a process for restoring a database to my Azure SQL Managed instance which involves dropping the existing database and restoring a backup in its place (since Managed Instance doesn't support WITH REPLACE).
I am, however, running into an issue with disconnecting any open connections so I can do this operation. Users should be warned before updates take place, but we cannot guarantee no open connections.
Typically, I would do something along the lines of the following:
ALTER DATABASE AdventureWorks2012 SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
--RESTORE HERE
ALTER DATABASE AdventureWorks2012 SET MULTI_USER;
When I attempt to run something like this against the database in the managed instance, however, I get the following error:
This ALTER DATABASE statement is not supported. Correct the syntax and execute the statement again. ALTER DATABASE statement failed.
Is there a way to accomplish this in an Azure SQL Managed Instance?
In RESTORE FROM URL in Managed Instance you can't even replace existing databases.
So either drop or rename the database before the RESTORE. Both DROP DATABASE MyDb and ALTER DATABASE MyDb MODIFY NAME = MyDb_old will kill existing connections to the database.
Alternatively you can use the Managed Point-in-Time Restore to restore an existing database to a previous point-in-time.
I need to write a C# program that restores a SQL Server database at a remote computer and I need to do this from local computer. My code is restoring database but I need to put path to backup .bak file at remote computer using "From Disk".
string sql = "ALTER DATABASE [" + MyDatabaseName + "] ; Restore Database [" + MyDatabaseName + "] From Disk= '" + pathToBackupAtRemoteComputer + "'WITH REPLACE;"
When I delete database using SQL Server Management Studio and run code, I get an error that database does not exist or I don't have permission. I want to 1st: delete database, 2nd: create new database, 3rd: put data from backup file. Is there an option to write something like: "DROP SCHEMA IF NOT EXITS" or "CREATE DATABASE IF NOT EXIST" (like in MySQL)? I tried but it didn't work.
Is there an option that I can use .bak file at my local computer (like in MySQL, when I transfer .sql file at local computer into string then restore database remotely)? Or maybe send .bak file from local to remote computer using C# application and do it automatically? I tried it out using PsExec, but there is no option to transfer file between two computers.
One way to delete database is by using the following:
USE master;
ALTER DATABASE [MyDatabaseName] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE [MyDatabaseName] ;
This way, it will drop the database and the physical files .ldf and .mdf files. Another thing is you can also rename the database (and maybe compare the database with restored one)
A good article on renaming a database logical and physical files are here:
https://www.mssqltips.com/sqlservertip/1891/steps-to-rename-a-sql-server-database/
DROP DATABASE IF EXISTS is possible in SQL Server in SQL Server 2016 onwards.
Because it is the SQL Server database engine performing the restore, the backup file must be accessible to the remote SQL Server and could be a UNC path.
I'm very new to SQL and made a small program where a user can input some data, click submit and the data is then stored in a table in the database.
I know want to move the application onto a friends computer, which i'm assuming has no SQL software installed, what would be the easiest way to do this, when obviously the connection string is unique to my computer and the database is stored on my computer.
You will have to install SQL Server on their machine first and foremost. Once this is done, you can obtain a relevant connection string. Note, for the 'Server name' part of the connection string, if you are using SQL Express, instead of using 'localhost', or the name of the server instance (i.e. 'MyMachine'), you would use 'localhost\SQLEXPRESS'/'MyMachine\SQLEXPRESS'.
After setting up the SQL Server instance on the new machine, to copy the required database, first detach the database to avoid any corruption. Now you are free to merely copy the file from your machine to theirs and go through the usual attachment process using SQL Server Management Studio (SQLMS).
I hope this helps.
You can use SQL CE or other file databases. On this way you need to install SQL CE(you can include SQl CE installer into your program installer) on target computer and after that you can easy copy db-file from you computer to target computer.
Also, you can use relative path to db-file from your exe file instead of fixed connection string:
string dbDirPath=Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"DB" );
private const string CONN_STR_TEMPLATE = "Data Source={0};Persist Security Info=False;";
string dbFilePath = Path.Combine(dbDirPath, "my.sdf");
_connStr =String.Format(CONN_STR_TEMPLATE,dbFilePath);
You cannot simply copy your database since SQL Server database is NOT a standalone database as SQL Compact edition/MS Access.
You may configure your router to remote access SQL Server instance over the Internet by forwarding the port
Accessing SQL Server Instance through NAT
I have wrote this code
but its generating error
please help
System.IO.File.Copy("JDB.mdf", "d:\\JDB.mdf", true);
System.IO.File.Copy("JDb_log.ldf", "d:\\JDb_log.ldf", true);
the error is
The process cannot access the file 'JDB.mdf' because it is being used by another process.
Please help me
The file is being used by some process. I believe the database is still attached to Sql Server.
Use Process Explorer tool from Sys Internal to find out the program using this file.
Why don't you use SQL back tool to backup the database?
Check out What happens during a live SQL Server backup?
If you still want to backup or make copy of ldf mdf files then you can perform these steps:
1. Detach database
USE MASTER;
GO
-- Take database in single user mode -- if you are facing errors
-- This may terminate your active transactions for database
ALTER DATABASE DatabaseName
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE;
GO
-- Detach DB
EXEC MASTER.dbo.sp_detach_db #dbname = N'DatabaseName'
Open Windows Explorer go to the the folder where ldf and mdf files are and then copy the file manually.
Reattach the database:
USE [master]
GO
CREATE DATABASE [DatabaseName] ON
( FILENAME = N’C:\Data\DataBase_Data.mdf’ ),
( FILENAME = N’C:\Data\Database_Log.ldf’ )
FOR ATTACH
GO
IF EXISTS ( SELECT name FROM master.sys.databases sd
WHERE name = N’DataBaseName’ AND SUSER_SNAME(sd.owner_sid) = SUSER_SNAME() )
EXEC [AdventureWorks].dbo.sp_changedbowner #loginame=N’sa’,#map=false
If you want to do it programatically, then you can execute the command given in step 1,2,3 using ADO.NET and the use c# file copy command to copy the file.
Download Process Explorer and run the program.
Option 1:
Click the Find menu, and choose Find Handle or DLL...
Type the file name (in your case JDB.mdf)
After typing the search phrase, click the Search button
Once you know what process the file has locked you, need to close that process (by closing that program). Another option is to use KILL in the process explorer terminating that process.
Option 2:
From the error message, the .mdf file has already been attached to an instance of an SQL Server. If you have multiple instances running, make sure it is detached from any other instance.
I am trying to create backup and restore of a database to new server with new name using C# and SQL server database. I can create a backup of the database but I am not able to restore it to the new server using the new name.
My query looks something like this: it doesn't work and errors out:
RESTORE DATABASE test1 FROM DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL\BACKUP\setupdb\BackupForsetupdb.bak'
WITH MOVE 'setupdb_Data' TO '\\newserver\e$\MSSQL\DATA\test1_Data.MDF',
MOVE 'setupdb_log' TO '\\newserver\e$\MSSQL\DATA\test1_Log.LDF';
I am trying to achieve this through C# code.It looks like the database cannot be restored to the remote servers. Please throw some light on this.
Thanks!
You can't have SQL Server databases on network shares normally: local/SAN type drives only
The backup file can be on a share but the MDF and LDFs must be local
There is an MS KB article on it: it can be done but at your own risk
Your paths for the move command have to be relative to the server.
e:\MSSQL\Data\test1_data.mdf
And your restore from path has to be relative to the server as well. If the c:\ is from your local machine, you either need to point it to a UNC path (\\yourpc\c$\...) or move it to the server. But be aware that if using the UNC path option, the user the server process is running as has to have permissions to access the share as well. So you're probably better off copying to a drive on the remote computer.