Ana veritabanına kaydedilen veritabanı sahibi SID'si veritabanı sahibinin SID'sinden farklıdır


87

TSQLt'i mevcut bir veritabanına yüklemeye çalıştığımda şu hatayı alıyorum:

Ana veritabanına kaydedilen veritabanı sahibi SID'si, veritabanında kaydedilen veritabanı sahibi SID'sinden farklıdır ''. ALTER AUTHORIZATION deyimini kullanarak veritabanının sahibini sıfırlayarak bu durumu düzeltmelisiniz.

Yanıtlar:


143

Bu sorun, bir yedeklemeden geri yüklenen bir veritabanı ve veritabanı sahibinin SID'si, ana veritabanında listelenen sahip SID ile eşleşmediğinde ortaya çıkabilir. Hata mesajında ​​önerilen "ALTER AUTHORIZATION" ifadesini kullanan bir çözüm:

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)

Teşekkürler! Bu daha uygun görünüyor. Dizeye '[' koymak yerine quename () kullanmanın faydalı olmadığını düşünüyor musunuz? Ayrıca, var DBName ve var LoginName'i seçip bunları REPLACE () kullanmak yerine var Command'a koymak mı?
JDPeckham

3
DB adınızda boşluklar veya '-' gibi özel karakterler varsa, bu komut dosyası size hata verecektir. Bu yüzden [] parantezleri şu şekilde koyun: 'VERİTABANINDA
DEĞİŞTİRME

10
Bunu çalıştırdığımda "Önerilen yeni veritabanı sahibi, veritabanında zaten bir kullanıcı veya takma addır" hatasını alıyorum
MobileMon

SID uyumsuzluğu nedeniyle muhtemelen bu komut dosyası için, iç benim için çalışmıyor syslogins katılmak olduğunu sorun.
crokusek

31

Bunu tSQLt.class.sql betiğinin üstüne eklendi

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)

Bu bir cazibe gibi çalıştı tSQLt Version: 1.0.5873.27393ve daha basit bir çözüm gibi görünüyor. MS SQL Server 2019 Developer ve SSMS 18'i kullanma
gümüş

19

Aşağıdaki komut dosyasını veritabanına uygulayarak hatayı alırsınız:

EXEC sp_changedbowner 'sa'

ALTER DATABASE [database_name] SET TRUSTWORTHY ON 

1
İkinci ifade aşağıdaki güvenlik açığını ortaya çıkarır: VA1102 - Güvenilir bit,
MSDB

5

Necromaning:
SQL-Server 2000 görünümlerini (kullanımdan kaldırıldı) kullanmak istemiyorsanız, şunu kullanın:

-- 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

Ayrıca, garip bir şekilde adlandırılmış veritabanı veya kullanıcı üzerindeki hatayı önler ve ayrıca hiçbir kullanıcı ilişkilendirilmemişse hatayı düzeltir (sa oturum açma kullanır).


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.