MSSQLSERVER_15517
S'applique à : SQL Server
Détails
Attribut | Valeur |
---|---|
Nom du produit | SQL Server |
ID de l’événement | 15517 |
Source de l’événement | MSSQLSERVER |
Composant | SQLEngine |
Nom symbolique | SEC_CANNOTEXECUTEASUSER |
Texte du message | Impossible d’exécuter en tant que principal de base de données, car le principal « principal » n’existe pas, ce type de principal ne peut pas être emprunt d’identité ou vous n’avez pas d’autorisation. |
Explication
Cette erreur se produit généralement parce que Microsoft SQL Server ne peut pas obtenir les informations sur le contexte d’exécution du principal spécifié dans une instruction utilisateur ou un module à l’aide de l’instruction EXECUTE AS
.
Votre IDENTIFICATEUR de sécurité des informations de connexion est automatiquement enregistré lorsque vous créez une base de données sur une instance SQL Server en tant que propriétaire de la base de données dans la ligne de base de données correspondante de la sys.databases
table et pour l’élément dbo
utilisateur de la table dans la sys.database_principals
base de données.
Les instructions ou modules qui utilisent la EXECUTE AS OWNER
clause fonctionnent comme prévu si l’entrée SID stockée pour l’utilisateur dbo est valide.
Remarque
Le problème peut se produire pour tout principal utilisé dans l’instruction EXECUTE AS
et qui n’existe pas sur le serveur sur lequel la base de données est restaurée.
Voici quelques scénarios courants susceptibles de provoquer ce problème :
Vous restaurez une base de données sur la même instance de serveur où la sauvegarde a été effectuée à l’origine, mais le principal SQL Server qui a créé la base de données n’est plus valide pour une raison quelconque. Par exemple :
- La connexion d’authentification SQL Server a été supprimée.
- La connexion Authentification Windows n’est plus destinée à un utilisateur valide dans Active Directory, car l’employé a quitté l’entreprise.
Vous restaurez une base de données sur un serveur différent de l’instance où la sauvegarde a été effectuée à l’origine, mais le principal SQL Server qui a créé la base de données n’est pas un principal valide sur le nouveau serveur.
- Si l’utilisateur est une connexion SQL Server, le principal peut exister sur le serveur cible ou de destination, mais la
sid
valeur sera différente. - Si l’utilisateur est une connexion Windows, la connexion Windows n’existe pas sur le serveur cible ou n’est plus valide.
- Si l’utilisateur est une connexion SQL Server, le principal peut exister sur le serveur cible ou de destination, mais la
L’utilisateur ou l’application qui exécute la procédure stockée, la fonction ou le déclencheur ne dispose pas des autorisations nécessaires pour emprunter l’identité du principal spécifié dans l’instruction EXECUTE AS
.
Action utilisateur
Utilisez le nom d’un principal existant ou accordez l’autorisation IMPERSONATE sur ce principal aux utilisateurs requis.
Pour résoudre le problème qui se produit en raison d’une erreur dbo utilisateur non valide, remplacez la dbo_User
valeur par une connexion valide sur votre serveur en exécutant la commande suivante :
ALTER AUTHORIZATION ON DATABASE:: DBName TO [NewLogin]
Exemple de scénario
Créez deux principaux temporaires :
CREATE LOGIN login1 WITH PASSWORD = 'J345#$)thb'; CREATE LOGIN login2 WITH PASSWORD = 'Uor80$23b';
Ajoutez ces connexions au rôle sysadmin (pour démonstration uniquement).
Connectez-vous à votre instance SQL Server à l’aide
login1
de .Créez une base de données de démonstration et une procédure stockée nommée
testexec
en exécutant le script suivant :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
Exécutez les requêtes suivantes et vérifiez si les
sid
valeurs sont résolues sur une connexion valide :Requête 1 : Vérifiez la valeur de la
Owner_Name
valeur dans 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
Requête 2 : Vérifiez la
Owner_Name
valeur dans la table dans lasys.database_principals
base de données de démonstration :SELECT SUSER_SNAME(sid) AS Owner_Name, sid FROM Demodb_15517.sys.database_principals WHERE NAME = N'dbo';
Owner_Name SID ------------- ------------------------------------------------ login1 0xDB79ED7B6731CF4E8DC7DF02871E3E36
Sauvegardez la base de données de démonstration à l’aide d’une requête semblable au script suivant :
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
Supprimez la base de données de démonstration et
login1
:DROP DATABASE demodb_15517 GO DROP login login1 GO
Connectez-vous à SQL Server en tant que
login2
.Restaurez la base de données de démonstration à partir de la sauvegarde à l’aide d’une instruction semblable au script suivant :
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
Réexécutez la requête 1 et la requête 2.
Dans la requête 1, vérifiez la valeur de la
Owner_Name
valeur danssys.databases
. La valeur reflètelogin2
maintenant .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
Dans la requête 2, vérifiez la valeur de la
Owner_Name
valeur dans la table dans lasys.database_principals
base de données de démonstration. La valeur reflèteNULL
maintenant .SELECT SUSER_SNAME(sid) AS Owner_Name, sid FROM Demodb_15517.sys.database_principals WHERE NAME = N'dbo';
Owner_Name sid ------------------ ----------------------------------------------- NULL 0xDB79ED7B6731CF4E8DC7DF02871E3E36
Exécutez la
testexec
procédure stockée. Vous devez maintenant voir le message d’erreur « 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.
Pour résoudre l’erreur, remplacez le dbo par un utilisateur valide (
login2
) à l’aide de la commande suivante :ALTER AUTHORIZATION ON DATABASE:: Demodb_15517 TO [login2]
Réexécutez la requête 2 et vérifiez que les utilisateurs dbo se résolvent désormais à l’utilisateur login2.
Owner_Name SID ---------------------------------------------------------------- login2 0xD63086DD7277BC4EB88013D359AF73A6
Réessayez pour exécuter la procédure stockée de test. Notez qu’elle s’exécute maintenant correctement.
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) */
Voir aussi
Copier des bases de données sur d’autres serveurs
Transférer des connexions et des mots de passe entre des instances