代码之家  ›  专栏  ›  技术社区  ›  Joe

由于不匹配的SID,程序集部署失败

  •  1
  • Joe  · 技术社区  · 7 年前

    因此,这是类似于这种情况,但不完全相同,因此我的问题。

    Msg 33009, Level 16, State 2, Line 17
    The database owner SID recorded in the master database differs from the
    database owner SID recorded in database 'FOO_PROD'. You should correct
    this situation by resetting the owner of database 'FOO_PROD' using the
    ALTER AUTHORIZATION statement.
    

    实际上,以下两个查询证明了SID的差异。 首先,我们看一下FOO\u PROD的SID:

    SELECT  SD.[SID],
            SL.Name as [LoginName]
    FROM  master..sysdatabases SD INNER JOIN master..syslogins SL
        on  SD.SID = SL.SID
    WHERE  SD.Name = 'FOO_PROD'
    

    SID,                                                             LoginName
    
    0x010500000000000515000000C4B7E63D99D15C20332A47A24B100000,      BATZ\boink
    

    其次,我们查看主数据库中FOO\u PROD的SID:

    SELECT  SD.[SID],
            SL.Name as [LoginName]
    FROM  master..sysdatabases SD INNER JOIN master..syslogins SL
        on  SD.SID = SL.SID
    WHERE  SD.Name = 'master'
    

    其中显示了以下结果:

    SID,      LoginName
    
    0x01,   [sa]
    

    火柴它们必须匹配才能继续(显然)。

    约束:无法更改FOO\u PROD上的SID,因为其他几个系统 使用数据库的用户希望它具有当前的SID和登录名。

    这样做伤害了什么,或者是个坏主意?

    如何更改“master”数据库?嗯,我已经 以前没有做过,但可以在这里找到候选解决方案和评论: The database owner SID recorded in the master database differs from the database owner SID

    考虑到主数据库ala上必须发生变化:

      exec sp_changedbowner [BATZ\boink]
    

    问题2:这样做正确吗?

    根据@srutzky的更新答案进行更新:

      -- Step 1
      SELECT sd.[name], sd.[owner_sid], sp.[name]
      FROM   sys.databases sd
      INNER JOIN sys.server_principals sp
              ON sp.[sid] = sd.[owner_sid]
      WHERE  sd.[name] = N'FOO_PROD';
    

    返回:

      name, owner_sid,  name
      FOO_PROD, 0x010500000000000515000000C4B7E63D99D15C20332A47A24B100000, BATZ\boink
    

    然后

      -- Step 2
      USE [FOO_PROD];
      SELECT dp.[sid], sp.[name]
      FROM   sys.database_principals dp
      INNER JOIN sys.server_principals sp
              ON sp.[sid] = dp.[sid]
      WHERE  dp.[name] = N'dbo';
    

      sid,  name
      0x01, sa
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   Solomon Rutzky    7 年前

    是的,SID确实需要匹配,因为不匹配表示正在将潜在有害的DB恢复到实例中;这是一个安全警卫。

    但是,首先我们需要确切地知道我们在看什么。虽然中的记录之间的所有者SID肯定不匹配 FOO_PROD master (因此出现错误消息),您的查询没有查看 。您的两个查询正在查看中的值 主人 对于所有者 ,和 主人 (此处完全无关)。

    不要使用 sys* 任何东西的对象都是兼容性视图,因此为SQL Server 2000和更早版本编写的旧东西仍然可以工作(很好, dbo.sys* msdb sys.* 对象(无需指定 master. )应使用。含义、用途:

    SELECT sd.[name], sd.[owner_sid], sp.[name]
    FROM   sys.databases sd
    INNER JOIN sys.server_principals sp
            ON sp.[sid] = sd.[owner_sid]
    WHERE  sd.[name] = N'FOO_PROD';
    

    第2步

    sys.databases (甚至在 master..sysdatabases ). 在检查数据库的所有者值时,需要查看 sys.database_principals 对于 dbo

    USE [FOO_PROD];
    SELECT dp.[sid], sp.[name]
    FROM   sys.database_principals dp
    INNER JOIN sys.server_principals sp
            ON sp.[sid] = dp.[sid]
    WHERE  dp.[name] = N'dbo';
    

    步骤3

    使用 sp_changedbowner 如果您使用的是SQL Server 2005,但从SQL Server 2008开始,该存储过程已被弃用,取而代之的是较新的 ALTER AUTHORIZATION (尽管它仍然有效)。但是是的,这是使它们相同的方法,因为它将两个位置同步到您指定的任何登录。

    BATZ\boink 是SQL Server实例所属域的有效Windows登录,并且此特定Windows登录的SID为 0x010500000000000515000000C4B7E63D99D15C20332A47A24B100000 。如果登录不存在,希望您能够通过 CREATE LOGIN .

        2
  •  1
  •   David Browne - Microsoft    7 年前

    由于数据库中的所有者是SA,并且您希望将Master中记录的所有者更改为SA,因此只需运行

    alter authorization on database::[foo_prod] to sa