主数据库中记录的数据库所有者SID与数据库所有者SID不同


86

当我尝试将tSQLt安装到现有数据库上时,出现以下错误:

主数据库中记录的数据库所有者SID与数据库''中记录的数据库所有者SID不同。您应该通过使用ALTER AUTHORIZATION语句重置数据库”的所有者来纠正这种情况。

Answers:


141

当从备份还原的数据库和数据库所有者的SID与主数据库中列出的所有者SID不匹配时,可能会出现此问题。这是使用错误消息中建议的“ ALTER AUTHORIZATION”语句的解决方案:

DECLARE @Command VARCHAR(MAX) = 'ALTER AUTHORIZATION ON DATABASE::[<<DatabaseName>>] TO 
[<<LoginName>>]' 

SELECT @Command = REPLACE(REPLACE(@Command 
            , '<<DatabaseName>>', SD.Name)
            , '<<LoginName>>', SL.Name)
FROM master..sysdatabases SD 
JOIN master..syslogins SL ON  SD.SID = SL.SID
WHERE  SD.Name = DB_NAME()

PRINT @Command
EXEC(@Command)

谢谢!这似乎更合适。您是否认为不应该使用quotename()而不是将'['放在字符串中?还可能选择var DBName和var LoginName,然后将它们放到var Command中,而不是使用REPLACE()吗?
JDPeckham 2012年

3
如果您的数据库名称中包含空格或特殊字符(例如“-”),则此脚本将给您错误。因此,只需将[]括号放在这样的位置:“在数据库上进行ALTER AUTHORIZATION :: [<< DatabaseName >>] TO [<< LoginName >>]”
buhtla 2013年

9
运行此命令时,出现错误“建议的新数据库所有者已经是数据库中的用户或别名”
MobileMon

对于此脚本,可能由于SID不匹配导致对syslogins的内部联接不起作用。
crokusek

31

将其添加到tSQLt.class.sql脚本的顶部

declare @user varchar(50)
SELECT  @user = quotename(SL.Name)
  FROM  master..sysdatabases SD inner join master..syslogins SL
    on  SD.SID = SL.SID
 Where  SD.Name = DB_NAME()
exec('exec sp_changedbowner ' + @user)

这就像一个魅力一样tSQLt Version: 1.0.5873.27393,似乎是一个更简单的解决方案。使用的MS SQL Server 2019 Developer和SSMS 18

19

将以下脚本应用于数据库,您会收到错误消息:

EXEC sp_changedbowner 'sa'

ALTER DATABASE [database_name] SET TRUSTWORTHY ON 

第二条语句说明了以下安全漏洞:VA1102-应在除MSDB之外的所有数据库上禁用“可信任”位
Shadi Namrouti

5

死灵法:
如果您不想使用SQL-Server 2000视图(不建议使用),请使用以下命令:

-- Restore sid when db restored from backup... 
DECLARE @Command NVARCHAR(MAX) 
SET @Command = N'ALTER AUTHORIZATION ON DATABASE::<<DatabaseName>> TO <<LoginName>>' 
SELECT @Command = REPLACE 
                  ( 
                      REPLACE(@Command, N'<<DatabaseName>>', QUOTENAME(SD.Name)) 
                      , N'<<LoginName>>' 
                      ,
                      QUOTENAME
                      (
                          COALESCE
                          (
                               SL.name 
                              ,(SELECT TOP 1 name FROM sys.server_principals WHERE type_desc = 'SQL_LOGIN' AND is_disabled = 'false' ORDER BY principal_id ASC )
                          )
                      )
                  ) 
FROM sys.databases AS SD
LEFT JOIN sys.server_principals  AS SL 
    ON SL.SID = SD.owner_sid 


WHERE SD.Name = DB_NAME() 

PRINT @command 
EXECUTE(@command) 
GO

还可以防止在名称奇怪的数据库或用户上出现错误,并且还可以在没有用户关联的情况下修复错误(使用sa登录)。



0

我也遇到了这个问题,发现主数据库中不存在目标数据库的所有者。将该用户映射到master数据库为我解决了该问题。


映射到母版不会更改所有者。您应该运行映射后的情况如下:EXEC sp_changedbowner的“TheOwnerName”
沙迪Namrouti
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.