Drop User Error Msg 15138, Level 16, State 1, Line 5 The database principal owns a schema in the database, and cannot be dropped.

Msg 15138, Level 16, State 1, Line 5 The database principal owns a schema in the database, and cannot be dropped.
Things constantly change and one such thing is the addition and removal of users and servers.  In an attempt to remove a Machine account SQL Server login that was being replaced we know that removing a user from an Instance is not the same as removing them from a databases.  The Instance removal was simple however I came across this error message at the database level "The database principal owns a schema in the database, and cannot be dropped. (Msg 15138, Level 16, State 1, Line 5)".  

Here are some steps to successfully review and drop the SQL Server user database logins:
1. What schema(s) does the user own?
The following example finds the user and each schema owner.
SELECT s.name, USER_NAME(s.principal_id) AS Schema_Owner
FROM sys.schemas s
-- WHERE s.principal_id = USER_ID('You user Name');

B. Now reassign or drop the schema the choice is up to you.

Quick and dirty would be to simply reassign the schema to [dbo].  If you can confirm that it's not in use or will not ever be used then drop it.  If there is an existing reference or something you missed and you do attempt to drop the schema it will fail with a message similar to the following: " Msg 3729, Level 16, State 1, Line 29 Cannot drop schema 'Your Schema' because it is being referenced by object 'Something'. " 

USE [Your Database Name]
GO

ALTER AUTHORIZATION ON SCHEMA::[Your Schema] TO [dbo]
-- DROP SCHEMA [You Schema name]
GO

C. Schema reference to a Table

If the Schema is used in a table name then you will need to do more research and ensure there isn't other references in stored procedures or view or even triggers.  So assuming you have done your research you are now free to us sp_changeobjectowner 'Old Schema.TableName','new schema'.
sp_changeobjectowner 'YourSchema.table','dbo'

D. Finally Drop User from database and verify that they do not exist anywhere that you would not expect.

Use the below to identify if a user exists on any database across the entire SQL Instance for all databases that are online and accessible.  Update 'User2Search4' to be the login you are looking for.  Note that in the last few lines we are doing a like serach on the login being searched so it can be changed as need.
SET NOCOUNT ON; -- Update the below 'User2Search4' for the User to verify if Exists and in what database DECLARE @LoginName VARCHAR(255)='User2Search4' CREATE TABLE #temp (SERVER_name SYSNAME NULL,Database_name SYSNAME NULL,UserName SYSNAME,GroupName SYSNAME ,LoginName SYSNAME NULL,DefDBName SYSNAME NULL,DefSchemaName SYSNAME NULL,UserID INT,[SID] VARBINARY(85)); DECLARE @command VARCHAR(MAX); --this will be used for all the databases and their sizes on a server DECLARE @databases TABLE (Database_name VARCHAR(255),Database_size INT,remarks VARCHAR(Max)); INSERT INTO @databases -- Load with the list of databases EXEC sp_databases; SELECT @command = COALESCE( @command, '' ) + ' USE ' + database_name + ' insert into #temp (UserName,GroupName, LoginName,DefDBName, DefSchemaName,UserID,[SID]) Execute sp_helpuser UPDATE #TEMP SET database_name=DB_NAME(),server_name=@@ServerName where database_name is null' FROM @databases; EXECUTE (@command); DECLARE @LoginName2 VARCHAR(255)='%'+@LoginName+'%' SELECT loginname, UserName, Database_name FROM #temp WHERE LoginName LIKE @LoginName2; DROP TABLE #temp


Comments

Popular posts from this blog

How to mass update all or some sql server agent job step commands

SQL Monitoring for Blocking and Locking Capture and Log to table with sp_WhoIsActive or sp_BlitzWho

SQL Server General Index Naming Convention