Поделиться через


MSSQLSERVER_15517

Область применения: SQL Server

Сведения

Атрибут Значение
Название продукта SQL Server
ИД события 15517
Источник событий MSSQLSERVER
Компонент SQLEngine
Символическое имя SEC_CANNOTEXECUTEASUSER
Текст сообщения Невозможно выполнить как субъект базы данных, так как субъект-субъект не существует, этот тип субъекта не может быть олицетворен или у вас нет разрешения.

Описание

Эта ошибка обычно возникает, так как Microsoft SQL Server не может получить сведения о контексте выполнения субъекта, указанного в инструкции пользователя или модуле с помощью инструкции EXECUTE AS .

Идентификатор безопасности для входа автоматически сохраняется при создании базы данных в экземпляре SQL Server в качестве владельца базы данных в sys.databases соответствующей строке базы данных в таблице и dbo для элемента пользователя в sys.database_principals таблице в базе данных.

Инструкции или модули, использующие EXECUTE AS OWNER предложение, будут работать должным образом, если запись SID, хранимая для пользователя dbo, действительна.

Примечание.

Проблема может возникнуть для любого субъекта, используемого 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. Добавьте эти имена входа в роль sysadmin (только для демонстрации).

  3. Войдите в экземпляр SQL Server с помощью login1.

  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. Проверьте значение Owner_Name значения в sys.database.

      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 проверьте значение Owner_Name значения в sys.databases. Теперь значение отражается 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_Name значения в таблице в sys.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) 
    */ 
    

См. также

Копирование баз данных на другие серверы

Передача имен входа и паролей между экземплярами