Moving DataBase from Microsoft SQL folder to App_Data folder (appseting.json) - sql-server

1. "WebApi": "Data Source=.;Initial Catalog=TaskDB; Integrated Security=true"
2. "WebApi": "Server=(localdb)\\mssqllocaldb;AttachDBFilename=%CONTENTROOTPATH%\\App_Data\\TaskDB.mdf;Trusted_Connection=true;MultipleActiveResultSets=true"
I am trying to move my DataBase from main folder of Microsoft SQL to project folder App_Data, but it does not work for some reason. I do not know why maybe my connection string is wrong. So with number 1 is working fine, but it is in main folder of Microsoft SQL, but with number 2 there is something wrong I guess

The files of database are exclusive in hand of SQL Server. You can not move database when it is online. Taking database offline, requires that no one be connected to database.
First take the database offline then try to move the files. You can take the database offline both using SSMS and query. First line of code kill all active sessions then set database multiple user; but it must be offline before anyone can connect to database so all these code must be executed together.
ALTER DATABASE DatabaseName SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
ALTER DATABASE DatabaseName SET MULTI_USER
GO
USE master
GO
ALTER DATABASE DATABASE_NAME SET OFFLINE
Be aware that when you move file to another location database could not been brought ONLINE if you do not set new filename before taking the database offline.
Use this code for all of files that you want to move them.
ALTER DATABASE TEST
MODIFY FILE (NAME = 'LOGICAL_NAME', FILENAME = 'New_Directort\Filename.mdf')
After you moved the files then bring online the database with this statement.
ALTER DATABASE DATABASE_NAME SET ONLINE
As you can see this action is not a kind, that can be done without plan. Specially with application code. When trying to do it in application code; then all session including application connection will be lost. then you can not continue the progress.

Related

Permissions on new mdf file

