Restore database SQL server query - sql

I want a way to write my own query to restore the database. The database to restore needs to have all the settings to delete the current user and re-map the same user. The reason for that is because when the database is restored, the user will not have the right settings to use the database and will have to re assign the user the privileges.

Check this out:-
Step 1: Retrive the Logical file name of the database from backup.
RESTORE FILELISTONLY
FROM DISK = 'D:BackUpYourBaackUpFile.bak'
GO
Step 2: Use the values in the LogicalName Column in following Step.
----Make Database to single user Mode
ALTER DATABASE YourDB
SET SINGLE_USER WITH
ROLLBACK IMMEDIATE
----Restore Database
RESTORE DATABASE YourDB
FROM DISK = 'D:BackUpYourBaackUpFile.bak'
WITH MOVE 'YourMDFLogicalName' TO 'D:DataYourMDFFile.mdf',
MOVE 'YourLDFLogicalName' TO 'D:DataYourLDFFile.ldf'
/If there is no error in statement before database will be in multiuser
mode.
If error occurs please execute following command it will convert
database in multi user./
ALTER DATABASE YourDB SET MULTI_USER
GO

The reason for that is because when the database is restored, the user will not have the right settings to use the database and will have to re assign the user the privileges.
I guess that:
You are using mixed mode authentication and the user is a SQL Server user (not a Windows user)
You are restoring the database to a different server than the one where the backup was made
Correct?
If yes, you need to consider the following:
The user must exist on the second server as well, it's not created automatically when you restore the database there
It's not enough to just create a new user with the same name on the second server - to SQL Server, this would be a different user!
I guess that the second point is the reason why your user doesn't have "the right settings" after restoring.
Some background:
Internally, all SQL Server users are represented by a SID (something unique and unreadable - similar to a GUID. SQL Server doesn't care about the actual user name internally).
The permissions that each user has on a database are saved inside the database, using the SID and not the username
When you restore the database to a different server, the permissions are restored with the database...but they only work when there's a user with the exact SID on the new server
As I said before: when you just create a new user with the same name, he gets a new SID.
So what probably happened is this:
on the old server, there's a user "Mohammed Tahir" with the SID 123456789
inside the database, there's a permission that says "SID 123456789 is allowed to read from this database"
you restored the database on the new server
you created a user "Mohammed Tahir" on the new server, but he has a different SID (let's say 987654321), so the existing permissions on 123456789 don't work for him!
So what you need is a way to "copy" the user from the old server to the new server, with the exact same SID.
There is a stored procedure from Microsoft named sp_help_revlogin, which does just that.
It generates a script with all the users from the old server. You can then run the script on the new server, and it will create the users with the same SIDs they had on the old server.
Then, you can restore the database from the old server to the new server, and all the permissions already in the database just work.
You can get sp_help_revlogin from this MSDN article:
How to transfer logins and passwords between instances of SQL Server.
Note that there is nothing special about the actual restoring process - it's the users and their SIDs that make the difference.
So you don't need any "special" commands to restore the database, just the standard ones, for example the one from Rahul Tripathi's answer.

Related

Get DBs Location In A Network Server by a query

Is there a query in T-SQL that pulls out the location of all databases within a server in the network (not the local drive).
I had a look at this example SQL Server - get all databases with MDF and LDF File Location
.But, it didn't seem to work, I am guessing this is due to the location of this server which is not local.
The linked answer works but you must have enough permissions to view the results.
From sys.databases:
If the caller of sys.databases is not the owner of the database and the database is not master or tempdb, the minimum permissions required to see the corresponding row are ALTER ANY DATABASE or VIEW ANY DATABASE server-level permission, or CREATE DATABASE permission in the master database. The database to which the caller is connected can always be viewed in sys.databases.
From sys.master_files:
The minimum permissions that are required to see the corresponding row are CREATE DATABASE, ALTER ANY DATABASE, or VIEW ANY DEFINITION.

Move SQL Server 2008 R2 database files to a new folder location

Currently i have a list of databases i wish to move on the current server.
DATA:
Current Path: Drive:\MSSQL\DATA\FOLDER
New Path: Drive:\MSSQL\DATA
LOGS:
Current Path: Drive:\MYSSQL\LOGS\FOLDER
New Path: Drive:\MYSSQL\LOGS
Is there a SQL script that can be used to set offline multiple databases, detactch them and attach them to the new location? This is also a production enviroment and are pretty large databases (a backup and restore would take much longer). In total 9 databases need to be moved, is this a simple procedure aslong as the location and user have required permissions? Thank you for any help.
This is a simple procedure, and you don't really need to detach the database to do it either, you can just do something along the lines of:
set db offline
alter the file location in the master db (using alter database)
physically move the files
set db online
The process is described in the following article:
Move User Databases
So long as the user moving the files has the permissions and the service account you're running SQL server as has full control of the new folder it's quite easy, and something I've done many times.
Doing it for multiple databases too is simple once you've worked out the procedure for doing the first one.
You can use this code to change the path. But you have to manually move the files to the new location. The WITH ROLLBACK IMMEDIATE speeds up the offline procedure by disconnecting any current connections.
ALTER DATABASE <db-name> SET OFFLINE WITH ROLLBACK IMMEDIATE;
ALTER DATABASE <db-name> MODIFY FILE ( NAME = <db-name>, FILENAME = <db-path\filename.mdf> );
ALTER DATABASE <db-name> SET ONLINE;
For more info check the relevant MSDN article

database owner is empty after restoring database?

I have backup from production database, which I restore on my local computer.
But when I try to create diagram, I have got message where is noticed problem with authorization. Ok, I went to change database owner, right click on database, option Files, and I have noticed that owner field is empty.
Why is it empty?
This is most likely because the login that was set as the owner on the production server doesn't exist on the server you restored it to.
You can recreate this by creating a login, say "test_user", creating a database and making "test_user" the owner.
Backup the database, delete it, then delete the "test_user" login.
Restore the database you deleted, the owner will now be blank.
I had this issue then realised that it would be affecting quite a few databases so i needed some way of finding which databases were affected - using the latest SQL SSMS 17 I found that if I was the person who had restored the database that the usual suggestions of sp_helpdb etc. don't work as they fill in the owner name with your own username, yet the "owner" field is still empty in the files tab of the database properties.
I used the SQL Profiler and found that it uses:
use MyDatabaseThatsMissingItsOwner;
select suser_sname((select sid from sys.database_principals where name = N'dbo'));
to populate that field, and bingo, that will indeed return a null string if the originally owner is missing.

Set permissions on newly created databases with rules

I have a situation whereby an application we use has many databases used for storage, and creates new ones on the fly as needed (SQL Server 2008 R2).
ApplicationDatabase
ApplicationDatabase_Storage001
ApplicationDatabase_Storage002
ApplicationDatabase_Storage003
etc...
As needed the application will create a new storage database for itself.
My problem is that I have a sql server account that is used for the ApplicationDatabase, and I want to automatically give it permissions to the storage databases as they are created, but not to any other database that happens to be created in the same sql server instance. I have no control over the creation of the storage databases.
I read In the answer to this question that I can add the account in the model database however this appears to add the permissions for all new databases, when I only want it to apply to the databases mentioned above.
The best solution I could come up with is a SQL server job or external app that runs once a day or so and looks for the existence of each database, applying the permissions on each that it finds, but this does not seem ideal.
You can implement a DDL trigger that will be fired whenever a new database is created. Depending on the properties of the database, like name or storage definition, you can probably run additional scripts on the new database to set up the required security.
http://msdn.microsoft.com/en-us/library/ms186406.aspx
Here's a snippet from the article above:
IF EXISTS (SELECT * FROM sys.server_triggers
WHERE name = 'ddl_trig_database')
DROP TRIGGER ddl_trig_database
ON ALL SERVER;
GO
CREATE TRIGGER ddl_trig_database
ON ALL SERVER
FOR CREATE_DATABASE
AS
PRINT 'Database Created.'
SELECT EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')
GO
DROP TRIGGER ddl_trig_database
ON ALL SERVER;
GO
Regards
Piotr

set sql server connection to readonly?

How do I set a SQL server connection to readonly? I tried Googling and all I found was File Mode=Read Only, but it didn't work (File Mode keyword not supported). The reference looked SQL CE specific.
No luck with SQLite Read Only=True either.
-edit-
My connection string is below. I have no clue when it comes to configuring the tables. I don't know how to make users/permissions.
rdconn = new SqlConnection(#"(wrong)Read Only=True;Server=.\SQLExpress;AttachDbFilename=test2.mdf;Database=dbo;Integrated Security=SSPI;User Instance=True;");
Just set on current user's permissions to SELECT only.
Is that what you want?
Click on the current db in SQL Server Management Studio, after click on Security->Users. Find your user, right click on him -> properties->Securable. Just mark SELECT, unmark all others.
Here're links on managing permissions
http://www.databasejournal.com/features/mssql/article.php/2246271/Managing-Users-Permissions-on-SQL-Server.htm
http://www.mssqlcity.com/Articles/Adm/manage_users_permissions.htm
Just found a a free tool for managing permissions. It can be useful too. Check the link
http://www.idera.com/Products/Free-Tools/SQL-permissions/
UPDATE:
If you want the DB to be read-only to any user:
ALTER DATABASE database-name SET READ_ONLY
or read here for more information
http://www.sqlservercurry.com/2009/03/set-database-to-read-only-mode-using.html
http://www.blackwasp.co.uk/SQLReadOnly.aspx
Change the security settings for the used login in SQL server.
For instance only db_datareader.
It's really simple.
If your db-user is called
MyApplicationWebServices_EN
Create a new login called MyApplicationWebServicesReadOnly_EN, with default language English (or whatever you need), who is member of the server-role "public" only (default).
In the DB you want the user to have access to, create a new user called MyApplicationWebServicesReadOnly_EN, and map it to login MyApplicationWebServicesReadOnly_EN.
Right-click the user in the database, and select properties -> general
In the Select-box list for "Membership in database roles", select db_datareader only (make sure all others options are unchecked).
Now use MyApplicationWebServicesReadOnly_EN in your connection string as "user id", and you have your read-only mode..
Of course, if your entire db should be read-only, then
ALTER DATABASE your_database_name SET READ_ONLY
will do just fine, as hgulyan said.
If you want to access the database in readonly mode, you can create a user for database and can enable 'READ' rights and disable 'WRITE' rights
you can see the users under database in sqlserver select that and if you want you can create new user else you can set the rights in properties
Also refer
http://www.zimbio.com/SQL/articles/-jf4iDK7qWQ/Set+database+read+only+mode+using+SQL+Server
In some cases, for instance in a High Availability instance in Azure, you may have a read-only replicated duplicate of your database. In that case, you add
;applicationintent=readonly
to the connection string to have that user reach the Read-Only replica.
More at Microsoft...