針對 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 (密碼過期/必須變更)
│
└─ 連線逾時/網路錯誤 → 檢查服務、防火牆、埠、協定
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 登入屬性
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';
-m (單用戶模式) → 確定sqlcmd -S . -EALTER LOGIN sa WITH PASSWORD = 'NewStrongPwd123!' UNLOCK;
ALTER LOGIN sa ENABLE;
GO
-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 碼對照表、優先排查 |
ALTER LOGIN sa DISABLE; 建立具名 sysadmin 帳號替代ALTER LOGIN sa WITH NAME = [SQLAdmin_Prod];EVENTDATA().value('(/EVENT_INSTANCE/ClientHost)[1]', 'NVARCHAR(128)')ALTER LOGIN sa WITH CHECK_POLICY = ON, CHECK_EXPIRATION = ON;