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.
- Se l'utente è un account di accesso di SQL Server, l'entità potrebbe esistere nel server di destinazione o di destinazione, ma il
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
Creare due entità temporanee:
CREATE LOGIN login1 WITH PASSWORD = 'J345#$)thb'; CREATE LOGIN login2 WITH PASSWORD = 'Uor80$23b';
Aggiungere questi account di accesso al ruolo sysadmin (solo per la dimostrazione).
Accedere all'istanza di SQL Server usando
login1
.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
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 nellasys.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
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
Eliminare il database dimostrativo e
login1
:DROP DATABASE demodb_15517 GO DROP login login1 GO
Accedere a SQL Server come
login2
.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
Eseguire di nuovo query 1 e Query 2.
In Query 1 controllare il valore del
Owner_Name
valore insys.databases
. Il valore ora riflettelogin2
.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
In Query 2 controllare il valore del
Owner_Name
valore nellasys.database_principals
tabella all'interno del database dimostrativo. Il valore ora rifletteNULL
.SELECT SUSER_SNAME(sid) AS Owner_Name, sid FROM Demodb_15517.sys.database_principals WHERE NAME = N'dbo';
Owner_Name sid ------------------ ----------------------------------------------- NULL 0xDB79ED7B6731CF4E8DC7DF02871E3E36
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.
Per risolvere l'errore, modificare dbo in un utente valido (
login2
) usando il comando seguente:ALTER AUTHORIZATION ON DATABASE:: Demodb_15517 TO [login2]
Eseguire di nuovo la query 2 e verificare che gli utenti dbo risolvono ora l'utente login2.
Owner_Name SID ---------------------------------------------------------------- login2 0xD63086DD7277BC4EB88013D359AF73A6
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) */