SID pemilik database yang direkam dalam database master berbeda dengan SID pemilik database

87

Ketika saya mencoba menginstal tSQLt ke database yang sudah ada, saya mendapatkan error berikut:

SID pemilik database yang tercatat di database master berbeda dengan SID pemilik database yang tercatat di database ''. Anda harus memperbaiki situasi ini dengan mengatur ulang pemilik database '' menggunakan pernyataan ALTER AUTHORIZATION.

JDPeckham
sumber

Jawaban:

143

Masalah ini dapat muncul ketika database dipulihkan dari cadangan dan SID pemilik database tidak cocok dengan SID pemilik yang tercantum dalam database master. Berikut adalah solusi yang menggunakan pernyataan "ALTER AUTHORIZATION" yang disarankan dalam pesan kesalahan:

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)
JohnnyM
sumber
Terima kasih! Sepertinya lebih tepat. Apakah menurut Anda tidak ada gunanya menggunakan quotename () daripada meletakkan '[' dalam string? Juga mungkin memilih ke var DBName dan var LoginName lalu menggabungkannya ke dalam var Command daripada menggunakan REPLACE ()?
JDPeckham
3
Jika Anda memiliki spasi atau karakter khusus seperti '-' pada nama DB Anda, skrip ini akan memberi Anda kesalahan. Jadi cukup masukkan [] tanda kurung seperti ini: 'ALTER AUTHORIZATION ON DATABASE :: [<<DatabaseName>>] TO [<<LoginName>>]'
buhtla
10
Ketika saya menjalankan ini, saya mendapatkan kesalahan "Pemilik database baru yang diusulkan sudah menjadi pengguna atau alias dalam database"
MobileM
Untuk script ini, batin bergabung untuk syslogins tidak bekerja untuk saya mungkin karena SID ketidakcocokan adalah masalah.
crokusek
31

Menambahkan ini ke bagian atas skrip 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)
JDPeckham
sumber
Ini bekerja seperti jimat dengan tSQLt Version: 1.0.5873.27393dan tampaknya menjadi solusi yang lebih sederhana. Menggunakan Pengembang MS SQL Server 2019 dan SSMS 18.
perak
19

Terapkan skrip di bawah ini pada database Anda mendapatkan kesalahan:

EXEC sp_changedbowner 'sa'

ALTER DATABASE [database_name] SET TRUSTWORTHY ON 
NarendraMishra
sumber
1
Pernyataan kedua menunjukkan kerentanan keamanan berikut: VA1102 - Bit Tepercaya harus dinonaktifkan pada semua database kecuali MSDB
Shadi Namrouti
5

Necromaning:
Jika Anda tidak ingin menggunakan tampilan SQL-Server 2000 (usang), gunakan ini:

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

Juga mencegah bug pada database atau pengguna bernama aneh, dan juga memperbaiki bug jika tidak ada pengguna yang dikaitkan (menggunakan login).

Stefan Steiger
sumber
3

Cara termudah untuk mengubah pemilik DB adalah:

EXEC SP_ChangeDBOwner 'sa'
Shadi Namrouti
sumber
Ya, kami telah menetapkannya.
JDPeckham