【问题标题】:SQL Server 2016 Change Object OwnerSQL Server 2016 更改对象所有者
【发布时间】:2016-11-18 15:05:58
【问题描述】:

我继承了一个 SQL 2008 数据库,其中所有对象都以作为所有者的开发人员名称为前缀,即 ownername.sp_get_all_users。

我已将 dbase 恢复到 SQL Server 2016 Express Edition。

有数百个 dbase 对象,有没有办法自动将对象所有者更改为 dbo,而不是手动编辑每个对象?

我已经尝试了以下方法,但显然您不能再对自 SQL Server 2005 以来的对象进行临时更改?

SELECT * from sysobjects where uid = user_id('UseNAme')
declare @Return int
exec @Return = sp_configure 'allow updates', '1'
SELECT @Return as 'Returned Code'
GO
reconfigure WITH OVERRIDE
GO
DECLARE @Rows int, @Error int
BEGIN TRANSACTION
update sysobjects set uid = user_id('dbo') where uid = user_id('UseNAme')
SELECT @Error = @@Error, @Rows = @@RowCount
SELECT @Rows as '#Rows'
IF @Rows > 0
 BEGIN  
  SELECT  @Rows AS '#Rows'
  COMMIT TRANSACTION
 END
else 
 BEGIN
  SELECT @Error AS 'Error #'
  ROLLBACK TRANSACTION
 END

exec sp_configure 'allow updates', '0'
reconfigure WITH OVERRIDE
go

非常感谢任何帮助。

【问题讨论】:

    标签: sql-server sql-server-2016


    【解决方案1】:

    你必须使用 Alter Schema...

    ALTER SCHEMA oldschemaname TRANSFER dbo.Address; 
    

    在下面自动使用

    这会将所有具有系统以外模式的表更改为 dbo,请注意,如果您有两个不同模式的表,它们不能存在于同一模式中

    select *,row_number() over (order by (select null)) as rownum
    into #tables
     from information_Schema.tables
    where table_schema in (select name  from sys.schemas
     where name  not in ('dbo','guest','INFORMATION_SCHEMA','sys') and principal_id <16384
     )
    
    now move 
    declare @min int,@max int
    
    select @min=min(rownum),@max=max(rownum)
    from #tables
    
    declare @tblname varchar(255),@schemaname sysname
    declare @sql varchar(max)
    
    while @min<=@max
    Begin
    
    select @tblname=table_name,@schemaname=table_schema from
    #tables where rownum=@min
    
    set @sql='alter schema dbo transfer '+ @schemaname+'.'+@tblname
    
    --print @sql
    exec(@sql)
    
    Set @min=@min+1
    End
    

    sp_change 对象所有者根据文档状态..

    此存储过程仅适用于 MicrosoftSQL Server 2000 中可用的对象。此功能将在 Microsoft SQL Server 的未来版本中删除。避免在新的开发工作中使用此功能,并计划修改当前使用此功能的应用程序。请改用 ALTER SCHEMA 或 ALTER AUTHORIZATION。 sp_changeobjectowner 同时更改架构和所有者。为了保持与早期版本的 SQL Server 的兼容性,此存储过程将仅在当前所有者和新所有者都拥有与其数据库用户名同名的架构时更改对象所有者。

    【讨论】:

    • 我也会避免sp_msforeachtable - 它不受支持,甚至没有记录。您的代码目前还将尝试移动系统中的每个表,无论它当前处于什么模式。
    • 谢谢@AaronBertrand
    • @TheGameiswar 我更新了我的答案以反映您指出的内容。 SP 在 2012 年仍然适用于我,但你的方法是正确的。希望我的回答现在仍然有价值。
    • 这是漫长的一周,针对正确的数据库运行您的 SQL(与我之前的想法相反)有效。谢谢!
    【解决方案2】:

    使用这个sp_changeobjectowner

    正如这里所解释的MSDN

    例如:EXEC sp_changeobjectowner 'YourObject', 'dbo'

    您可以使用它来更改较新的 SQL Server DBS 的架构语句

    declare @sql varchar(8000), @table varchar(1000), @oldschema varchar(1000), @newschema   varchar(1000)
    
      set @oldschema = 'dbo'
      set @newschema = 'exe'
    
     while exists(select * from sys.tables where schema_name(schema_id) = @oldschema)
    
      begin
          select @table = name from sys.tables 
          where object_id in(select min(object_id) from sys.tables where  schema_name(schema_id)  = @oldschema)
    
        set @sql = 'alter schema ' + @newschema + ' transfer ' + @oldschema + '.' + @table
    
       exec(@sql)
     end
    

    【讨论】:

      【解决方案3】:

      循环遍历开发人员拥有的对象的一般想法是一个好主意(假设您已经测试过了)。我建议使用ALTER AUTHORIZATION 命令而不是MSDN Doc

      【讨论】:

        【解决方案4】:

        除了上述建议之外,SP 的所有者还发生了以下变化:

          Declare @sql varchar(8000),
                @table varchar(1000),
                @oldschema varchar(1000),
                @newschema   varchar(1000)
        
          set @oldschema = 'developername'
          set @newschema = 'dbo'
        
         while exists(select * from information_schema.routines where routine_type = 'PROCEDURE' and routine_schema = @oldschema )
        
          begin
              select @table = SPECIFIC_NAME from information_schema.routines 
              where SPECIFIC_NAME in(select SPECIFIC_NAME from information_schema.routines where routine_type = 'PROCEDURE' and routine_schema = @oldschema)
        
            set @sql = 'alter schema ' + @newschema + ' transfer ' + @oldschema + '.' + @table
        
           exec(@sql)
         end
        

        【讨论】:

          猜你喜欢
          • 2023-03-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-04-22
          • 2018-08-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多