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.