Share via


MSSQLSERVER_15517

適用於:SQL Server

詳細資料

屬性
產品名稱 SQL Server
事件識別碼 15517
事件來源 MSSQLSERVER
元件 SQLEngine
符號名稱 SEC_CANNOTEXECUTEASUSER
訊息文字 無法以資料庫主體的形式執行,因為主體 「principal」 不存在、無法模擬此類型的主體,或您沒有許可權。

說明

此錯誤通常會發生,因為 Microsoft SQL Server 無法使用 語句取得用戶語句或模組 EXECUTE AS 中所指定主體執行內容的相關信息。

當您在 SQL Server 實例上建立資料庫時,系統會自動儲存登入資訊安全性識別碼,作為數據表中對應資料庫數據列中 sys.databases 的資料庫擁有者,以及 dbo 資料庫中數據表中 sys.database_principals 之使用者專案的資料庫擁有者。

如果針對 dbo 使用者儲存的 SID 專案有效,使用 EXECUTE AS OWNER 子句的語句或模組將如預期般運作。

注意

在語句中使用的 EXECUTE AS 任何主體,且不存在於還原資料庫的伺服器上,都可能發生此問題。

以下是一些可能導致此問題發生的常見案例:

  • 您在原本建立備份的相同伺服器實例上還原資料庫,但建立資料庫的 SQL Server 主體因某些原因已不再有效。 例如:

    • 已移除 SQL Server 驗證登入。
    • Windows 驗證 登入已不再供 Active Directory 中的有效使用者使用,因為員工離開公司。
  • 您在原本建立備份的實例不同的伺服器上還原資料庫,但建立資料庫的 SQL Server 主體不是新伺服器上的有效主體。

    • 如果使用者是 SQL Server 登入,則主體可能存在於目標或目的地伺服器上,但 sid 值會不同。
    • 如果使用者是 Windows 登入,則目標伺服器上沒有 Windows 登入,或不再有效。

執行預存程式、函式或觸發程式的使用者或應用程式沒有模擬 語句中所 EXECUTE AS 指定主體的必要許可權。

使用者動作

使用現有主體的名稱,或將該主體的 IMPERSONATE 許可權授與必要的使用者。

若要解決因為無效 dbo 使用者錯誤而發生的問題,請執行下列命令,將 值變更 dbo_User 為伺服器上的有效登入:

ALTER AUTHORIZATION ON DATABASE:: DBName TO [NewLogin]  

