MSSQLSERVER_15517

Si applica a:SQL Server

Dettagli

Attributo valore
Nome prodotto SQL Server
ID evento 15517
Origine evento MSSQLSERVER
Componente SQLEngine
Nome simbolico SEC_CANNOTEXECUTEASUSER
Testo del messaggio Impossibile eseguire come entità di database perché l'entità principale "principal" non esiste, questo tipo di entità non può essere rappresentato o non si dispone dell'autorizzazione.

Spiegazione

Questo errore si verifica in genere perché Microsoft SQL Server non riesce a ottenere le informazioni sul contesto di esecuzione dell'entità specificata in un'istruzione utente o in un modulo usando l'istruzione EXECUTE AS .

Il SID (Login Information Security Identifier) viene salvato automaticamente quando si crea un database in un'istanza di SQL Server come proprietario del database nella riga di database corrispondente nella sys.databases tabella e per l'elemento dbo utente nella sys.database_principals tabella all'interno del database.

Le istruzioni o i moduli che usano la EXECUTE AS OWNER clausola funzioneranno come previsto se la voce SID archiviata per l'utente dbo è valida.

Nota

Il problema può verificarsi per qualsiasi entità usata nell'istruzione EXECUTE AS e che non esiste nel server in cui viene ripristinato il database.

Ecco alcuni scenari comuni che potrebbero causare questo problema:

  • Si ripristina un database nella stessa istanza del server in cui è stato originariamente eseguito il backup, ma l'entità sql Server che ha creato il database non è più valida per qualche motivo. Ad esempio:

    • L'account di accesso per l'autenticazione di SQL Server è stato rimosso.
    • L'account di accesso autenticazione di Windows non è più per un utente valido in Active Directory perché il dipendente ha lasciato l'azienda.
  • È possibile ripristinare un database in un server diverso dall'istanza in cui è stato originariamente eseguito il backup, ma l'entità sql Server che ha creato il database non è un'entità valida nel nuovo server.

    • Se l'utente è un account di accesso di SQL Server, l'entità potrebbe esistere nel server di destinazione o di destinazione, ma il sid valore sarà diverso.
    • Se l'utente è un account di accesso di Windows, l'account di accesso di Windows non esiste nel server di destinazione o non è più valido.

L'utente o l'applicazione che esegue la stored procedure, la funzione o il trigger non dispone delle autorizzazioni necessarie per rappresentare l'entità specificata nell'istruzione EXECUTE AS .

Azione utente

Usare il nome di un'entità esistente o concedere l'autorizzazione IMPERSONATE per tale entità agli utenti necessari.

Per risolvere il problema che si verifica a causa di un errore utente dbo non valido, modificare il dbo_User valore in un account di accesso valido nel server eseguendo il comando seguente:

ALTER AUTHORIZATION ON DATABASE:: DBName TO [NewLogin]  

Scenario di esempio

  1. Creare due entità temporanee:

    CREATE LOGIN login1 WITH PASSWORD = 'J345#$)thb';
    CREATE LOGIN login2 WITH PASSWORD = 'Uor80$23b';
    
  2. Aggiungere questi account di accesso al ruolo sysadmin (solo per la dimostrazione).

  3. Accedere all'istanza di SQL Server usando login1.

  4. Creare un database dimostrativo e una stored procedure denominata testexec eseguendo lo script seguente:

    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. Eseguire le query seguenti e verificare se i sid valori vengono risolti in un account di accesso valido:

    • Query 1: controllare il valore del Owner_Name valore in sys.databases.

      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
      
    • Query 2: Controllare il Owner_Name valore nella sys.database_principals tabella all'interno del database dimostrativo:

      SELECT SUSER_SNAME(sid) AS Owner_Name, sid 
      FROM Demodb_15517.sys.database_principals 
      WHERE NAME = N'dbo'; 
      
      Owner_Name    SID
      ------------- ------------------------------------------------ 
      login1        0xDB79ED7B6731CF4E8DC7DF02871E3E36
      
  6. Eseguire il backup del database dimostrativo usando una query simile allo script seguente:

    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. Eliminare il database dimostrativo e login1:

    DROP DATABASE demodb_15517
    GO
    DROP login login1
    GO
    
  8. Accedere a SQL Server come login2.

  9. Ripristinare il database dimostrativo dal backup usando un'istruzione simile allo script seguente:

    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. Eseguire di nuovo query 1 e Query 2.

  11. In Query 1 controllare il valore del Owner_Name valore in sys.databases. Il valore ora riflette 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. In Query 2 controllare il valore del Owner_Name valore nella sys.database_principals tabella all'interno del database dimostrativo. Il valore ora riflette 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. Eseguire la testexec stored procedure. Verrà visualizzato il messaggio di errore "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. Per risolvere l'errore, modificare dbo in un utente valido (login2) usando il comando seguente:

    ALTER AUTHORIZATION ON DATABASE:: Demodb_15517 TO [login2]   
    
  15. Eseguire di nuovo la query 2 e verificare che gli utenti dbo risolvono ora l'utente login2.

    Owner_Name          SID
    ---------------------------------------------------------------- 
    login2              0xD63086DD7277BC4EB88013D359AF73A6 
    
  16. Riprovare a eseguire la stored procedure di test. Si noti che ora viene eseguito correttamente.

    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) 
    */ 
    

Vedi anche

Copiare database in altri server

Trasferire account di accesso e password tra istanze