SQL Server – Orphaned Users
A database user for which the corresponding SQL Server login is undefined or is incorrectly defined on a server instance cannot log in to the instance. Such a user is said to be an orphaned user of the database on that server instance.
A database user can become orphaned if the corresponding SQL Server login is dropped.
Also, a database user can become orphaned after a database is restored or attached to a different instance of SQL Server.
Orphaning can happen if the database user is mapped to a SID that is not present in the new server instance
Useful Tables and Stored Procedures
--First, make sure that this is the problem. This will lists the orphaned users: EXEC sp_change_users_login 'Report' -- If you already have a login id and password for this user, fix it by doing: EXEC sp_change_users_login 'Auto_Fix', 'user' -- If you want to create a new login id and password for this user, fix it by doing: EXEC sp_change_users_login 'Auto_Fix', 'user', 'login', 'password'
Orphaned Users Reports including Windows Logins
-- Report Orphaned Users Including Windows Users for a Given Database SELECT p.name FROM sys.database_principals AS p WHERE [type] IN ( N'U', N'G' ) AND NOT EXISTS ( SELECT 1 FROM sys.server_principals AS sp WHERE sp.sid = p.sid ); GO -- Report Orphaned Users Including Windows Users for a All Databases DECLARE @sql NVARCHAR(MAX) = N''; SELECT @sql += N'SELECT ''' + db.name + ''',p.name FROM ' + QUOTENAME(db.name) + '.sys.database_principals AS p WHERE [type] IN (N''U'', N''G'') AND NOT EXISTS ( SELECT 1 FROM sys.server_principals AS sp WHERE sp.sid = p.sid );' FROM sys.databases AS db WHERE [state] = 0; SELECT @sql EXEC sp_executesql @sql;
Drop Orphaned Users
-- Report Orphaned Users Including Windows Users for a Given Database SELECT ' DROP USER ' + QUOTENAME(p.name) FROM sys.database_principals AS p WHERE [type] IN ( N'U', N'G' ) AND NOT EXISTS ( SELECT 1 FROM sys.server_principals AS sp WHERE sp.sid = p.sid );
Drop orphaned users who doesn’t have any dependencies.
If they have dependencies, you need to drop the dependencies explicitly before dropping the orphaned users.
Otherwise , you will encounter errors like this.
/*
Msg 15421, Level 16, State 1, Line 1
The database principal owns a database role and cannot be dropped.
*/
DECLARE cur CURSOR FAST_FORWARD FOR SELECT name FROM sys.databases WHERE database_id > 4; OPEN cur; DECLARE @SQL AS NVARCHAR (MAX), @DBName AS SYSNAME, @pUserName NVARCHAR(255) DECLARE @Results TABLE ( DBName SYSNAME , UserName SYSNAME , UserSID VARBINARY (MAX)); FETCH NEXT FROM cur INTO @DBName; WHILE @@FETCH_STATUS = 0 BEGIN SET @SQL = 'USE ' + @DBName + '; SELECT ''' + @DBName + ''' AS DBName, UserName = name, UserSID = sid from sysusers WHERE issqluser = 1 AND (sid IS NOT NULL AND sid <> 0x0) AND (LEN(sid) <= 16) AND SUSER_SNAME(sid) IS NULL'; INSERT INTO @Results EXECUTE (@SQL); FETCH NEXT FROM cur INTO @DBName; END CLOSE cur; DEALLOCATE cur; SELECT * FROM @Results DECLARE c CURSOR FOR SELECT DBName , UserName FROM @Results WHERE UserName NOT IN ('dbo') OPEN c FETCH NEXT FROM c INTO @DBName , @pUserName WHILE @@FETCH_STATUS = 0 BEGIN SELECT @SQL = 'USE ' + @DBName + CHAR(13)+ 'DROP USER ' + '['+@pUserName +']'+ CHAR(13) PRINT @SQL EXEC (@SQL) FETCH NEXT FROM c INTO @DBName , @pUserName END CLOSE c DEALLOCATE c