範例案例

  1. 建立兩個暫存主體:

    CREATE LOGIN login1 WITH PASSWORD = 'J345#$)thb';
    CREATE LOGIN login2 WITH PASSWORD = 'Uor80$23b';
    
  2. 將這些登入新增至系統管理員角色(僅適用於示範)。

  3. 使用 login1登入您的 SQL Server 實例。

  4. 執行下列腳本來建立示範資料庫和名為 testexec 的預存程式:

    CREATE DATABASE Demodb_15517
    GO
    USE Demodb_15517
    GO
    CREATE procedure [dbo].[testexec]
    WITH EXECUTE AS owner
    AS SELECT @@VERSION
    GO
    EXEC dbo.testexec
    GO
    
  5. 執行下列查詢,並檢查值是否 sid 解析為有效的登入:

    • 查詢 1:檢查 sys.databases 中的值 Owner_Name

      SELECT NAME AS Database_Name, owner_sid, SUSER_SNAME(owner_sid) AS OwnerName
      FROM sys.databases
      WHERE NAME = N'Demodb_15517';
      
      Database_Name         owner_sid                               OwnerName
      --------------------- -------------------------------------- ----------------------------
      Demodb_15517          0xDB79ED7B6731CF4E8DC7DF02871E3E36      login1
      
    • 查詢 2:檢查 Owner_Name 示範資料庫中資料表中的值 sys.database_principals

      SELECT SUSER_SNAME(sid) AS Owner_Name, sid 
      FROM Demodb_15517.sys.database_principals 
      WHERE NAME = N'dbo'; 
      
      Owner_Name    SID
      ------------- ------------------------------------------------ 
      login1        0xDB79ED7B6731CF4E8DC7DF02871E3E36
      
  6. 使用類似下列文稿的查詢來備份示範資料庫:

    BACKUP DATABASE [Demodb_15517] TO DISK = N'C:\SQLBackups\Demodb_15517.bak' WITH NOFORMAT, NOINIT, NAME = N'Demodb_15517 Full backup', SKIP, EWIND, NOUNLOAD, STATS = 10 
    GO
    
  7. 卸除示範資料庫與 login1

    DROP DATABASE demodb_15517
    GO
    DROP login login1
    GO
    
  8. 以登入 SQL Server login2

  9. 使用類似下列文稿的 語句,從備份還原示範資料庫:

    USE [master] 
    RESTORE DATABASE [Demodb_15517] FROM   
    DISK = N'C:\SQLBackups\Demodb_15517.bak' WITH FILE = 1,   
    MOVE N'Demodb_15517' TO N'C:\SQLBackups\Demodb_15517.mdf',   
    MOVE N'Demodb_15517_log' TO N'C:\SQLBackups\\Demodb_155172_log.ldf',   
    NOUNLOAD, STATS = 5 
    GO 
    
  10. 重新執行查詢 1 和查詢 2。

  11. 在查詢 1 中,檢查 中的sys.databasesOwner_Name。 值現在會 login2反映 。

    SELECT NAME AS Database_Name, owner_sid, SUSER_SNAME(owner_sid) AS OwnerName 
    FROM sys.databases 
    WHERE NAME = N'Demodb_15517';
    
    Database_Name  owner_sid                               OwnerName
    -------------- --------------------------------------- ---------------------
    Demodb_15517   0xD63086DD7277BC4EB88013D359AF73A6      login2
    
  12. 在查詢 2 中,檢查示範資料庫中數據表中值的值Owner_Namesys.database_principals。 值現在會 NULL反映 。

    SELECT SUSER_SNAME(sid) AS Owner_Name, sid
    FROM Demodb_15517.sys.database_principals
    WHERE NAME = N'dbo';
    
    Owner_Name         sid 
      ------------------ -----------------------------------------------
    NULL               0xDB79ED7B6731CF4E8DC7DF02871E3E36 
    
  13. 執行預 testexec 存程式。 您現在應該會看到「15517」錯誤訊息。

    USE Demodb_15517 
    GO 
    EXEC dbo.testexec 
    GO
    
    Msg 15517, Level 16, State 1, Procedure dbo.testexec, Line 0 [Batch Start Line 19] 
    Cannot execute as the database principal because the principal "dbo" does not exist, this type of principal cannot be impersonated, or you do not have permission. 
    
  14. 若要解決錯誤,請使用下列命令,將 dbo 變更為有效的使用者 (login2

    ALTER AUTHORIZATION ON DATABASE:: Demodb_15517 TO [login2]   
    
  15. 重新執行查詢 2,並確認 dbo 用戶現在解析為 login2 使用者。

    Owner_Name          SID
    ---------------------------------------------------------------- 
    login2              0xD63086DD7277BC4EB88013D359AF73A6 
    
  16. 請再試一次以執行測試預存程式。 請注意,它現在已成功執行。

    USE Demodb_15517 
    GO 
    EXEC dbo.testexec 
    GO
    
    /* -- You get an output that resembles the following 
    ---------------------------------------------------------------------------------------------------------
    Microsoft SQL Server 2019 (RTM-CU16-GDR) (KB5014353) - 15.0.4236.7 (X64)  
    May 29 2022 15:55:47  
    Copyright (C) 2019 Microsoft Corporation 
    Express Edition (64-bit) on Windows 10 Enterprise 10.0 <X64> (Build 22621: ) (Hypervisor) 
    */ 
    

另請參閱

將資料庫複製到其他伺服器

在實例之間傳輸登入和密碼