About myself My technical skills My favorites My picture album Shortcut keys My code library VB resources SQLServer resources SQLServer books Replication FAQ Scripting resources ASP resources Search my site Sign my guestbook Contact information SQL Server Articles New ![]() |
How to troubleshoot orphan users in SQL Server databases? sp_change_users_login : Use this stored procedure to see and fix orphaned users. Books Online has complete documentation and examples Troubleshooting Orphaned Users : Refer to this section in SQL Server Books Online for troubleshooting tips. sp_validatelogins : This stored procedure reports information about orphaned Microsoft Windows NT/2000 users and groups that no longer exist in the Windows NT environment but still have entries in the Microsoft SQL Server system tables. Complete documentation is available in Books Online. Q168001 PRB: User Logon and/or Permission Errors After Restoring Dump Q274188 PRB: "Troubleshooting Orphaned Users" Topic in Books Online is Incomplete Q246133 INF: Transfer Logins and Passwords Between SQL 7.0 or SQL 2000 Servers Q240872 How to Resolve Permission Issues When a Database Is Moved Between SQL Servers As I mentioned above, we need to use sp_change_users_login to identify and fix orphaned users. But sp_change_users_login has the following limitations: - It can only show orphaned users from the current database. - It will not report orphaned users belonging to Windows accounts. (In this case, it is better to drop the user using sp_revokedbaccess, and readd the user using sp_grantdbaccess) - It will not report/fix orphaned dbo user (Orphaned dbo user can be fixed by using sp_changedbowner. This will change/update the owner of a database and associate the owning login to the dbo user). To overcome the above problems, I wrote my own stored procedure ShowOrphanUsers, that loops through all the databases and identifies all orphaned users. ShowOrphanUsers output contains two columns: The database name and the orphaned user name. We use it extensively at my work place, whenever we build new servers, or move databases between different servers and domains. It takes no input parameters. It is tested on SQL Server 2000. To get this working on SQL Server 7.0, simply remove all references to COLLATE and compile the procedure. By default, this procedure will not check the following databases for orphaned users: master, model, tempdb, msdb, distribution, pubs and northwind. If you wish to verify any of these databases, simply remove that database name from the NOT IN list, by editing the stored procedure. As the name ShowOrphanUsers indicates, it only shows the list of orphaned users! You will still have to use sp_change_users_login to fix these orphaned users. Here is the stored procedure code: CREATE PROC dbo.ShowOrphanUsers AS BEGIN CREATE TABLE #Results ( [Database Name] sysname COLLATE Latin1_General_CI_AS, [Orphaned User] sysname COLLATE Latin1_General_CI_AS ) SET NOCOUNT ON DECLARE @DBName sysname, @Qry nvarchar(4000) SET @Qry = '' SET @DBName = '' WHILE @DBName IS NOT NULL BEGIN SET @DBName = ( SELECT MIN(name) FROM master..sysdatabases WHERE name NOT IN ( 'master', 'model', 'tempdb', 'msdb', 'distribution', 'pubs', 'northwind' ) AND DATABASEPROPERTY(name, 'IsOffline') = 0 AND DATABASEPROPERTY(name, 'IsSuspect') = 0 AND name > @DBName ) IF @DBName IS NULL BREAK SET @Qry = ' SELECT ''' + @DBName + ''' AS [Database Name], CAST(name AS sysname) COLLATE Latin1_General_CI_AS AS [Orphaned User] FROM ' + QUOTENAME(@DBName) + '..sysusers su WHERE su.islogin = 1 AND su.name <> ''guest'' AND NOT EXISTS ( SELECT 1 FROM master..sysxlogins sl WHERE su.sid = sl.sid )' INSERT INTO #Results EXEC (@Qry) END SELECT * FROM #Results ORDER BY [Database Name], [Orphaned User] ENDNote: I referred to the system table sysxlogins through out this article, but this system table is not documented. Querying the system tables is not a recommended approach, but if you do want to query sysxlogins, query syslogins instead, which is a view on top of sysxlogins and is documented. |