Восстановление потерянных пользователей (Orphaned Users) в MSSQL после RESTORE
- Пользователи или сервисные учетные записи 1С не могут авторизоваться в восстановленной базе с ошибкой
Login failed for user (Error 18456). - В системной таблице
sys.database_principalsпользователь существует, но егоSIDне совпадает сSIDвsys.server_principalsинстанса. - Невозможно пересоздать пользователя базы, так как объект с таким именем уже зарегистрирован.
1. Поиск изолированных пользователей (Orphaned Users)
USE [TradeEnterprise];
GO
-- Поиск пользователей базы без сопоставленного серверного логина
SELECT
dp.name AS DatabaseUserName,
dp.type_desc,
dp.sid AS DatabaseSID
FROM sys.database_principals dp
LEFT JOIN sys.server_principals sp ON dp.sid = sp.sid
WHERE sp.sid IS NULL
AND dp.type IN ('S', 'U', 'G') -- SQL, Windows User, Windows Group
AND dp.authentication_type = 1; -- INSTANCE authentication2. Автоматическое сопоставление пользователя с существующим серверным логином
Используйте современный синтаксис ALTER USER:
USE [TradeEnterprise];
GO
-- Привязка существующего пользователя базы к одноименному логину инстанса
ALTER USER [user_1c] WITH LOGIN = [user_1c];
GO3. Массовое исправление всех изолированных пользователей через курсор
USE [TradeEnterprise];
GO
DECLARE @username VARCHAR(100);
DECLARE user_cursor CURSOR FOR
SELECT dp.name
FROM sys.database_principals dp
LEFT JOIN sys.server_principals sp ON dp.sid = sp.sid
WHERE sp.sid IS NULL AND dp.type = 'S' AND dp.name NOT IN ('guest', 'INFORMATION_SCHEMA', 'sys');
OPEN user_cursor;
FETCH NEXT FROM user_cursor INTO @username;
WHILE @@FETCH_STATUS = 0
BEGIN
IF EXISTS (SELECT 1 FROM sys.server_principals WHERE name = @username)
BEGIN
EXEC('ALTER USER [' + @username + '] WITH LOGIN = [' + @username + '];');
PRINT 'Fixed user: ' + @username;
END
ELSE
BEGIN
PRINT 'Server Login not found for user: ' + @username;
END
FETCH NEXT FROM user_cursor INTO @username;
END;
CLOSE user_cursor;
DEALLOCATE user_cursor; Частые вопросы (FAQ)
Почему возникают Orphaned Users при переносе базы на другой сервер?
Права внутри базы привязаны к глобальному идентификатору безопасности (SID). При создании одноименного логина на новом сервере ему присваивается новый уникальный GUID/SID, не совпадающий с сохраненным внутри файла базы.
Почему процедура sp_change_users_login считается устаревшей?
Хранимая процедура sp_change_users_login объявлена как Deprecated начиная с SQL Server 2012. Ее официальной заменой является инструкция ALTER USER ... WITH LOGIN.
Как перенести серверные логины с сохранением оригинальных SID и паролей?
Используйте официальную хранимую процедуру sp_help_revlogin от Microsoft, которая генерирует T-SQL скрипт создания логинов с параметрами SID и HASHED паролем.
Что делать, если учетная запись базы является владельцем схемы (Schema Owner)?
Перед удалением или сменой прав передайте владение схемой пользователю dbo: ALTER AUTHORIZATION ON SCHEMA::[SchemaName] TO [dbo];.