首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 刪除資料庫使用者受阻:「主體擁有結構描述無法刪除」完整解決方案

     編輯:關於SqlServer

在 SSMS 中嘗試刪除資料庫使用者時,彈出錯誤:「資料庫主體在該資料庫中擁有結構描述,無法刪除」 (錯誤 15138)。本文提供三種層層遞進的解決方案,從圖形介面到 T-SQL 腳本,徹底清除擁有權阻礙。

錯誤原因

使用者擁有資料庫內的結構描述 或物件 (表、檢視、SP 等),SQL Server 禁止刪除擁有物件的主體,以防孤立物件產生。

方案一:圖形介面手動清理 (適用物件較少)

  1. SSMS → 資料庫 → 安全性 → 結構描述,找到該使用者擁有的結構描述 (Owner 欄位為該使用者)
  2. 右鍵結構描述 → 「屬性」 → 將「結構描述擁有者」改為 dbo,或直接刪除空結構描述
  3. 返回「使用者」節點,再次嘗試刪除使用者

方案二:T-SQL 快速轉移結構描述擁有權 (推薦)


-- 在目標資料庫執行
ALTER AUTHORIZATION ON SCHEMA::db_owner TO dbo;
-- 或針對特定結構描述
ALTER AUTHORIZATION ON SCHEMA::[UserSchema] TO dbo;

執行後重新整理,即可刪除使用者。

方案三:批次轉移所有使用者物件給 dbo (徹底清理)

適用於大量物件、遷移資料庫、清理孤立使用者場景:


USE YourDatabaseName;
GO

DECLARE @sql NVARCHAR(MAX) = N'';

-- 1. 轉移結構描述擁有權 (非 dbo 的結構描述)
SELECT @sql += N'ALTER AUTHORIZATION ON SCHEMA::' + QUOTENAME(name) + N' TO dbo;'
FROM sys.schemas 
WHERE principal_id <> SCHEMA_ID('dbo') AND name NOT IN ('sys', 'INFORMATION_SCHEMA');

-- 2. 轉移物件擁有權 (非 dbo 擁有的表、檢視、SP 等)
SELECT @sql += N'ALTER AUTHORIZATION ON OBJECT::' + QUOTENAME(s.name) + N'.' + QUOTENAME(o.name) + N' TO dbo;'
FROM sys.objects o
JOIN sys.schemas s ON o.schema_id = s.schema_id
WHERE o.principal_id IS NOT NULL 
  AND o.principal_id <> SCHEMA_ID('dbo')
  AND o.type IN ('U', 'V', 'P', 'FN', 'IF', 'TF', 'TR');

-- 3. 執行動態 SQL
EXEC sp_executesql @sql;
GO

方案四:強制刪除 (不推薦,僅限緊急且了解風險)

  1. SSMS → 伺服器屬性 → 允許對系統目錄直接修改
  2. 刪除 sysusers / sys.database_principals 中對應列
  3. 還原系統目錄修改設定
  4. 重建使用者

風險:直接改系統表可能導致資料庫損壞、升級失敗、不受支援。嚴禁生產環境使用。

常見遷移場景:備份還原產生孤立使用者

將資料庫從主機 A 備份還原到主機 B 後,常出現:

  • 原登入在新主機不存在 → 孤立使用者
  • 無法刪除原使用者,提示「擁有物件」

標準處理流程:

  1. 建立新登入:CREATE LOGIN NewUser WITH PASSWORD = '...';
  2. 對應使用者:ALTER USER OldUser WITH LOGIN = NewUser; (或 sp_change_users_login 'update_one', 'OldUser', 'NewUser')
  3. 轉移物件擁有權:EXEC sp_changeobjectowner 'OldUser.TableName', 'dbo'; 逐一轉移
  4. 刪除舊使用者:DROP USER OldUser;
  5. 刪除舊登入:DROP LOGIN OldLogin;

sp_changeobjectowner 使用範例


-- 將 web102101 擁有的所有表轉給 dbo
EXEC sp_changeobjectowner 'web102101.Orders', 'dbo';
EXEC sp_changeobjectowner 'web102101.Customers', 'dbo';
-- ... 依此類推

轉移完成後,即可在「使用者」與「登入」節點刪除舊帳號。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved