マスターデータベースに記録されているデータベース所有者SIDがデータベース所有者SIDと異なります


86

tSQLtを既存のデータベースにインストールしようとすると、次のエラーが発生します。

マスターデータベースに記録されているデータベース所有者SIDは、データベース ''に記録されているデータベース所有者SIDとは異なります。ALTER AUTHORIZATIONステートメントを使用してデータベース ''の所有者をリセットすることにより、この状況を修正する必要があります。

回答:


141

この問題は、データベースがバックアップから復元され、データベース所有者のSIDがマスターデータベースにリストされている所有者のSIDと一致しない場合に発生する可能性があります。エラーメッセージで推奨されている「ALTERAUTHORIZATION」ステートメントを使用するソリューションは次のとおりです。

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()を使用する価値はないと思いますか?また、おそらく、varDBNameとvarLoginNameを選択し、REPLACE()を使用する代わりに、それらをvar Commandにまとめますか?
JDPeckham 2012年

3
DB名にスペースまたは「-」のような特殊文字が含まれている場合、このスクリプトはエラーを出します。したがって、[]角かっこを次のように配置します。'ALTERAUTHORIZATION ON DATABASE :: [<< DatabaseName >>] TO [<< LoginName >>] '
buhtla 2013年

9
これを実行すると、「提案された新しいデータベース所有者はすでにデータベース内のユーザーまたはエイリアスです」というエラーが表示されます
MobileMon 2013年

このスクリプトの場合、おそらくSIDの不一致問題であるため、sysloginsへの内部結合は機能しません。
crokusek 2015

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 

2番目のステートメントは、次のセキュリティの脆弱性を示しています。VA1102
MSDB

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

私もこの問題に遭遇し、ターゲットデータベースの所有者がマスターデータベースに存在しないことがわかりました。そのユーザーをマスターデータベースにマッピングすると、問題が解決しました。


マスターへのマッピングは所有者を変更しません。マッピング後に以下を実行する必要があります。EXECsp_changedbowner'TheOwnerName '
ShadiNamrouti19年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.