由于 SID 不匹配,程序集部署失败
Failed assembly deploy due to non-matching SIDs
数据库名称和登录名在下文中是匿名的。有一些答案
在 SO 上与这种情况相似,但不完全相同,因此我的问题。
尝试将程序集部署到生产数据库 FOO_PROD 失败并显示消息:
Msg 33009, Level 16, State 2, Line 17
The database owner SID recorded in the master database differs from the
database owner SID recorded in database 'FOO_PROD'. You should correct
this situation by resetting the owner of database 'FOO_PROD' using the
ALTER AUTHORIZATION statement.
确实,以下两个查询证明了 SID 的差异。
首先我们查看FOO_PROD的SID:
SELECT SD.[SID],
SL.Name as [LoginName]
FROM master..sysdatabases SD INNER JOIN master..syslogins SL
on SD.SID = SL.SID
WHERE SD.Name = 'FOO_PROD'
显示以下结果:
SID, LoginName
0x010500000000000515000000C4B7E63D99D15C20332A47A24B100000, BATZ\boink
其次,我们查看master数据库中FOO_PROD的SID:
SELECT SD.[SID],
SL.Name as [LoginName]
FROM master..sysdatabases SD INNER JOIN master..syslogins SL
on SD.SID = SL.SID
WHERE SD.Name = 'master'
显示以下结果:
SID, LoginName
0x01, [sa]
我们确实注意到,正如 Visual Studio 所抱怨的那样,SID 并没有
比赛。必须使它们匹配才能继续(显然)。
约束:FOO_PROD 上的 SID 无法更改,因为其他几个系统
使用数据库的用户期望它具有当前具有的 SID 和登录名。
问题一:那么解决办法是修改master数据库的SID,LoginName吗?将
这样做会伤害任何东西还是一个坏主意?
假设您回应说可以更改 master 上的 SID、LoginName,那么,
如何更改 'master' 数据库?嗯,我有
以前没有做过,但可以在这里找到候选解决方案和评论:
The database owner SID recorded in the master database differs from the database owner SID
不过这个情况和上面link呈现的情况不一样,我
认为,因为更改必须发生 to/on 主数据库 ala:
exec sp_changedbowner [BATZ\boink]
问题 2:这是正确的做法吗?
当然,我会与利益相关者核实对主数据库的此类更改是否会
导致不良后果,但我希望在我什至之前在这里得到一些指导
检查一下。
根据@srutzky 的更新答案更新:
-- Step 1
SELECT sd.[name], sd.[owner_sid], sp.[name]
FROM sys.databases sd
INNER JOIN sys.server_principals sp
ON sp.[sid] = sd.[owner_sid]
WHERE sd.[name] = N'FOO_PROD';
returns:
name, owner_sid, name
FOO_PROD, 0x010500000000000515000000C4B7E63D99D15C20332A47A24B100000, BATZ\boink
然后
-- Step 2
USE [FOO_PROD];
SELECT dp.[sid], sp.[name]
FROM sys.database_principals dp
INNER JOIN sys.server_principals sp
ON sp.[sid] = dp.[sid]
WHERE dp.[name] = N'dbo';
returns:
sid, name
0x01, sa
由于数据库中的owner是SA,想把Master中记录的owner改成SA,运行
alter authorization on database::[foo_prod] to sa
是的,SID 确实需要匹配,因为不匹配表明可能有害的数据库正在还原到实例;这是一个保障。
但是,首先我们需要确切地知道我们在看什么。虽然 FOO_PROD
中的记录与 master
中的记录之间的所有者 SID 肯定不匹配(因此出现错误消息),但您的查询并未查看 FOO_PROD
中的值。您的两个查询正在查看 master
中 FOO_PROD
所有者的值,以及 master
中(再次)master
所有者的值(此处完全不相关) .
步骤 1
不要将 sys*
对象用于任何东西,因为它们是兼容性视图,以便为 SQL Server 2000 和之前编写的旧内容仍然有效(好吧,dbo.sys*
中的表 msdb
仍然有效)。从 SQL Server 2005 开始,只应使用 sys.*
个对象(无需指定 master.
)。含义,使用:
SELECT sd.[name], sd.[owner_sid], sp.[name]
FROM sys.databases sd
INNER JOIN sys.server_principals sp
ON sp.[sid] = sd.[owner_sid]
WHERE sd.[name] = N'FOO_PROD';
步骤 2
您需要检查 IN 数据库本身的值,因为它记录了所有者的 SID,它不在 sys.databases
(甚至 master..sysdatabases
)。检查数据库所有者的值时,您需要在 sys.database_principals
中查找 dbo
用户,如下所示:
USE [FOO_PROD];
SELECT dp.[sid], sp.[name]
FROM sys.database_principals dp
INNER JOIN sys.server_principals sp
ON sp.[sid] = dp.[sid]
WHERE dp.[name] = N'dbo';
步骤 3
如果您使用 SQL Server 2005,则需要使用 sp_changedbowner
,但从 SQL Server 2008 开始,不推荐使用较新的 ALTER AUTHORIZATION 存储过程(尽管它仍然有效)。但是,是的,这是使它们相同的方法,因为它会将两个位置同步到您指定的任何登录名。
但是,您需要确保 BATZ\boink
是 SQL 服务器实例所属域的有效 Windows 登录名,并且这个特定的 Windows 登录的 SID 为 0x010500000000000515000000C4B7E63D99D15C20332A47A24B100000
。如果登录名不存在,希望您能够通过 CREATE LOGIN
.
创建它
数据库名称和登录名在下文中是匿名的。有一些答案 在 SO 上与这种情况相似,但不完全相同,因此我的问题。
尝试将程序集部署到生产数据库 FOO_PROD 失败并显示消息:
Msg 33009, Level 16, State 2, Line 17
The database owner SID recorded in the master database differs from the
database owner SID recorded in database 'FOO_PROD'. You should correct
this situation by resetting the owner of database 'FOO_PROD' using the
ALTER AUTHORIZATION statement.
确实,以下两个查询证明了 SID 的差异。 首先我们查看FOO_PROD的SID:
SELECT SD.[SID],
SL.Name as [LoginName]
FROM master..sysdatabases SD INNER JOIN master..syslogins SL
on SD.SID = SL.SID
WHERE SD.Name = 'FOO_PROD'
显示以下结果:
SID, LoginName
0x010500000000000515000000C4B7E63D99D15C20332A47A24B100000, BATZ\boink
其次,我们查看master数据库中FOO_PROD的SID:
SELECT SD.[SID],
SL.Name as [LoginName]
FROM master..sysdatabases SD INNER JOIN master..syslogins SL
on SD.SID = SL.SID
WHERE SD.Name = 'master'
显示以下结果:
SID, LoginName
0x01, [sa]
我们确实注意到,正如 Visual Studio 所抱怨的那样,SID 并没有 比赛。必须使它们匹配才能继续(显然)。
约束:FOO_PROD 上的 SID 无法更改,因为其他几个系统 使用数据库的用户期望它具有当前具有的 SID 和登录名。
问题一:那么解决办法是修改master数据库的SID,LoginName吗?将 这样做会伤害任何东西还是一个坏主意?
假设您回应说可以更改 master 上的 SID、LoginName,那么, 如何更改 'master' 数据库?嗯,我有 以前没有做过,但可以在这里找到候选解决方案和评论: The database owner SID recorded in the master database differs from the database owner SID
不过这个情况和上面link呈现的情况不一样,我 认为,因为更改必须发生 to/on 主数据库 ala:
exec sp_changedbowner [BATZ\boink]
问题 2:这是正确的做法吗?
当然,我会与利益相关者核实对主数据库的此类更改是否会 导致不良后果,但我希望在我什至之前在这里得到一些指导 检查一下。
根据@srutzky 的更新答案更新:
-- Step 1
SELECT sd.[name], sd.[owner_sid], sp.[name]
FROM sys.databases sd
INNER JOIN sys.server_principals sp
ON sp.[sid] = sd.[owner_sid]
WHERE sd.[name] = N'FOO_PROD';
returns:
name, owner_sid, name
FOO_PROD, 0x010500000000000515000000C4B7E63D99D15C20332A47A24B100000, BATZ\boink
然后
-- Step 2
USE [FOO_PROD];
SELECT dp.[sid], sp.[name]
FROM sys.database_principals dp
INNER JOIN sys.server_principals sp
ON sp.[sid] = dp.[sid]
WHERE dp.[name] = N'dbo';
returns:
sid, name
0x01, sa
由于数据库中的owner是SA,想把Master中记录的owner改成SA,运行
alter authorization on database::[foo_prod] to sa
是的,SID 确实需要匹配,因为不匹配表明可能有害的数据库正在还原到实例;这是一个保障。
但是,首先我们需要确切地知道我们在看什么。虽然 FOO_PROD
中的记录与 master
中的记录之间的所有者 SID 肯定不匹配(因此出现错误消息),但您的查询并未查看 FOO_PROD
中的值。您的两个查询正在查看 master
中 FOO_PROD
所有者的值,以及 master
中(再次)master
所有者的值(此处完全不相关) .
步骤 1
不要将 sys*
对象用于任何东西,因为它们是兼容性视图,以便为 SQL Server 2000 和之前编写的旧内容仍然有效(好吧,dbo.sys*
中的表 msdb
仍然有效)。从 SQL Server 2005 开始,只应使用 sys.*
个对象(无需指定 master.
)。含义,使用:
SELECT sd.[name], sd.[owner_sid], sp.[name]
FROM sys.databases sd
INNER JOIN sys.server_principals sp
ON sp.[sid] = sd.[owner_sid]
WHERE sd.[name] = N'FOO_PROD';
步骤 2
您需要检查 IN 数据库本身的值,因为它记录了所有者的 SID,它不在 sys.databases
(甚至 master..sysdatabases
)。检查数据库所有者的值时,您需要在 sys.database_principals
中查找 dbo
用户,如下所示:
USE [FOO_PROD];
SELECT dp.[sid], sp.[name]
FROM sys.database_principals dp
INNER JOIN sys.server_principals sp
ON sp.[sid] = dp.[sid]
WHERE dp.[name] = N'dbo';
步骤 3
如果您使用 SQL Server 2005,则需要使用 sp_changedbowner
,但从 SQL Server 2008 开始,不推荐使用较新的 ALTER AUTHORIZATION 存储过程(尽管它仍然有效)。但是,是的,这是使它们相同的方法,因为它会将两个位置同步到您指定的任何登录名。
但是,您需要确保 BATZ\boink
是 SQL 服务器实例所属域的有效 Windows 登录名,并且这个特定的 Windows 登录的 SID 为 0x010500000000000515000000C4B7E63D99D15C20332A47A24B100000
。如果登录名不存在,希望您能够通过 CREATE LOGIN
.