MSSQLSERVER_15517
Gilt für: SQL Server
Details
attribute | Wert |
---|---|
Produktname | SQL Server |
Ereignis-ID | 15517 |
Ereignisquelle | MSSQLSERVER |
Komponente | SQLEngine |
Symbolischer Name | SEC_CANNOTEXECUTEASUSER |
Meldungstext | Kann nicht als Datenbankprinzipal ausgeführt werden, da der Prinzipal "Prinzipal" nicht vorhanden ist, dieser Prinzipaltyp kann nicht als Identitätswechsel verwendet werden, oder Sie besitzen keine Berechtigung. |
Erklärung
Dieser Fehler tritt in der Regel auf, da Microsoft SQL Server mithilfe der Anweisung keine Informationen zum Ausführungskontext des Prinzipals abrufen kann, der in einer Benutzeranweisungen oder einem Modul EXECUTE AS
angegeben ist.
Ihre SID (Login Information Security Identifier) wird automatisch gespeichert, wenn Sie eine Datenbank in einer SQL Server-Instanz als Datenbankbesitzer in der entsprechenden Datenbankzeile in der sys.databases
Tabelle und für das dbo
Benutzerelement in der Tabelle innerhalb der sys.database_principals
Datenbank erstellen.
Die Anweisungen oder Module, die die EXECUTE AS OWNER
Klausel verwenden, funktionieren wie erwartet, wenn der FÜR den dbo-Benutzer gespeicherte SID-Eintrag gültig ist.
Hinweis
Das Problem kann für jeden Prinzipal auftreten, der in der EXECUTE AS
Anweisung verwendet wird und nicht auf dem Server vorhanden ist, auf dem die Datenbank wiederhergestellt wird.
Nachfolgend sind einige häufige Szenarien aufgeführt, die dazu führen können, dass dieses Problem auftritt:
Sie stellen eine Datenbank auf derselben Serverinstanz wieder her, in der die Sicherung ursprünglich ausgeführt wurde, aber der SQL Server-Prinzipal, der die Datenbank erstellt hat, ist aus irgendeinem Grund nicht mehr gültig. Zum Beispiel:
- Die SQL Server-Authentifizierungsanmeldung wurde entfernt.
- Die Windows-Authentifizierung Anmeldung gilt nicht mehr für einen gültigen Benutzer in Active Directory, da der Mitarbeiter das Unternehmen verlassen hat.
Sie stellen eine Datenbank auf einem Server wieder her, der sich von der Ursprünglichen Instanz unterscheidet, in der die Sicherung ursprünglich ausgeführt wurde, aber der SQL Server-Prinzipal, der die Datenbank erstellt hat, ist kein gültiger Prinzipal auf dem neuen Server.
- Wenn es sich bei dem Benutzer um eine SQL Server-Anmeldung handelt, ist der Prinzipal möglicherweise auf dem Ziel- oder Zielserver vorhanden, der
sid
Wert ist jedoch unterschiedlich. - Wenn der Benutzer eine Windows-Anmeldung ist, ist die Windows-Anmeldung nicht auf dem Zielserver vorhanden oder ist nicht mehr gültig.
- Wenn es sich bei dem Benutzer um eine SQL Server-Anmeldung handelt, ist der Prinzipal möglicherweise auf dem Ziel- oder Zielserver vorhanden, der
Der Benutzer oder die Anwendung, der die gespeicherte Prozedur, Funktion oder den Trigger ausführt, verfügt nicht über die erforderlichen Berechtigungen zum Identitätswechsel des Prinzipals, der in der EXECUTE AS
Anweisung angegeben ist.
Aktion des Benutzers
Verwenden Sie den Namen eines vorhandenen Prinzipals, oder erteilen Sie den erforderlichen Benutzern die Berechtigung "IDENTITÄTSWECHSEL".
Um das Problem zu beheben, das aufgrund eines ungültigen Dbo-Benutzerfehlers auftritt, ändern Sie den dbo_User
Wert in eine gültige Anmeldung auf Ihrem Server, indem Sie den folgenden Befehl ausführen:
ALTER AUTHORIZATION ON DATABASE:: DBName TO [NewLogin]
Beispielszenario
Erstellen Sie zwei temporäre Prinzipale:
CREATE LOGIN login1 WITH PASSWORD = 'J345#$)thb'; CREATE LOGIN login2 WITH PASSWORD = 'Uor80$23b';
Fügen Sie diese Anmeldungen zur Sysadmin-Rolle hinzu (nur zur Demonstration).
Melden Sie sich mit der Verwendung
login1
von SQL Server bei Ihrer SQL Server-Instanz an.Erstellen Sie eine Demodatenbank und eine gespeicherte Prozedur, die durch Ausführen des folgenden Skripts benannt
testexec
wird: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
Führen Sie die folgenden Abfragen aus, und überprüfen Sie, ob die
sid
Werte in einen gültigen Anmeldenamen aufgelöst werden:Abfrage 1: Überprüfen Sie den Wert des
Owner_Name
Werts 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
Abfrage 2: Überprüfen Sie den
Owner_Name
Wert in dersys.database_principals
Tabelle in der Demodatenbank:SELECT SUSER_SNAME(sid) AS Owner_Name, sid FROM Demodb_15517.sys.database_principals WHERE NAME = N'dbo';
Owner_Name SID ------------- ------------------------------------------------ login1 0xDB79ED7B6731CF4E8DC7DF02871E3E36
Sichern Sie die Demodatenbank mithilfe einer Abfrage, die dem folgenden Skript ähnelt:
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
Legen Sie die Demodatenbank ab und
login1
:DROP DATABASE demodb_15517 GO DROP login login1 GO
Melden Sie sich bei SQL Server als
login2
.Stellen Sie die Demodatenbank aus der Sicherung mithilfe einer Anweisung wieder her, die dem folgenden Skript ähnelt:
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
Führen Sie Abfrage 1 und Abfrage 2 erneut aus.
Überprüfen Sie in Abfrage 1 den Wert des
Owner_Name
Werts insys.databases
. Der Wert spiegelt nun widerlogin2
.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
Überprüfen Sie in Abfrage 2 den Wert des
Owner_Name
Werts in dersys.database_principals
Tabelle in der Demodatenbank. Der Wert spiegelt nun widerNULL
.SELECT SUSER_SNAME(sid) AS Owner_Name, sid FROM Demodb_15517.sys.database_principals WHERE NAME = N'dbo';
Owner_Name sid ------------------ ----------------------------------------------- NULL 0xDB79ED7B6731CF4E8DC7DF02871E3E36
Führen Sie die gespeicherte
testexec
Prozedur aus. Nun sollte die Fehlermeldung "15517" angezeigt werden.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.
Um den Fehler zu beheben, ändern Sie den Dbo mithilfe des folgenden Befehls in einen gültigen Benutzer (
login2
):ALTER AUTHORIZATION ON DATABASE:: Demodb_15517 TO [login2]
Führen Sie Abfrage 2 erneut aus, und vergewissern Sie sich, dass dbo-Benutzer jetzt zum Anmelde-2-Benutzer aufgelöst werden.
Owner_Name SID ---------------------------------------------------------------- login2 0xD63086DD7277BC4EB88013D359AF73A6
Versuchen Sie es erneut, um die gespeicherte Testprozedur auszuführen. Beachten Sie, dass sie jetzt erfolgreich ausgeführt wird.
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) */
Weitere Informationen
Kopieren von Datenbanken auf andere Server
Übertragen von Anmeldungen und Kennwörtern zwischen Instanzen