问题描述
这个问题的重点是为什么会发生这种情况。
我们从另一台发生故障的服务器恢复了一个数据库。恢复成功,但是当我们尝试运行任何存储过程(使用“sa”登录,或具有完全管理员访问权限的基于 Windows 的登录)时,我们收到此错误:
无法作为数据库主体执行,因为主体“dbo” 不存在,这种类型的委托人不能被冒充,或者您 没有权限。
很多 SO 用户都遇到过同样的问题,所以我遵循了相关的答案。例如,以下两个片段:
EXEC sp_changedbowner 'dbo';
ALTER AUTHORIZATION ON DATABASE::MyDb TO dbo;
...结果如下:
找不到主体“dbo”,因为它不存在或您没有权限。
在之前的服务器(以及我的恢复开发服务器)上,没有 dbo
user 可以重新关联为所有者。我不确定如何找到 principal,但它列在架构中。
解决方法
数据库所有者是服务器级主体(即登录)或 Windows 用户(不一定具有登录)。如评论中所述,dbo
是数据库主体而不是服务器主体(假设您没有碰巧拥有名为 dbo
的登录名)。
所有者存储在 master 数据库中,并显示为 owner_sid
目录视图的 sys.databases
列:
SELECT name AS DatabaseName,owner_sid,SUSER_SNAME(owner_sid) AS OwnerName
FROM sys.databases
WHERE name = N'MyDb';
数据库所有者也以众所周知的 dbo
用户身份存储在数据库本身中:
SELECT SUSER_SNAME(sid) AS OwnerName,sid
FROM sys.database_principals AS dp
WHERE name = N'dbo';
当数据库被恢复并且它不存在时,所有者(授权)最初被设置为恢复数据库的人。但是,数据库本身中的 dbo
条目保持不变。这会导致 sys.databases
中的所有者与 sys.database_principals
dbo
用户之间不匹配。有必要在恢复后与所需的所有者一起执行 ALTER AUTHORIZATION ON DATABASE
以纠正不匹配。
下面的脚本演示了执行恢复的个人未以 sa
身份登录时的问题。
CREATE DATABASE MyDb; --database is owned by current login
ALTER AUTHORIZATION ON DATABASE::MyDb TO sa; --sa is an example; can be any login
--shows owners are same (sa)
SELECT name AS DatabaseName,SUSER_SNAME(owner_sid) AS OwnerName
FROM sys.databases
WHERE name = N'MyDb';
SELECT SUSER_SNAME(sid) AS OwnerName,sid
FROM MyDb.sys.database_principals AS dp
WHERE name = N'dbo';
BACKUP DATABASE MyDb TO DISK=N'C:\Backups\MyDb.bak' WITH INIT;
DROP DATABASE MyDb;
RESTORE DATABASE MyDb FROM DISK=N'C:\Backups\MyDb.bak';
--shows owners are different (current user and sa)
SELECT name AS DatabaseName,sid
FROM MyDb.sys.database_principals AS dp
WHERE name = N'dbo';
ALTER AUTHORIZATION ON DATABASE::MyDb TO sa; --sa is an example; can be any login
--shows owners are same (sa)
SELECT name AS DatabaseName,sid
FROM MyDb.sys.database_principals AS dp
WHERE name = N'dbo';
以下是 the documentation 关于数据库所有者主体的摘录。
新的所有者委托人必须是以下之一:
A SQL Server authentication login.
A Windows authentication login representing a Windows user (not a group).
A Windows user that authenticates through a Windows authentication login representing a Windows group.