Error getting SQL Server database out of recovery mode? - sql-server

I have a SQL Server database in recovery status this is the script i used to try to get it out of recovery mode:
--Step 1 (Check Database Status)
SELECT
DATABASEPROPERTYEX ('CM_DSS', 'status') AS '"CM_DSS Current Status"',
DATABASEPROPERTYEX ('ReportServer', 'status') AS '"ReportServer Current Status"',
DATABASEPROPERTYEX ('ReportServerTempDB', 'status') AS '"ReportServerTempDB Current Status"',
DATABASEPROPERTYEX ('SUSDB', 'status') AS '"SUSDB Current Status"'
--Step 2 (Set Database into Single User Mode)
ALTER DATABASE ReportServer SET Single_User
--Step 3 (Set Database in Emergency Mode)
ALTER DATABASE ReportServer SET EMERGENCY
--Step 4 (Repair Missing Log File with Dataloss
DBCC CHECKDB('ReportServer', REPAIR_ALLOW_DATA_LOSS)
--Step 5 Set Database Access for Everyone
ALTER DATABASE ReportServer SET MULTI_USER
This is the error I get back after trying to run step 2 :
Msg 5011, Level 14, State 9, Line 2
User does not have permission to alter database 'ReportServer', the database does not exist, or the database is not in a state that allows access checks.
Msg 5069, Level 16, State 1, Line 2
ALTER DATABASE statement failed.
I am sure I have admin rights to this db , if not how do I check? Because the ReportServer database does exist it is just in recovery mode..

ALTER DATABASE [database_name]
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE;
should kick everyone else off so it can change to single user mode
To check what your rights are,
use [database_name]
select *
from sys.fn_my_permissions (NULL,'DATABASE')
and you need to have ALTER rights on the database to use SET on the database
Example:

Related

Switching a user in SQL Server fails when accessing through user's default schema in stored proc

I'm trying to implement shared API in MS SQL Server 2014 DB. In that architecture, schemas should have similar structures and use shared API owned by dbo whereas at the same time exposes own API. To call one another without qualifying object names, EXECUTE AS USER statement is used for context switching to a certain default schema of the current user.
The problem is here: while immediate access with user context switching works fine (e.g. EXECUTE AS USER followed by SELECT * from test_tbl;), the access through default schema in a stored procedure fails with error Msg 208, Level 16, State 1.
Before posting my question, I tried a lot of experiments and tests and searched MSDN, Web and SQL forums for any clue during several days with no luck.
Scripts for reproducing (<MDF> and <LDF> requires substitutions with appropritate file paths):
-- DB creation
CREATE DATABASE [test_sql]
CONTAINMENT = NONE
ON PRIMARY
( NAME = N'test_sql', FILENAME = N'<MDF>' , SIZE = 5120KB , FILEGROWTH = 1024KB )
LOG ON
( NAME = N'test_sql_log', FILENAME = N'<LDF>' , SIZE = 2048KB , FILEGROWTH = 10%)
COLLATE Cyrillic_General_CI_AS
GO
ALTER DATABASE [test_sql] SET COMPATIBILITY_LEVEL = 120
GO
ALTER DATABASE [test_sql] SET ANSI_NULL_DEFAULT OFF
GO
ALTER DATABASE [test_sql] SET ANSI_NULLS OFF
GO
ALTER DATABASE [test_sql] SET ANSI_PADDING OFF
GO
ALTER DATABASE [test_sql] SET ANSI_WARNINGS OFF
GO
ALTER DATABASE [test_sql] SET ARITHABORT OFF
GO
ALTER DATABASE [test_sql] SET AUTO_CLOSE OFF
GO
ALTER DATABASE [test_sql] SET AUTO_SHRINK OFF
GO
ALTER DATABASE [test_sql] SET AUTO_CREATE_STATISTICS ON
GO
ALTER DATABASE [test_sql] SET AUTO_UPDATE_STATISTICS ON
GO
ALTER DATABASE [test_sql] SET CURSOR_CLOSE_ON_COMMIT OFF
GO
ALTER DATABASE [test_sql] SET CURSOR_DEFAULT GLOBAL
GO
ALTER DATABASE [test_sql] SET CONCAT_NULL_YIELDS_NULL OFF
GO
ALTER DATABASE [test_sql] SET NUMERIC_ROUNDABORT OFF
GO
ALTER DATABASE [test_sql] SET QUOTED_IDENTIFIER OFF
GO
ALTER DATABASE [test_sql] SET RECURSIVE_TRIGGERS OFF
GO
ALTER DATABASE [test_sql] SET DISABLE_BROKER
GO
ALTER DATABASE [test_sql] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
GO
ALTER DATABASE [test_sql] SET DATE_CORRELATION_OPTIMIZATION OFF
GO
ALTER DATABASE [test_sql] SET PARAMETERIZATION SIMPLE
GO
ALTER DATABASE [test_sql] SET READ_COMMITTED_SNAPSHOT OFF
GO
ALTER DATABASE [test_sql] SET READ_WRITE
GO
ALTER DATABASE [test_sql] SET RECOVERY FULL
GO
ALTER DATABASE [test_sql] SET MULTI_USER
GO
ALTER DATABASE [test_sql] SET PAGE_VERIFY CHECKSUM
GO
ALTER DATABASE [test_sql] SET TARGET_RECOVERY_TIME = 0 SECONDS
GO
ALTER DATABASE [test_sql] SET DELAYED_DURABILITY = DISABLED
GO
USE [test_sql]
GO
IF NOT EXISTS (SELECT name FROM sys.filegroups WHERE is_default=1 AND name = N'PRIMARY') ALTER DATABASE [test_sql] MODIFY FILEGROUP [PRIMARY] DEFAULT
GO
-- Srv login, DB user and schema creation
CREATE LOGIN [test_usr_login] WITH PASSWORD=N'test_usr_login', DEFAULT_DATABASE=[test_sql], DEFAULT_LANGUAGE=[us_english], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO
CREATE USER [test_usr] FOR LOGIN [test_usr_login] WITH DEFAULT_SCHEMA=[test_schema]
GO
CREATE SCHEMA [test_schema] AUTHORIZATION [test_usr]
GO
-- Table and stored proc creation
IF OBJECT_id("[test_schema].[test_tbl]", "U") IS NOT NULL
DROP TABLE [test_schema].[test_tbl];
GO
CREATE TABLE [test_schema].[test_tbl](
[tc] [nchar](10) NULL
) ON [PRIMARY]
GO
IF OBJECT_id("[dbo].[TA]", "P") IS NOT NULL
DROP PROCEDURE [dbo].[TA];
GO
CREATE PROCEDURE [dbo].[TA] AS BEGIN
SET NOCOUNT ON;
SELECT * FROM
(VALUES
('CURRENT_USER', CURRENT_USER),
('SCHEMA_NAME', SCHEMA_NAME()),
('have_UNqualified_select', cast(HAS_PERMS_BY_NAME("[test_tbl]", "OBJECT", "SELECT") as nchar(10))),
('have_qualified_select', cast(HAS_PERMS_BY_NAME("[test_schema].[test_tbl]", "OBJECT", "SELECT") as nchar(10)))
) AS tmptbl([key], val); -- select permissions fro [test_tbl] of the current user
SELECT tc as qualified_tc FROM [test_schema].[test_tbl]; -- qualified select
SELECT tc as UNqualified_tc from [test_tbl]; -- unqualified select fails with Msg 208
END
GO
GRANT EXECUTE ON [dbo].[TA] TO [test_usr]
GO
Test script:
USE [test_sql]
GO
DECLARE #return_value int
execute as login = N'test_usr_login'; -- even when logged in with test_usr_logn, Msg 208 occurs
EXEC #return_value = [dbo].[TA]
revert
SELECT 'Return Value' = #return_value
GO
Output message:
Msg 208, Level 16, State 1, Procedure TA, Line 14 Invalid object name
'test_tbl'.
(1 row(s) affected)
Output result:
key val
CURRENT_USER test_usr
SCHEMA_NAME test_schema
have_UNqualified_select 1
have_qualified_select 1
I would appreciate anyone who could bring light to the solution to the problem described.
The problem is here: while immediate access with user context
switching works fine (e.g. EXECUTE AS USER followed by SELECT * from
test_tbl;), the access through default schema in a stored procedure
fails with error Msg 208, Level 16, State 1.
The problem here is that you don't know how SQL Server resolves non qualified object name.
When you execute plain sql and use an object without specifying its schema, first user default schema is checked, if object is not found, dbo schema is checked. If the object is not found even in dbo, the error is raised.
It's different when it comes to stored procedure. If schema is not specified, sp's schema is checked first, if object is not found, dbo schema is checked, if it's not found again the error is raised. User default schema is never checked in case of stored procedure

Cannot enable Query Store on SQL Azure database

One of our Azure SQL databases ran out of space recently which I believe resulted in Query Store switching over to "READ_ONLY".
I increased the size of the database however this has not resulted in the status changing even though running this query:
SELECT desired_state_desc, actual_state_desc, readonly_reason, current_storage_size_mb, max_storage_size_mb
FROM sys.database_query_store_options
Suggests that there is enough space available:
desired_state_desc actual_state_desc readonly_reason current_storage_size_mb max_storage_size_mb
READ_WRITE READ_ONLY 524288 522 1024
I tried to alter the Query Store status to Read_Write by running this statement (as database server admin user):
ALTER DATABASE [QueryStoreDB]
SET QUERY_STORE (OPERATION_MODE = READ_WRITE)
However, the statement failed with the following error:
User does not have permission to alter database 'QueryStoreDB', the database does not exist, or the database is not in a state that allows access checks.
Has anybody manged to switch SQL Azure Query Store to READ-WRITE so performance statistics start being collected again?
First, let’s try to clear the query store:
ALTER DATABASE [QueryStoreDB]
SET QUERY_STORE CLEAR;
GO
If that did not work, let’s run a consistency check.
ALTER DATABASE [DatabaseOne] SET QUERY_STORE = OFF;
GO
sp_query_store_consistency_check
GO
ALTER DATABASE [DatabaseOne] SET QUERY_STORE = ON;
GO
Try more options to troubleshoot this issue on this following article:

set database to multi_user through management studio

I have had to set my database to single_user mode to allow for a dbcc checkdb repair and now I am unable to get my database back to multi_user. I have tried the following command in a query window against the master database but it hasn't worked as suggested by another Stack overflow post:
USE [master];
GO
ALTER DATABASE mydb SET MULTI_USER WITH ROLLBACK IMMEDIATE;
GO
I get the following error:
Msg 5064, Level 16, State 1, Line 2 Changes to the state or options of
database 'mydb' cannot be made at this time. The database is in
single-user mode, and a user is currently connected to it.
Msg 5069,
Level 16, State 1, Line 2 ALTER DATABASE statement failed.
If I right click on the database and try selecting properties then it errors saying that it is already in use.
Any help would be greatly appreciated.
Try killing the existing connection and setting MULTI_USER in the same batch:
USE master;
GO
DECLARE #sql nvarchar(MAX);
SELECT #sql = STRING_AGG(N'KILL ' + CAST(session_id as nvarchar(5)), ';')
FROM sys.dm_exec_sessions
WHERE database_id = DB_ID(N'mydb');
SET #sql = #sql + N';ALTER DATABASE mydb SET MULTI_USER;';
--PRINT #sql;
EXEC sp_executesql #sql;
GO
To get the session that was tied to the database I ran:
SELECT request_session_id
FROM sys.dm_tran_locks
WHERE resource_database_id = DB_ID('mydb')
This yielded a processid of 55
I then ran:
kill 55
go
And I was the able to use the alter multi_user line that was previously not working
The most likely reason why you're getting this error is that you still have the original session open that you used to set the database to single user. If you execute the above SQL in the same session that you set the database to single user in, it will work.
First try selecting the master database and run the alter command.
If it does not work, There exists some open connections to database and you can check and kill the processes
use master
GO
select
d.name,
d.dbid,
spid,
login_time,
nt_domain,
nt_username,
loginame
from sysprocesses p
inner join sysdatabases d
on p.dbid = d.dbid
where d.name = 'dbname'
GO
kill 52 -- kill the number in spid field
GO
exec sp_dboption 'dbname', 'single user', 'FALSE'
GO

What are the user permissions needed to enable snapshot isolation in a DB?

I have a user who has db_datareader, db_datawriter permissions on a DB.
I want to set the isolation levels to the DB to which the user has access to.
What permissions will my user need to be able to set these.
DB used: SQL SERVER 2008
This is not setting an isolation level:
ALTER DATABASE dbname SET ALLOW_SNAPSHOT_ISOLATION ON;
That is altering the database. For that you need to provide them with ALTER rights on the database:
GRANT ALTER ON DATABASE::dbname TO username;
Otherwise you get this error:
Msg 5011, Level 14, State 9, Line 1
User does not have permission to alter database 'dbname', the database does not exist, or the database is not in a state that allows access checks.
Msg 5069, Level 16, State 1, Line 1
ALTER DATABASE statement failed.
Now, ALTER is all or nothing - you can't use it to allow them to change the allow snapshot setting but not other settings like forced parameterization, compatibility level, etc. You can do this much more granularly, though; perhaps you could create a stored procedure that does something like this:
CREATE PROCEDURE dbo.SetIsolationLevel
WITH EXECUTE AS OWNER
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX) = N'ALTER DATABASE '
+ QUOTENAME(DB_NAME())
+ ' SET ALLOW_SNAPSHOT_ISOLATION ON;';
EXEC sp_executesql #sql;
END
GO
Now you just have to give the user EXEC permissions on that procedure, which your user can now call (instead of the ALTER DATABASE command explicitly and instead of giving them full ALTER DATABASE privileges):
GRANT EXEC ON dbo.SetIsolationLevel TO username;
GO
You can simulate them calling this stored procedure by logging in as them, or using the EXECUTE AS feature directly:
EXECUTE AS USER = 'username';
GO
EXEC dbo.SetIsolationLevel;
GO
REVERT;
GO
Another idea is to simply set the model database to have this setting, than any new databases that get created for your users will automatically inherit it, then you don't have to worry about making them turn it on.
ALTER DATABASE model SET ALLOW_SNAPSHOT_ISOLATION ON;
GO
CREATE DATABASE splunge;
GO
SELECT snapshot_isolation_state_desc FROM sys.databases WHERE name = N'splunge';
Result:
ON