I'm trying to write a program to allow a non-privileged technically naive user to create a new SQL Server database and receive it in the form of a .mdf file. I understand that .mdf files are not really supposed to be treated like database backups, but I need to do it this way to maintain compatibility with existing commercial software that works like this.
I'm using Visual Studio 2013 and SQL Server 2014, though I would like the program to be able to work with versions of SQL Server going back at least to 2008.
What I find is that I can't copy the .mdf file created by
CREATE DATABASE XXXXX on
(NAME=<name>,FILENAME=<filename>')
because it ends up belonging (I think) to MSSQL$SQLEXPRESS. The reason I say 'I think' is that when I go to the file properties and accept Administrator privileges to view the owner, it tells me 'Unable to display current owner.' I can transfer ownership of the file, but only using Administrator privileges.
So it seems that I cannot copy the .MDF file without Administrator privileges, which seems fairly ridiculous given that I was able to create the file without those privileges. I've tried creating the file in a folder located under my user's App_Data folder and with full access for everyone to subfolders and files, but that didn't help.
Can anyone suggest me what I can do (programatically) to make this file available to a non-privileged user?
Many thanks for your help.
Try following script before trying to copy mdf file:
USE [master]
GO
EXEC master.dbo.sp_detach_db #dbname = N'DatabaseName';
GO
It will detach Database from SQL Server and you can treat it's files as regular files within a system.
After copying you'd have to re-attach the database by "sp_attach_db".
Be aware that during that period database won't be visible by SQL Server.
USE [master]
GO
EXEC master.dbo.sp_attach_db #dbname = N'DatabaseName'
, #filename1 = 'C:\Data\Datfile.mdf';
, #filename2 = 'C:\Data\Logfile.ldf';
GO
First get location of data files into a variable, so that you can easly move from there after you detach.
select a.filename from sys.sysfiles a inner join sys.master_files b on a.fileid=b.file_id
where b.database_id=db_id('DB_NAME')
Verify if there is any open session with the database.
select spid from sysprocesses where dbid=db_id('DB_NAME')
Kill All the sessions using [kill spid]
Then Detach your database
USE [master]
GO
EXEC master.dbo.sp_detach_db 'DB_NAME';
Now you can move the database from the source holded in the variable to desired destination.
Now if you want to attach the database on other server.
If you moved both .ldf and .mdf to same directory
USE [master]
GO
EXEC master.dbo.sp_attach_db #dbname = 'DB_NAME', #filename1 = 'C:\Data\Datfile.mdf';
If you moved .ldf and .mdf to seperate directory.
Use the script suggested by Mr. Slava Murygin here to attach database.
Thanks

SQL Server backup to Azure stopped working after moving DB files

I have a database in SQL Server 2014 on premises. For that database I have a backup to Azure storage configured using smart_admin.sp_set_db_backup procedure.
Recently I had to move the database files from one disk to another. I detached database, moved files, reattached it.
After that my backup stopped working. The function smart_admin.fn_backup_db_config shows that database backup record exists but database marked as is_dropped = 1
Any attempt to enable or disable backup for this database fails with error:
SQL Server Managed Backup to Windows Azure cannot configure the database, 'DATABASE_NAME', because it either does not exist or is offline.
Any way I can remove backup configuration information and create a new one? One of the ideas I found is rename the database, but I cannot do that in production.
Vad's answer is close, but there can be more than one record in autoadmin_managed_databases for a given db_name. You need to get the last record, which is the one with the max autoadmin_id. I picked the wrong one, and SQL Server repopulated the drop_date after I ran smart_admin.sp_set_db_backup or the 15 minute interval ran.
use msdb;
go
update [dbo].[autoadmin_managed_databases]
set drop_date = null
where [autoadmin_id]= (select max(autoadmin_id)
from [dbo].[autoadmin_managed_databases]
where db_name = '<DROPPPED_DATABASE_NAME>')
go
Managed Backups - is_dropped flag set to Yes after detaching database
and reattaching DB
Rename the database and set up managed backup again.
Reference
As I mentioned earlier I was not allowed to rename the database on the Production. So I found where it's marked as dropped and changed the value. That helped. Automated backups for the database started working again. IMO what happened looks like a bug in SQL Server 2014.
use msdb;
go
update [dbo].[autoadmin_managed_databases]
set drop_date = null
where [db_name] = '<DROPPED_DATABASE_NAME>'
go

Clone an existing database to a new database

I'm struggling to find a suitable solution to this. I have a fairly large SQL Server 2008 Express database containing 60+ tables (many with key constraints) and a whole bunch of data.
I need to essentially copy all of these tables and the data and the constraints exactly from one database to another. I'm basically duplicating website A - to produce an exact copy (website B) on a different domain so we end up with two completely identical websites running in parallel, each with their own identical database to begin with.
Database A is up and running on website A. Database B is set up and has it's own user. I just need to get the tables and the data intact from A to B. I can them modify my web.config connection to use the log-in credentials for database B and it should work.
I've tried backing up database A and restoring to database B via Management Studio Express, but it tells me:
System.Data.SqlClient.SqlError: The backup set holds a backup of a database other than the existing 'database-B' database.
(Microsoft.SqlServer.Smo)
I've also tried right clicking database A in Management Studio Express and going to Tasks > Generate scripts. But when I do this and run the SQL scripts on database B I get a whole load of errors to do with foreign keys etc as it imports the content. It seems like it's doing the right thing, but can't handle the different keys/relationships.
So does anyone know of a simple, sure-fire way of getting my data 100% exact and intact from database A to database B?
I think I used SQL Server Database Publishing Wizard to do something like this about 5 years ago, but that product seems to be defunct now - I tried to install it and it wanted me to regress my version of SQL Server to 2005, so I'm not going there!
Don't use the UI for this. If you're not familiar with the various aspects of BACKUP/RESTORE the UI is just going to lead you down the wrong path for a lot of options. The simplest backup command would be:
BACKUP DATABASE dbname TO DISK = 'C:\some folder\dbname.bak' WITH INIT;
Now to restore this as a different database, you need to know the file names because it will try to put the same files in the same place. So if you run the following:
EXEC dbname.dbo.sp_helpfile;
You should see output that contains the names and paths of the data and log files. When you construct your restore, you'll need to use these, but replace the paths with the name of the new database, e.g.:
RESTORE DATABASE newname FROM DISK = 'C\some folder\dbname.bak'
WITH MOVE 'dbname' TO 'C:\path_from_sp_helpfile_output\newname_data.mdf',
MOVE 'dbname_log' TO 'C:\path_from_sp_helpfile_output\newname_log.ldf';
You'll have to replace dbname and newname with your actual database names, and also some folder and C:\path_from_sp_helpfile_output\ with your actual paths. I can't get more specific in my answer unless I know what those are.
** EDIT **
Here is a full repro, which works completely fine for me:
CREATE DATABASE [DB-A];
GO
EXEC [DB-A].dbo.sp_helpfile;
Partial results:
name fileid filename
-------- ------ ---------------------------------
DB-A 1 C:\Program Files\...\DB-A.mdf
DB-A_log 2 C:\Program Files\...\DB-A_log.ldf
Now I run the backup:
BACKUP DATABASE [DB-A] TO DISK = 'C:\dev\DB-A.bak' WITH INIT;
Of course if the clone target (in this case DB-B) already exists, you'll want to drop it:
USE [master];
GO
IF DB_ID('DB-B') IS NOT NULL
BEGIN
ALTER DATABASE [DB-B] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE [DB-B];
END
GO
Now this restore will run successfully:
RESTORE DATABASE [DB-B] FROM DISK = 'C:\dev\DB-A.bak'
WITH MOVE 'DB-A' TO 'C:\Program Files\...\DB-B.mdf',
MOVE 'DB-A_log' TO 'C:\Program Files\...\DB-B_log.ldf';
If you are getting errors about the contents of the BAK file, then I suggest you validate that you really are generating a new file and that you are pointing to the right file in your RESTORE command. Please try the above and let me know if it works, and try to pinpoint any part of the process that you're doing differently.
I realize this is an old question, but I was facing the same problem and I found that the UI was easier and faster than creating scripts to do this.
I believe Dan's problem was that he created the new database first and then tried to restore another database into it. I tried this as well and got the same error. The trick is to not create the database first and name the database during the "Restore Database" process.
The following article is somewhat useful in guiding you through the process:
http://msdn.microsoft.com/en-us/library/ms186390(v=sql.105).aspx

Trying to restore via t-sql script. Exclusive access could not be obtained because the database is in use

I'm trying to restore backups of our production databases to our development server. When I run the following script which has previously worked:
RESTORE DATABASE M2MDATA01 FROM DISK = 'C:\Install\SQLBackup\M2MDATA01.SQLBackup' WITH REPLACE,
MOVE 'M2MDATA01' TO 'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\M2MData01.mdf',
MOVE 'M2MDATA01_log' TO 'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\M2MData01.ldf'
I get the following error:
Error 12/21/2009 9:06:09 AM 0:00:00.000 SQL Server Database Error: Exclusive access could not be obtained because the database is in use. 5 0
However, I have no idea how what could possibly be using it. How can I tell?
Check what's connected (the easy way)
SELECT * FROM sys.sysprocesses S WHERE S.dbid = DB_ID('M2MDATA01')
Note: sysprocesses can not be emulated using dmvs...
Edit, check for locks too
SELECT * FROM sys.dm_tran_locks L WHERE L.resource_type = 'DATABASE' AND L.resource_database_id = DB_ID('M2MDATA01')
In SQL Server Management Studio, go to Management => Activity Monitor. This will show you all processes that are connected to all databases, and allow you to kill these processes (only recommended as a last resort).
Profiler is one option.
From Sql Server Management Studio, select Tools|Sql Server Profiler.
Connect to the server instance that the database you are working with is on.
Switch to the Event Selection tab
check the checkbox below the grid labeled "Show all columns"
In the grid find the DatabaseName column and check the entire column.
(optional) press the Column Filters button and filter to the database name you are working with.
This should at least tell you if something is using the database in question.
Easiest solution here is to delete the database and select the "close existing connections" checkbox before hitting okay. Then the restore will work just fine. It's just DEV right? :}
If you're restoring a db, do you really care who is connected? Or what is being done with those connections? I would think not. Just "kick everyone out" by setting the database into single user mode and then restore the database.
USER master
GO
ALTER DATABASE M2MDATA01
SET SINGLE_USER
--This rolls back all uncommitted transactions in the db.
WITH ROLLBACK IMMEDIATE
GO
RESTORE DATABASE M2MDATA01
FROM DISK = 'C:\Install\SQLBackup\M2MDATA01.SQLBackup'
WITH REPLACE,
MOVE 'M2MDATA01' TO 'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\M2MData01.mdf',
MOVE 'M2MDATA01_log' TO 'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\M2MData01.ldf'
GO
Now, one additional item to be aware of. After you set the db into single user mode, someone else may attempt to connect to the db. If they succeed, you won't be able to proceed with your restore. It's a race! My suggestion is to run all three statements at once in a single batch.

How to recover database from MDF in SQL Server 2005?

I have an MDF file and no LDF files for a database created in MS SQL Server 2005. When I try to attach the MDF file to a different SQL Server, I get the following error message.
The log cannot be rebuilt because there were open transactions/users when the database was shutdown, no checkpoint occurred to the database, or the database was read-only. This error could occur if the transaction log file was manually deleted or lost due to a hardware or environment failure.
I would like to accomplish any one of the following options:
Attach the database without data loss (unlikely but would save me some time).
Attach the database with data loss (whatever transactions were open are lost).
Recover the schema only (no data) from the MDF file.
What SQL commands can I try to get my database going again?
I found the following document on Experts Exchange.
patrikt:
You will have data loss but it can be done.
1. Detach database and move your mdf to save location.
2. Create new databse of same name, same files, same file location and same file size.
3. Stop SQL server.
4. Swap mdf file of just created DB to your save one.
5. Start SQL. DB will go suspect.
6. ALTER DATABASE yourdb SET EMERGENCY
7. ALTER DATABASE yourdb SET SINGLE_USER
8. DBCC CHECKDB (yourdb, REPAIR_ALLOW_DATA_LOSS)
9. ALTER DATABASE yourdb SET MULTI_USER
10. ALTER DATABASE yourdb SET ONLINE
Here are details that cover parts 2) and 3) in case re-creating log doesn’t work which can happen if MDF file is corrupted.
You can recover data and structure only by reading MDF file with some third party tool that can de-code what’s written as binary data but even with such tools you can’t always do the job completely.
In such cases you can try ApexSQL Recover. From what I know this is the only tool that can do this kind of job but it’s quite expensive.
Much better idea is to try to recover these from any old backups if you have any.
FROM a post at SQL Server Forums Attaching MDF without LDF:
If you want to attach a MDF without LDF you can follow the steps below
It is tested and working fine
Create a new database with the same name and same MDF and LDF files
Stop sql server and rename the existing MDF to a new one and copy the original MDF to this location and delete the LDF files.
Start SQL Server
Now your database will be marked suspect 5. Update the sysdatabases to update to Emergency mode. This will not use LOG files in start up
Sp_configure "allow updates", 1
go
Reconfigure with override
GO
Update sysdatabases set status = 32768 where name = "BadDbName"
go
Sp_configure "allow updates", 0
go
Reconfigure with override
GO
Restart sql server. now the database will be in emergency mode
Now execute the undocumented DBCC to create a log file
DBCC REBUILD_LOG(dbname,'c:\dbname.ldf') -- Undocumented step to
create a new log file.
(replace the dbname and log file name based on ur requirement)
Execute sp_resetstatus
Restart SQL server and see the database is online.
UPDATE: DBCC REBUILD_LOG does not existing SQL2005 and above. This should work:
USE [master]
GO
CREATE DATABASE [Test] ON
(FILENAME = N'C:\MSSQL\Data\Test.mdf')
FOR ATTACH_REBUILD_LOG
GO
have you tried to ignore the ldf and just attach the mdf:
sp_attach_single_file_db [ #dbname = ] 'dbname' , [ #physname = ] 'physical_name'
i don't know exactly what will happen to your open transactions (probably just lost), but it might get your data back online.
-don
See here : Rebuild master and restore system databases from complete disk failure which has a very nice explanation
Just had this problem myself, but none of the above answers worked for me.
But instead, I found this which worked a treat and so I thought I'd share this for everyone else:
http://www.kodyaz.com/articles/sql-server-attach-database-mdf-file.aspx
Found a another way that works completely:
Create new database with same name to default database location.
Stop SQL server.
Copy old mdf file to overwrite newly created mdf file and delete new ldf file
Start SQL Server, database will be in emergency mode
Detach the emergency mode database
Copy original ldf file to default database location (where new LDF file as created and deleted under step 3 above.
Attach the database MDF file.
I got a working database after trying all of the above that failed for me.
I hope it is easy to do so,
Open SQL Server
Click New Query
Execute the following query
sp_attach_single_file_db #dbname='dbname',#physname='C:\Database\dbname.MDF'
Where dbname is you want to show in Object Explorer, where #physname is the local filepath location of your mdf file.
Hope it will help someone, i done by above, got both structure and also data.
Tested in Sql Server 2000 and 2008. In Sql Server 2000 it is not working, but works perfectly in 2008.

Resources