MSSQLSERVER_15517

Aplica-se a: SQL Server

Detalhes

Atributo Valor
Nome do produto SQL Server
ID do evento 15517
Origem do Evento MSSQLSERVER
Componente SQLEngine
Nome simbólico SEC_CANNOTEXECUTEASUSER
Texto da mensagem Não é possível executar como a entidade de segurança do banco de dados porque a entidade de segurança "principal" não existe, esse tipo de entidade não pode ser representado ou você não tem permissão.

Explicação

Esse erro normalmente ocorre porque o Microsoft SQL Server não pode obter as informações sobre o contexto de execução da entidade especificada em uma instrução de usuário ou módulo usando a EXECUTE AS instrução.

Suas informações de logon SID (Identificador de Segurança) são salvas automaticamente quando você cria um banco de dados em uma instância do SQL Server como o proprietário do banco de dados na linha de banco de dados correspondente na sys.databases tabela e para o dbo item de usuário na sys.database_principals tabela dentro do banco de dados.

As instruções ou módulos que usam a EXECUTE AS OWNER cláusula funcionarão conforme o esperado se a entrada SID armazenada para o usuário dbo for válida.

Observação

O problema pode ocorrer para qualquer entidade de segurança usada na EXECUTE AS instrução e que não exista no servidor para o qual o banco de dados é restaurado.

Aqui estão alguns cenários comuns que podem causar esse problema:

  • Você restaura um banco de dados na mesma instância de servidor em que o backup foi feito originalmente, mas a entidade de segurança do SQL Server que criou o banco de dados não é mais válida por algum motivo. Por exemplo:

    • O logon de autenticação do SQL Server foi removido.
    • O logon de autenticação do Windows não é mais para um usuário válido no Active Directory porque o funcionário saiu da empresa.
  • Você restaura um banco de dados em um servidor diferente da instância em que o backup foi feito originalmente, mas a entidade de segurança do SQL Server que criou o banco de dados não é uma entidade de segurança válida no novo servidor.

    • Se o usuário for um logon do SQL Server, a entidade de segurança poderá existir no servidor de destino ou de destino, mas o sid valor será diferente.
    • Se o usuário for um logon do Windows, o logon do Windows não existirá no servidor de destino ou não será mais válido.

O usuário ou aplicativo que está executando o procedimento armazenado, a função ou o gatilho não tem as permissões necessárias para representar a entidade especificada na EXECUTE AS instrução.

Ação do usuário

Use o nome de uma entidade existente ou conceda a permissão IMPERSONATE nessa entidade aos usuários necessários.

Para resolver o problema que ocorre devido a um erro de usuário dbo inválido, altere o dbo_User valor para um logon válido em seu servidor executando o seguinte comando:

ALTER AUTHORIZATION ON DATABASE:: DBName TO [NewLogin]  

Cenário de exemplo

  1. Crie duas entidades de segurança temporárias:

    CREATE LOGIN login1 WITH PASSWORD = 'J345#$)thb';
    CREATE LOGIN login2 WITH PASSWORD = 'Uor80$23b';
    
  2. Adicione esses logons à função sysadmin (somente para demonstração).

  3. Faça logon na instância do SQL Server usando login1o .

  4. Crie um banco de dados de demonstração e um procedimento armazenado nomeado testexec executando o seguinte script:

    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. Execute as seguintes consultas e verifique se os sid valores estão sendo resolvidos para um logon válido:

    • Consulta 1: Verifique o valor do Owner_Name valor em 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
      
    • Consulta 2: Verifique o Owner_Name sys.database_principals valor na tabela dentro do banco de dados de demonstração:

      SELECT SUSER_SNAME(sid) AS Owner_Name, sid 
      FROM Demodb_15517.sys.database_principals 
      WHERE NAME = N'dbo'; 
      
      Owner_Name    SID
      ------------- ------------------------------------------------ 
      login1        0xDB79ED7B6731CF4E8DC7DF02871E3E36
      
  6. Faça backup do banco de dados de demonstração usando uma consulta semelhante ao seguinte script:

    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. Descarte o banco de dados de demonstração e login1:

    DROP DATABASE demodb_15517
    GO
    DROP login login1
    GO
    
  8. Faça logon no SQL Server como login2.

  9. Restaure o banco de dados de demonstração do backup usando uma instrução semelhante ao seguinte script:

    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. Execute novamente a Consulta 1 e a Consulta 2.

  11. Na Consulta 1, verifique o Owner_Name valor do valor em sys.databases. O valor agora reflete 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. Na Consulta 2, verifique o valor do valor na sys.database_principals tabela no banco de Owner_Name dados de demonstração. O valor agora reflete 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. Execute o testexec procedimento armazenado. Agora você deve ver a mensagem de erro "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. Para resolver o erro, altere o dbo para um usuário válido (login2) usando o seguinte comando:

    ALTER AUTHORIZATION ON DATABASE:: Demodb_15517 TO [login2]   
    
  15. Execute novamente a Consulta 2 e verifique se os usuários dbo agora resolvem para o usuário login2.

    Owner_Name          SID
    ---------------------------------------------------------------- 
    login2              0xD63086DD7277BC4EB88013D359AF73A6 
    
  16. Tente executar novamente o procedimento armazenado de teste. Observe que agora ele é executado com êxito.

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

Confira também

Copiar bancos de dados para outros servidores

Transferir logins e senhas entre instâncias