Enabling broker after Restoring Sql Server DataBase

I have DataBase with enabled Service Broker. Then I want to restore my database in program from backup of other database, but after restoring(I restore on existing database name), my method, whitch enables Service Broker, puts this error:
Msg 9772, Level 16, State 1, Line 1
The Service Broker in database "ServeDB2" cannot be enabled because there is already an enabled Service Broker with the same ID.
Msg 5069, Level 16, State 1, Line 1
ALTER DATABASE statement failed.
This is my method:
public void TurnOnBroker()
{
if (!this.database.BrokerEnabled)
{
this.server.KillAllProcesses(this.database.Name);
this.database.BrokerEnabled = true;
this.database.Alter();
RefreshConnection();
}
}
What should i fix here?Any suggestions?
keep a note of these options
ALTER DATABASE mydb SET ENABLE_BROKER
ALTER DATABASE mydb SET DISABLE_BROKER
ALTER DATABASE mydb SET NEW_BROKER
if youre getting something like this is already an enabled Service Broker with the same ID, go for the NEW_BROKER
ALTER DATABASE [Database_name] SET NEW_BROKER WITH ROLLBACK IMMEDIATE;
This will create the new service broker
Every database has a unique ID used by Service Broker. This ID must be unique across all databases in a Sql Server instance (well, it should be unique globally, but Sql Server doesn't have a way to enforce that). When you restore a database, you have an option of disabling Service Broker in the restored database, enabling it with the GUID of the backed up database (so that it can take over message processing from the backed up database) or assign it a new GUID. You're trying to do the second option while you still have the old database around and you run into GUID conflict.
See here for more info.
Run this query to find out which other databases are using the same service broker as the database you are using (e.g. for a database called DATABASE_NAME)...
SELECT name, is_broker_enabled, service_broker_guid FROM sys.databases
WHERE service_broker_guid IN (SELECT service_broker_guid FROM sys.databases where name = 'DATABASE_NAME');
... returns ...
name, is_broker_enabled, service_broker_guid
DATABASE_NAME_OTHER, 1, KBHDBVJH-SDVHIOHD-SODIVDIOH-UHDSV
DATABASE_NAME_ANOTHER, 0, KBHDBVJH-SDVHIOHD-SODIVDIOH-UHDSV
DATABASE_NAME, 0, KBHDBVJH-SDVHIOHD-SODIVDIOH-UHDSV
Then run the following queries to obtain a new broker for your database...
ALTER DATABASE DATABASE_NAME SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
ALTER DATABASE DATABASE_NAME SET NEW_BROKER;
ALTER DATABASE DATABASE_NAME SET MULTI_USER;
Run the first query again and your database should be the only one in the list...
SELECT name, is_broker_enabled, service_broker_guid FROM sys.databases
WHERE service_broker_guid IN (SELECT service_broker_guid FROM sys.databases where name = 'DATABASE_NAME');
... now returns ...
name, is_broker_enabled, service_broker_guid
DATABASE_NAME, 1, ASJCBUHBC-7UIOSUI-IUGGUI87-IUGHUIG
I found a very simple solution for that- just simlpy assign new service broker, like this:
public void TurnOnBroker()
{
if (!this.database.BrokerEnabled)
{
this.server.KillAllProcesses(this.database.Name);
string brokerCommand = String.Format("ALTER DATABASE {0} SET NEW_BROKER", this.database.Name);
this.database.ExecuteNonQuery(brokerCommand);
RefreshConnection();
}
}

Resources