SQL Server登入無法連線到SQL Server,可能是因為與預設資料庫中登入相關聯的資料庫使用者的許可權問題,或是其預設資料庫發生問題。

許可權問題可以是下列其中一或多個:

  • 登入在其預設資料庫中沒有對應的對應使用者。
  • 您已將預設資料庫指派給登入,但未在指定的資料庫中建立使用者對應。
  • 登入的對應使用者遭到拒絕存取。 (例如,如果使用者不小心新增至 db_denydatareader 固定資料庫角色,就會發生這種情況。)
  • 因為下列原因,在連線時可能無法使用預設資料庫:

  • 預設資料庫處於可疑模式。
  • 預設資料庫已不存在。
  • 預設資料庫處於單一使用者模式,而且其他人或其他專案已使用唯一可用的連線。
  • 預設資料庫已中斷連結。
  • 預設資料庫會設定為RESTRICTED_USER狀態。
  • 預設資料庫離線。
  • 預設資料庫會設定為 EMERGENCY 狀態。
  • 預設資料庫是資料庫鏡像的一部分。
  • 此外,登入帳戶可能是多個群組的成員,而且連線時無法使用其中一個群組的預設資料庫。

    如需SQL Server中資料庫使用者的詳細資訊,請參閱 建立資料庫使用者

    使用者動作

    您可以採取下列其中一個動作:

    解決此問題

    如果您不需要存取目前設定的預設資料庫,而且只需要使用 SQL Server Management Studio (SSMS) 連線至其他作業的 SQL Server 實例,請遵循下列步驟:

  • 開啟 SQL Server Management Studio (SSMS)。

  • 物件總管 上,選取 [ 連接 > 資料庫引擎 ]。

  • 填寫 [ 連接到伺服器 ] 對話方塊。

  • 選取 [選項]。

  • 在 [ 連接屬性 ] 下,使用下列其中一個選項來修改 [連接到資料庫 ] 值:

  • 如果登入是系統管理員角色的成員,請輸入 master ,然後選取 [ 連線 ] 以建立與SQL Server的連線。 成功連線至SQL Server之後,您可以將預設資料庫變更為 SSMS 中登入屬性的 [ 一般 ] 頁面中目前可用的不同資料庫。 如需詳細資訊,請參閱 建立登入

  • 如果登入不是系統管理員角色的成員,請在您知道您有權存取的伺服器上輸入資料庫名稱。 或者,您可以嘗試輸入系統資料庫名稱,例如 master ,然後選取 [ 連線 ]。 如果您的系統管理員已明確拒絕資料庫中來賓使用者 master 的許可權,此步驟可能無法運作。 在該案例中,您必須與系統管理員合作,才能解決問題。

    系統管理員可以使用下列查詢來檢查使用者目前的預設資料庫是什麼:

    SELECT name, default_database_name
    FROM sys.server_principals
    WHERE type = 'S' AND name = '<sql-login>';
    

    使用下表來判斷修正問題的適當動作,以因應相關聯的原因:

    登入的預設資料庫中沒有使用者對應,或使用者遭到拒絕存取。 這些資料庫使用者也稱為孤立的使用者。 當資料庫在兩個伺服器實例之間移動,而且是 4064 錯誤常見原因之一時,通常會發生此問題。 若要偵測孤立的使用者並解決問題,請參閱針對孤立的使用者進行疑難排解 (SQL Server) 。 登入沒有資料庫使用者存在 建立資料庫使用者 ,並指派存取資料庫的相關許可權。 資料庫使用者帳戶拒絕存取資料庫的許可權 流覽至資料庫中的使用者屬性, ([展開資料庫節點 >安全性>使用者]) ,並檢查使用者是否屬於 [成員資格] 頁面中db_denydatareader角色的一部分。 您也可以使用 sys.fn_my_permissions來檢查使用者的有效許可權。 預設資料庫處於可疑模式。 資料庫會因為許多原因而變成可疑。 可能的原因包括作業系統拒絕存取資料庫資源,以及一或多個資料庫檔案無法使用或損毀。 您可以使用此查詢來檢查資料庫的狀態: SELECT DATABASEPROPERTYEX (N'<dbname>', N'STATUS') AS N'Database Status'; 。 在 SSMS 中,可疑資料庫的狀態會顯示為 (復原擱置) 。 您可能必須從其備份復原資料庫,才能解決此問題。 預設資料庫已不存在。 如果您已刻意從伺服器移除資料庫,請使用 SSMS 或 ALTER LOGIN (Transact-SQL) 語句,將登入的預設資料庫變更為伺服器上的另一個現有資料庫。 您可以選擇性地檢查伺服器上是否有其他登入,其預設資料庫是使用此查詢設定為這個非現有的資料庫: SELECT name AS Login_Name FROM sys.server_principals where default_database_name = '<removed-dbname>'; 。 預設資料庫處於單一使用者模式,而系統管理員或其他人只會使用連線。 如果資料庫設定為單一使用者模式以供維護之用,您應該在維護活動完成之後將其設定回多使用者模式,使用此查詢: ALTER DATABASE <dbname> SET MULTI_USER;
    如需詳細資訊,請參閱 將資料庫設定為單一使用者模式
    注意:若要檢查資料庫是否處於單一使用者模式,您可以使用此查詢: SELECT name, user_access_desc FROM sys.databases WHERE name = '<dbname>';
    如果您仍然需要限制資料庫的存取,但想要啟用受影響登入的連線能力,請將其預設資料庫變更為伺服器上的不同資料庫。 預設資料庫已中斷連結。 卸離資料庫會從 SQL Server 實例中移除它,而且無法再存取。 若要讓它可供登入使用,請使用 SSMS 或 sp_attach_db 預存程式附加資料庫。 如需詳細資訊,請參閱資料庫卸離和附加 (SQL Server) 。 預設資料庫已設定為RESTRICTED_USER狀態。 當資料庫設定為RESTRICTED_USER狀態時,只有db_owner固定資料庫角色的成員和 dbcreator 和 sysadmin 固定伺服器角色可以連線到資料庫。 如果您不再需要限制對對應資料庫的存取,請使用此查詢將資料庫設定為多使用者模式: ALTER DATABASE <dbname> SET MULTI_USER;
    注意:若要檢查資料庫是否處於受限制的使用者狀態,您可以使用此查詢: SELECT name, user_access_desc FROM sys.databases WHERE name = '<dbname>';
    如果您仍然需要限制資料庫的存取,但想要啟用受影響登入的連線能力,請將其預設資料庫變更為伺服器上的不同資料庫。 預設資料庫離線。 無法修改處於離線狀態的資料庫。 您可以使用此查詢讓資料庫上線: ALTER database <dnname> SET ONLINE;
    您可以使用 SSMS 或使用此查詢來檢查資料庫是否為 OFFLINE: SELECT DATABASEPROPERTYEX (N'<dbname>', N'STATUS') AS N'Database Status';
    如需詳細資訊,請參閱資料庫狀態ALTER DATABASE SET 選項 (Transact-SQL) - SQL Server
    如果您仍然需要讓資料庫處於離線狀態,但想要啟用受影響登入的連線能力,請將其預設資料庫變更為伺服器上的不同資料庫。 預設資料庫會設定為 EMERGENCY 狀態。 資料庫可能已進入緊急狀態,以便系統管理員進行疑難排解。 只有系統管理員角色的使用者才能存取設定為 EMERGENCY 狀態的資料庫。 您可以使用此查詢讓資料庫上線: ALTER database <dnname> SET ONLINE;
    您可以使用 SSMS 檢查資料庫是否處於緊急狀態,或此查詢: SELECT DATABASEPROPERTYEX (N'<dbname>', N'STATUS') AS N'Database Status';
    如需詳細資訊,請參閱資料庫 狀態ALTER DATABASE SET 選項 (Transact-SQL)
    如果您仍然需要讓資料庫處於緊急狀態,但想要啟用受影響登入的連線能力,請將其預設資料庫變更為伺服器上的不同資料庫。 預設資料庫是資料庫鏡像的一部分。 您無法連線到鏡像伺服器上的鏡像資料庫,而此行為是設計方式。 若要檢查資料庫目前是否處於鏡像角色,請使用此查詢 SELECT DB_NAME(database_id) as database_name, mirroring_role_desc FROM sys.database_mirroring WHERE DB_NAME(database_id) = '<dbname>'; 。 如需資料庫鏡像的詳細資訊,請參閱資料庫鏡像 (SQL Server) 。 登入帳戶可能是多個群組的成員,而其中一個群組的預設資料庫在連線時無法使用。 若要使用 PowerShell 列舉具有指定使用者的群組,請參閱 Get-ADPrincipalGroupMembership (ActiveDirectory)

    變更指定使用者的預設資料庫

    若要對使用者的預設資料庫進行變更,您必須具有 ALTER ANY LOGIN 許可權。 如果變更的登入是系統管理員固定伺服器角色的成員或 CONTROL SERVER 許可權的被授與者,在進行下列變更時也需要 CONTROL SERVER 許可權。 系統管理員角色的成員預設會啟用這些許可權。 如需詳細資訊,請參閱 ALTER LOGIN (Transact-SQL)

    SQL Server Management Studio sqlcmd 公用程式 PowerShell

    使用 SSMS 變更預設資料庫

  • 使用 SQL Server Management Studio (SSMS) 連線到您的SQL Server實例。

  • 選取[安全性>登入] 以找出使用者,並將使用者的預設資料庫變更為 SSMS 中登入屬性的 [一般] 頁面中目前可用的不同資料庫。 如需詳細資訊,請參閱 建立登入

  • 連接到 SQL Server 實例之後,您可以執行 ALTER LOGIN 語句,例如下列範例:

    ALTER LOGIN <LoginName> WITH DEFAULT_DATABASE = <AvailableDatabaseName>;

    <AvailableDatabaseName>是實例中SQL Server登入可以存取之現有資料庫名稱的預留位置。 <LoginName>是具有必要 ALTER LOGIN 許可權之SQL Server登入的預留位置。

    ALTER LOGIN [SQLLogin] WITH DEFAULT_DATABASE = master;
    ALTER LOGIN [Constoso\Windowslogin] WITH DEFAULT_DATABASE = [AdventureWorks];
    

    您可以使用下列程式,使用 sqlcmd 公用程式來變更預設資料庫:

  • 在執行SQL Server的電腦上,選取 [開始],然後選取 [執行],輸入 cmd ,然後按Enter

  • 使用sqlcmd公用程式與下列其中一個選項連線至SQL Server:

  • 如果您想要使用Windows 驗證使用目前登入的 Windows 使用者帳戶連線到實例,請在 [命令提示字元] 視窗中輸入下列命令,然後按Enter

    sqlcmd -E -S <InstanceName> -d master

    sqlcmd -S "contoso\sql22" -E -d master
    
  • 如果您想要使用SQL Server驗證來連線到實例,請在 [命令提示字元] 視窗中輸入下列命令,然後按Enter

    sqlcmd -S <InstanceName> -d master -U <SQLAdminAccount> -P <Password>

    <InstanceName>是您要連線之SQL Server實例名稱的預留位置。 <Password>是SQL Server登入密碼的預留位置。

    sqlcmd -S contososql -U sqladmin -P <Strong password>
    
  • 若要變更登入的預設資料庫,請在 sqlcmd 提示字元中使用下列範例,然後按 Enter

    ALTER LOGIN <LoginName> WITH DEFAULT_DATABASE = <AvailableDatabaseName>;

    <AvailableDatabaseName>是實例中SQL Server登入可以存取之現有資料庫名稱的預留位置。 <LoginName>是具有必要 ALTER LOGIN 許可權之SQL Server登入的預留位置。

    ALTER LOGIN [SQLLogin] WITH DEFAULT_DATABASE = master;
    ALTER LOGIN [Constoso\Windowslogin] WITH DEFAULT_DATABASE = [AdventureWorks];
    
  • sqlcmd 提示字元中,輸入 GO ,然後按 Enter

    如需 sqlcmd 公用程式的詳細資訊,請參閱 sqlcmd - 使用公用程式

    使用 PowerShell 變更預設資料庫

    您可以使用下列 PowerShell 腳本來更新指定登入的預設資料庫。

    # Define the variables for the SQL Server instance name and login name
    $instanceName = "YOUR_SQL_SERVER_INSTANCE_NAME"
    $loginName = "YOUR_SQL_SERVER_LOGIN_NAME"
    $newDefaultDB = "YOUR_NEW_DEFAULT_DATABASE"
    # Connect to the SQL Server instance
    $connectionString = "Server=$instanceName;Integrated Security=True"
    $connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
    $connection.Open()
    # Execute a T-SQL command to change the default database for the specified login
    $tsql = "ALTER LOGIN $loginName WITH DEFAULT_DATABASE = $newDefaultDB"
    $command = New-Object System.Data.SqlClient.SqlCommand($tsql, $connection)
    $command.ExecuteNonQuery()
    # Print a message indicating the update was successful
    Write-Host "The default database for the login '$loginName' has been successfully updated to '$newDefaultDB'"
    # Close the SQL Server connection
    $connection.Close()
    

    錯誤 18456 連同錯誤 4064 一起顯示

    使用 SSMS 之類的應用程式向使用者顯示錯誤 4064 時,下列訊息會記錄在SQL Server錯誤記錄檔中。 這是設計的行為。 使用本文中所述的程式,修正失敗登入的預設資料庫,會自動解決 18456 錯誤。

    2023-02-06 18:17:02.56 Logon       Error: 18456, Severity: 14, State: 40.
    2023-02-06 18:17:02.56 Logon       Login failed for user '<user name>. Reason: Failed to open the database '<db_name>' specified in the login properties. [CLIENT: <hostname >]
    
  •