Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Проблема с запросом в джобе  [new]
Danion
Member

Откуда: Москва
Сообщений: 203
Добрый день.

Есть база на проде, есть тестовый сервер на котором каждую ночь база должна перезаписываться свежей версией прода.
Данные по последний бекапом собираются отдельным заданием в таблицу, линкед сервер есть. Проблема возникает на этапе восстановления.
Запуск процедуры просто из окна нового запроса работает, полученный с помощью print текст из джоба работает, а вот такой же запуск процедуры с параметрами из джоба падает с ошибкой.

User does not have permission to alter database 'Test_DB', the database does not exist, or the database is not in a state that allows access checks. [SQLSTATE 42000] (Error 5011) ALTER DATABASE statement failed. [SQLSTATE 42000] (Error 5069) Database 'Test_DB' does not exist. Make sure that the name is entered correctly. [SQLSTATE 08004] (Error 911). The step failed.

Права у у\з и в SQL Server и на папку есть, база в состояние ресторинг не переходит. Пока больше похоже, что в скрипте плохо задал разбивку на этапы и сам шаг рестора почему-то из джоба пропускает. Просьба подсказать, что задал в скрипте неверно.


exec NEW_DB 'Prod_DB', 'Test_DB','user_abc'
GO



USE [master]
GO
/****** Object:  StoredProcedure [dbo].[NEW_DB]    Script Date: 18.03.2019 9:26:40 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[NEW_DB] 

	@dbname nvarchar(30),
    @newdbname nvarchar(30),
	@user nvarchar(20) 
	
AS
BEGIN

	SET NOCOUNT ON;

	DECLARE @sql nvarchar(2000)
	DECLARE @full_bkp_path nvarchar(250)
	DECLARE @diff_bkp_path nvarchar(250)
	DECLARE @full_date datetime
	DECLARE @diff_date datetime
	DECLARE @diff_sql nvarchar(250)

	declare @LnameData nvarchar(100)
	declare @LnameLog nvarchar(100)
	
	set @LnameData = 
(select 
f.name as logical_name
from [prod-serv].[master].[sys].[master_files] f
 inner join [prod-serv].[master].[sys].[databases] d
 on f.[database_id] =
 d.[database_id] 
 where d.name  = @dbname 
 and f.type_desc = 'ROWS'
 )
  
 set @LnameLog = 
(select 
f.name as logical_name
from [prod-serv].[master].[sys].[master_files] f
 inner join [prod-serv].[master].[sys].[databases] d
 on f.[database_id] =
 d.[database_id] 
 where d.name  = @dbname 
 and f.type_desc = 'LOG'
 )

	SELECT @full_bkp_path = physical_device_name, @full_date = backup_start_date
	FROM backups.dbo.backups
	WHERE type = 'D' and database_name = @dbname

	SELECT @diff_bkp_path = physical_device_name, @diff_date = backup_start_date
	FROM backups.dbo.backups
	WHERE type = 'I' AND database_name = @dbname

	IF (@diff_date < @full_date) SET @diff_sql = ''
	ELSE SET @diff_sql = 'RESTORE DATABASE ' + @newdbname + ' FROM DISK = N''' + @diff_bkp_path + ''' WITH FILE = 1, NOUNLOAD, NORECOVERY, STATS = 5;
'

IF Exists (select name from sys.databases where name = @newdbname)
Begin
	SET @sql = 'USE [master];
ALTER DATABASE ' + @newdbname + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE;'
exec sp_executesql @sql
END

BEGIN	
	SET @sql =
'USE [master];
RESTORE DATABASE ' + @newdbname + ' FROM DISK = N''' + @full_bkp_path + ''' WITH FILE = 1,
MOVE N''' + @LnameData + ''' TO N''C:\SQL\' + @newdbname + '.mdf'', MOVE N''' + @LnameLog + ''' TO N''C:\SQL\' + @newdbname + '_log.ldf'', 
NOUNLOAD, NORECOVERY,  REPLACE,  STATS = 5;
'
+ @diff_sql + 
'
RESTORE DATABASE ' + @newdbname + ' WITH RECOVERY;'
exec sp_executesql @sql

END

SET @sql =
'USE [master]; ALTER DATABASE ' + @newdbname + ' SET MULTI_USER;'
exec sp_executesql @sql

SET @sql =

'USE ' + @newdbname + ';

DROP USER [' +  @user + '];

CREATE USER [' + @user + '] FOR LOGIN [' + @user + '];

USE ' + @newdbname + ';

ALTER ROLE [db_owner] ADD MEMBER [' + @user + '];

USE [master];

ALTER DATABASE ' + @newdbname + ' SET RECOVERY SIMPLE WITH NO_WAIT;
'
exec sp_executesql @sql

END
18 мар 19, 11:56    [21835743]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с запросом в джобе  [new]
Slava_Nik
Member

Откуда: из России
Сообщений: 888
Поставьте якоря в виде принтов или seleсt чтобы определить где затык.
Судя по коду в переводите в Single режим а дальше пытаетесь восстанавливать и вам не дается это.
Попробуйте сделать в одной команде этот код, либо дропайте бд и восстаналивайте с указанием путей а не перезаписывая.

IF Exists (select name from sys.databases where name = @newdbname)
Begin
SET @sql = 'USE [master];
ALTER DATABASE ' + @newdbname + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE;'
exec sp_executesql @sql
END

BEGIN
SET @sql =
'USE [master];
RESTORE DATABASE ' + @newdbname + ' FROM DISK = N''' + @full_bkp_path + ''' WITH FILE = 1,
MOVE N''' + @LnameData + ''' TO N''C:\SQL\' + @newdbname + '.mdf'', MOVE N''' + @LnameLog + ''' TO N''C:\SQL\' + @newdbname + '_log.ldf'',
NOUNLOAD, NORECOVERY, REPLACE, STATS = 5;
'
+ @diff_sql +
'
RESTORE DATABASE ' + @newdbname + ' WITH RECOVERY;'
exec sp_executesql @sql

END
18 мар 19, 14:31    [21835993]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с запросом в джобе  [new]
Danion
Member

Откуда: Москва
Сообщений: 203
Slava_Nik,

Не, проблема вроде не в сингл юзере. Для варианта, где нет базы посмотрел код - там части про перевод нет, что правильно. А дальше пропускается часть с восстановлением и идут ошибки по переводу несуществующей базы в симпл, добавление пользователя.
Вот код, при отсутствии БД. И сейчас выдало ошибку сразу. Нужно как-то принудительно разделить части USE [master]; ALTER DATABASE test_res и SET MULTI_USER;
USE test_res;

Помогает добавление GO, но он для других целей в процедуре вроде не работает.

USE [master];
RESTORE DATABASE test_res FROM DISK = N'\\serv-bk-01\Backup\MSSQL\Full\Prod_db\Prod_db_backup_2019_03_16_010001_6905791.bak' WITH FILE = 1,
MOVE N'MIS' TO N'C:\SQL\test_res.mdf', MOVE N'MIS_log' TO N'C:\SQL\test_res_log.ldf', 
NOUNLOAD, NORECOVERY,  REPLACE,  STATS = 5;
RESTORE DATABASE test_res FROM DISK = N'\\serv-bk-01\Backup\MSSQL\Diff\Prod_db\Prod_db_backup_2019_03_18_010001_4636191.bak' WITH FILE = 1, NOUNLOAD, NORECOVERY, STATS = 20;

RESTORE DATABASE test_res WITH RECOVERY;
USE [master]; ALTER DATABASE test_res SET MULTI_USER;
USE test_res;

DROP USER [userabc];

CREATE USER [userabc] FOR LOGIN [userabc];

USE test_res;

ALTER ROLE [db_owner] ADD MEMBER [userabc];

USE [master];

ALTER DATABASE test_res SET RECOVERY SIMPLE WITH NO_WAIT;
18 мар 19, 16:02    [21836166]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить