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

SQL Server sa 登入失敗完整排查與解決方案

     編輯:關於SqlServer

sa 帳號無法登入的常見原因與解決步驟

針對 SQL Server 2005/2008/2012/2014/2016/2017/2019/2022 版本,系統性排查 sa 登入失敗的根本原因並提供解決方案。

快速診斷流程圖

sa 登入失敗
    │
    ├─ 錯誤 18456 (登入失敗) → 檢查狀態碼
    │       ├─ State 1: 錯誤資訊隱藏 (安全性)
    │       ├─ State 2/5: 無效使用者 ID / 使用者不存在
    │       ├─ State 6/7: 嘗試用 Windows 認證登入 SQL 認證帳號
    │       ├─ State 8: 密碼錯誤
    │       ├─ State 9: 無效密碼
    │       ├─ State 11/12: 登入有效但伺服器存取被拒
    │       ├─ State 16: 登入有效但資料庫存取被拒
    │       └─ State 18: 密碼過期需變更
    │
    ├─ 錯誤 18470 (登入失敗:帳號已停用)
    │
    ├─ 錯誤 18487/18488 (密碼過期/必須變更)
    │
    └─ 連線逾時/網路錯誤 → 檢查服務、防火牆、埠、協定

解決方案一:啟用混合模式驗證 (最常見原因)

  1. 開啟 SQL Server Management Studio (SSMS),以 Windows 管理員身分連線
  2. 右鍵伺服器節點 → 內容 → 安全性 頁面
  3. 伺服器驗證 區域選擇:SQL Server 和 Windows 驗證模式
  4. 點擊 確定 → 系統提示需重啟服務生效
  5. 右鍵伺服器 → 重新啟動

T-SQL 替代方案 (無法開啟 SSMS 時):

-- 需以 sysadmin 身分連線 (Windows 管理員)
EXEC xp_instance_regwrite 
    N'HKEY_LOCAL_MACHINE', 
    N'Software\Microsoft\MSSQLServer\MSSQLServer', 
    N'LoginMode', 
    REG_DWORD, 
    2;  -- 1=Windows Only, 2=Mixed Mode

-- 重啟服務
-- net stop MSSQLSERVER && net start MSSQLSERVER

解決方案二:重置 sa 密碼與解鎖帳號

  1. 以 Windows 管理員身分開啟 SSMS,Windows 驗證連線
  2. 展開 安全性 → 登入 → 右鍵 sa → 內容
  3. 一般 頁面:
    • 輸入新密碼、確認密碼 (符合複雜度原則)
    • 取消勾選「強制密碼過期」與「使用者下次登入時必須變更密碼」
  4. 狀態 頁面:
    • 登入:已啟用 (Enabled)
    • 連線到資料庫引擎:授與 (Grant)
  5. 點擊 確定 儲存

解決方案三:檢查預設資料庫與連線權限

-- 檢查 sa 登入屬性
SELECT name, is_disabled, default_database_name, 
       CREATE_DATE, MODIFY_DATE, 
       LOGINPROPERTY(name, 'IsLocked') AS IsLocked,
       LOGINPROPERTY(name, 'PasswordLastSetTime') AS PwdLastSet,
       LOGINPROPERTY(name, 'BadPasswordCount') AS BadPwdCount,
       LOGINPROPERTY(name, 'BadPasswordTime') AS BadPwdTime
FROM sys.server_principals 
WHERE name = 'sa' AND type = 'S';

-- 修正預設資料庫 (若預設 DB 被刪除/離線)
ALTER LOGIN sa WITH DEFAULT_DATABASE = master;

-- 確認 sysadmin 角色成員資格
SELECT sp.name AS LoginName, sp.type_desc, 
       CASE WHEN srv.role_principal_id IS NOT NULL THEN 'YES' ELSE 'NO' END AS IsSysadmin
FROM sys.server_principals sp
LEFT JOIN sys.server_role_members srm ON sp.principal_id = srm.member_principal_id
LEFT JOIN sys.server_principals srv ON srm.role_principal_id = srv.principal_id AND srv.name = 'sysadmin'
WHERE sp.name = 'sa';

解決方案四:重啟 SQL Server 服務 (關鍵步驟)

  1. 開啟 服務 (services.msc) 或 SQL Server 組態管理員
  2. 找到目標執行個體:SQL Server (MSSQLSERVER) 或 SQL Server (具名實體名)
  3. 右鍵 → 重新啟動
  4. 等待狀態變為「執行中」
  5. 關閉所有現有 SSMS/應用程式連線,重新開啟嘗試登入

解決方案五:單用戶模式緊急重置 (以上皆失效時)

  1. SQL Server 組態管理員 → 服務 → 目標執行個體 → 內容 → 啟動參數
  2. 加入 -m (單用戶模式) → 確定
  3. 重啟服務
  4. 命令列以 Windows 管理員身分執行:sqlcmd -S . -E
  5. 執行重置:
    ALTER LOGIN sa WITH PASSWORD = 'NewStrongPwd123!' UNLOCK;
    ALTER LOGIN sa ENABLE;
    GO
  6. 移除 -m 參數,重啟服務恢復正常

進階排查:錯誤日誌分析

-- 讀取 SQL Server 錯誤日誌 (最近 5 個檔案)
EXEC sp_readerrorlog 0, 1, 'Login failed', 'sa';
EXEC sp_readerrorlog 1, 1, 'Login failed', 'sa';
-- 參數: 0=目前日誌, 1=SQL Server 錯誤日誌, 搜尋字串1, 搜尋字串2

-- 關鍵日誌項目解讀:
-- "Login failed for user 'sa'. Reason: Password did not match..." → 密碼錯誤
-- "Login failed for user 'sa'. Reason: The account is disabled." → 帳號停用
-- "Login failed for user ''. Reason: Attempting to use an NT account name with SQL Server Authentication." → 驗證模式錯誤
-- "Error: 18456, Severity: 14, State: 8." → State 8 = 密碼錯誤

常見陷阱與避坑指南

操作風險正確做法
直接修改 master..syslogins 密碼欄位SQL Server 2005+ 不支援,導致系統表損毀使用 ALTER LOGIN / sp_password
重新安裝 SQL Server 解決密碼問題資料遺失、設定遺失、過度殺傷單用戶模式重置、註冊表修改驗證模式
sa 密碼設為簡單密碼 (123456、sa、password)極高安全風險、自動化攻擊目標複雜密碼、定期輪換、停用 sa 改用專用帳號
應用程式連線字串硬編碼 sa原始碼洩漏即資料庫失陷專用低權限帳號、Azure Key Vault/密碼管理器
忽略錯誤日誌 State 碼錯失精確診斷方向記錄 State 碼對照表、優先排查

安全性強化建議 (解決登入問題後必做)

  1. 停用 sa:ALTER LOGIN sa DISABLE; 建立具名 sysadmin 帳號替代
  2. 重新命名 sa:ALTER LOGIN sa WITH NAME = [SQLAdmin_Prod];
  3. 啟用登入稽核:伺服器屬性 → 安全性 → 登入稽核:失敗的登入 (生產建議「成功和失敗」)
  4. 限制連線 IP:登入觸發器檢查 EVENTDATA().value('(/EVENT_INSTANCE/ClientHost)[1]', 'NVARCHAR(128)')
  5. 密碼原則:ALTER LOGIN sa WITH CHECK_POLICY = ON, CHECK_EXPIRATION = ON;
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved