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

SQL Server 錯誤 21002:建立登入時提示使用者已存在(孤立使用者修復)

     編輯:關於SqlServer

錯誤現象

企業管理器 → 新增登入 → 「資料庫存取」分頁勾選目標資料庫時,彈出:

錯誤 21002:[SQL-DMO] 使用者 'UserName' 已經存在。

根因:孤立使用者

  • 資料庫從舊伺服器遷移至新伺服器,sysusers/sys.database_principals 保留了原使用者記錄(含 SID)。
  • 新伺服器 sys.server_principals 無對應登入(SID 不匹配)。
  • 嘗試為同名登入授權資料庫時,SQL Server 發現資料庫內已有同名使用者但 SID 不同,判定衝突而報錯。

修復步驟

1. 先建立同名登入(不授權任何資料庫)

CREATE LOGIN [UserName] WITH PASSWORD = 'StrongPassword@123';
-- 或 Windows 驗證
CREATE LOGIN [DOMAIN\UserName] FROM WINDOWS;

2. 映射登入與資料庫使用者


USE TargetDatabase;
GO
EXEC sp_change_users_login 'Update_One', 'UserName', 'UserName';
GO
  • Update_One:將資料庫使用者 UserName 的 SID 更新為登入 UserName 的 SID。
  • 執行後,使用者不再孤立,可正常授權。

批次修復所有孤立使用者


USE TargetDatabase;
GO
DECLARE @user SYSNAME;
DECLARE cur CURSOR LOCAL FAST_FORWARD FOR
    SELECT name FROM sys.database_principals 
    WHERE type IN ('S','U','G') AND sid IS NOT NULL 
      AND sid NOT IN (SELECT sid FROM sys.server_principals)
      AND name NOT IN ('dbo','guest','INFORMATION_SCHEMA','sys');
OPEN cur;
FETCH NEXT FROM cur INTO @user;
WHILE @@FETCH_STATUS = 0
BEGIN
    BEGIN TRY
        EXEC sp_change_users_login 'Auto_Fix', @user;
        PRINT 'Fixed: ' + @user;
    END TRY
    BEGIN CATCH
        PRINT 'Failed: ' + @user + ' - ' + ERROR_MESSAGE();
    END CATCH
    FETCH NEXT FROM cur INTO @user;
END
CLOSE cur; DEALLOCATE cur;

驗證修復結果


-- 再次掃描孤立使用者
EXEC sp_change_users_login 'Report';
-- 應無記錄返回

預防最佳實務

  1. 遷移前腳本化登入:使用 sp_help_revlogin (Microsoft 提供) 產生含 SID 的 CREATE LOGIN 腳本,在目標伺服器先執行。
  2. 還原後立即執行 sp_change_users_login 'Report' 並自動化修復。
  3. 含資料庫擁有者:dbo 孤立需用 sp_changedbowner 修復(參考錯誤 21776 文章)。
  4. 自動化部署管線:將「登入同步 → 資料庫還原 → 孤立使用者修復」納入 CI/CD 階段。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved