我收到以下错误
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.
我读过ALTER AUTHORIZATION,但我不知道这是在哪个数据库中发生的。这个错误非常频繁地吐出,并且每天将错误日志增加大约 1GB。
我收到以下错误
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.
我读过ALTER AUTHORIZATION,但我不知道这是在哪个数据库中发生的。这个错误非常频繁地吐出,并且每天将错误日志增加大约 1GB。
我通过设置数据库所有者解决了这个问题。在此问题之前,我的数据库没有任何所有者。在您的数据库中执行此命令以将所有者设置为 sysadmin 帐户:
use [YourDatabaseName] EXEC sp_changedbowner 'sa'
USE [<dbname>]
GO
sp_changedbowner '<user>' -- you can use 'sa' as a quick fix in databases with SQL authentication
KB913423 - 在 SQL Server 2005 中还原数据库后,您无法运行包含 EXECUTE AS 子句的语句或模块
当数据库是从不同的 SQL 服务器或实例恢复时,也可能发生这种情况。在这种情况下,数据库中的安全主体“dbo”与还原数据库的 SQL 服务器上的安全主体不同。别问我怎么知道的……
另一种方法
ALTER AUTHORIZATION
ON DATABASE::[DatabaseName]
TO [A Suitable Login];
选择的答案和其他一些都很好。我只是想给出一个更纯粹的 SQL 解释。没有(有效)数据库所有者的解决方案相同。
错误提及的数据库所有者帐户dbo始终是使用数据库创建的。所以它不存在似乎很奇怪,但是您可以使用两个选择(或一个,但让我们保持简单)进行检查。
SELECT [name],[sid]
FROM [DB_NAME].[sys].[database_principals]
WHERE [name] = 'dbo'
显示dboDB_NAME 数据库中用户的 SID 和
SELECT [name],[sid]
FROM [sys].[syslogins]
显示此 SQL Server 实例的所有登录名(及其 SID)。请注意,它没有写入任何 db_name 前缀,这是因为每个数据库在该视图中都有相同的信息。
因此,如果出现上述错误,将不会使用分配给数据库 dbo 用户的 SID 登录。
如上所述,这通常发生在从另一台计算机恢复数据库时(其中数据库和 dbo 用户是由不同的登录名创建的)。您可以通过将所有权更改为现有登录来修复它。
在安全性下,将主体添加为“无需登录的 SQL 用户”,使其拥有与主体同名的架构,然后在成员身份中使其成为 db_owner。
当意外地将数据库连接字符串提供给只读镜像时也会出现此错误 - 而不是 HA 设置中的主数据库。
正如消息所说,您应该将权限设置为您的用户的所有者。因此,您可以使用以下内容:
ALTER AUTHORIZATION
ON DATABASE::[YourDBName]
TO [UserLogin];
希望有帮助!如果您觉得可以,请发表评论。
就我而言,我在尝试冒充另一个用户时遇到了这个错误。例如
EXEC AS USER = 'dbo';
而且由于数据库是从另一个环境导入的,它的一些用户与 SQL Server 登录名不匹配。
您可以通过运行(已弃用) sp_change_users_login (在“报告”模式下)检查是否有相同的问题,或使用以下查询:
select p.name,p.sid "sid in DB", (select serp.sid from sys.server_principals serp where serp.name = p.name) "sid in server"
from sys.database_principals p
where p.type in ('G','S','U')
and p.authentication_type = 1
and p.sid not in (select sid from sys.server_principals)
如果在该列表中显示您尝试模拟的用户,那么您可能可以通过将 DB 用户分配给服务器中的正确登录名来修复它。例如:
ALTER USER dbo WITH LOGIN = dbo;
转到属性 - 文件。所有者名称必须为空。只需在用户名中输入“sa”即可解决问题。