SID ของเจ้าของฐานข้อมูลที่บันทึกไว้ในฐานข้อมูลหลักแตกต่างจาก SID ของเจ้าของฐานข้อมูล


87

เมื่อฉันพยายามติดตั้ง tSQLt ลงในฐานข้อมูลที่มีอยู่ฉันได้รับข้อผิดพลาดต่อไปนี้:

SID ของเจ้าของฐานข้อมูลที่บันทึกในฐานข้อมูลหลักแตกต่างจาก SID ของเจ้าของฐานข้อมูลที่บันทึกไว้ในฐานข้อมูล '' คุณควรแก้ไขสถานการณ์นี้โดยการรีเซ็ตเจ้าของฐานข้อมูล '' โดยใช้คำสั่ง ALTER AUTHORIZATION

คำตอบ:


143

ปัญหานี้อาจเกิดขึ้นเมื่อฐานข้อมูลที่กู้คืนจากข้อมูลสำรองและ 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

3
หากคุณมีช่องว่างหรืออักขระพิเศษเช่น "-" ในชื่อ DB ของคุณสคริปต์นี้จะทำให้คุณมีข้อผิดพลาด ดังนั้นเพียงใส่ [] วงเล็บดังนี้: 'ALTER AUTHORIZATION ON DATABASE :: [<<DatabaseName>>] ถึง [<<LoginName>>]'
buhtla

10
เมื่อฉันเรียกใช้สิ่งนี้ฉันได้รับข้อผิดพลาด "เจ้าของฐานข้อมูลใหม่ที่เสนอเป็นผู้ใช้หรือนามแฝงในฐานข้อมูลอยู่แล้ว"
MobileMon

สำหรับสคริปต์นี้การรวมภายในกับ syslogins ไม่ทำงานสำหรับฉันอาจเป็นเพราะ SID ไม่ตรงกันเป็นปัญหา
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.
silver

19

ใช้สคริปต์ด้านล่างกับฐานข้อมูลที่คุณได้รับข้อผิดพลาด:

EXEC sp_changedbowner 'sa'

ALTER DATABASE [database_name] SET TRUSTWORTHY ON 

1
คำสั่งที่สองระบุถึงช่องโหว่ด้านความปลอดภัยต่อไปนี้: VA1102 - บิตที่น่าเชื่อถือควรถูกปิดใช้งานบนฐานข้อมูลทั้งหมดยกเว้น MSDB
Shadi Namrouti

5

Necromaning:
ถ้าคุณไม่ต้องการใช้มุมมอง 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)


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.