在SQL Server 2005中,如何更改表的“模式”而不丢失任何数据?

75
我有一张表格被放在了"db_owner"模式下,我需要将它转移到"dbo"模式下。是否有脚本或命令可以切换它?

5
学究主义:*losing 请校对。 - GEOCHET
8个回答

86
在 SQL Server Management Studio 中:
  1. 右键点击表并选择修改(现在称为“设计”)
  2. 在属性面板上选择正确的拥有模式。

7
谢谢,有趣。如果你只是右键单击->属性,那么架构是不可改变的,所以我认为这是一项只属于忍者的命令任务之一。很高兴知道它并没有感觉那么痛苦。 - DevelopingChris
2
根据使用的SQL Server Management Studio版本,修改可能被称为设计。 - cjbarth
3
如果您只看到“列属性”窗口,请转到“视图”并选择“属性窗口”。编辑后,不要忘记保存更改。 - Jonas Äppelgran

84
ALTER SCHEMA [NewSchema] TRANSFER [OldSchema].[Table1]

这似乎无法在SQL Server Management Studio中将表从'OldSchema.Table1'重命名为'NewSchema.Table1'。 - Sanchit
3
你刷新了表格列表吗?我发现,与通过选择表格和使用内置工具进行更改不同,在使用tsql执行更改时,Management Studio倾向于不更新数据库列表,除非你强制要求它这样做。或者你断开/重连连接。 - Stephen Wrighton
是的,这绝对只是一个视觉问题,尽管SQL Server让我相信它不是。在运行您的命令并刷新等操作后,如果您在设计视图中右键单击表,然后在属性窗口中将模式从oldSchema更改为newSchema,则会刷新表名(以及警告消息)。我只希望这样做就相当于使用命令进行GUI操作,而不是完全不同的操作。有没有办法进行检查? - Sanchit

12

通过此选择显示所有的TABLE_SCHEMA

SELECT TABLE_SCHEMA, TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLES 

您可以使用此查询将所有表的模式更改为dbo表模式:

DECLARE cursore CURSOR FOR 

SELECT TABLE_SCHEMA, TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_SCHEMA <> 'dbo' 


DECLARE @schema sysname, 
 @tab sysname, 
 @sql varchar(500) 


OPEN cursore     
FETCH NEXT FROM cursore INTO @schema, @tab 

WHILE @@FETCH_STATUS = 0     
BEGIN 
 SET @sql = 'ALTER SCHEMA dbo TRANSFER ' + @schema + '.' + @tab     
 PRINT @sql     
 FETCH NEXT FROM cursore INTO @schema, @tab     
END 

CLOSE cursore     
DEALLOCATE cursore

1
这个很好用。请注意,PRINT @sql 应该改为 EXEC(@sql) - tharen

7
简单回答
sp_changeobjectowner [ @objname = ] 'object' , [ @newowner = ] 'owner'

你不需要停止所有与数据库的连接,这可以在运行时完成。


1
从技术上讲,是的。不过它仍然在Denali中,并且对于OP所要求的操作来说运行良好。他们总是说他们会将其删除,但他们从未这样做。 - Jeremy

6

对于sAeid的优秀答案,我进行了轻微改进...

我添加了一个exec来使代码自动执行,并在顶部添加了一个union,以便我可以更改两个表和存储过程的模式:

DECLARE cursore CURSOR FOR 


select specific_schema as 'schema', specific_name AS 'name'
FROM INFORMATION_SCHEMA.routines
WHERE specific_schema <> 'dbo' 

UNION ALL

SELECT TABLE_SCHEMA AS 'schema', TABLE_NAME AS 'name'
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_SCHEMA <> 'dbo' 



DECLARE @schema sysname, 
 @tab sysname, 
 @sql varchar(500) 


OPEN cursore     
FETCH NEXT FROM cursore INTO @schema, @tab 

WHILE @@FETCH_STATUS = 0     
BEGIN 
 SET @sql = 'ALTER SCHEMA dbo TRANSFER [' + @schema + '].[' + @tab +']'    
 PRINT @sql   
 exec (@sql)  
 FETCH NEXT FROM cursore INTO @schema, @tab     
END 

CLOSE cursore     
DEALLOCATE cursore

我也需要恢复一个数据库转储,但发现模式不是dbo - 我花了几个小时尝试使用Sql Server管理工具或Visual Studio数据传输来更改目标模式...最终我只是在新服务器上对恢复的转储运行了这个命令,以达到我想要的效果。


很棒的答案!+1 包含例程。我的数据库也包含了它们。还有 VIEW 和 FUNCTION 系统对象,它们都有模式字段。但在我的情况下,它们都在 'dbo' 模式中。 - Seven

4
当我使用SQL Management Studio时,我只能看到“设计”或“编辑”选项,而没有“修改”选项。如果您有Visual Studio(我已经检查了VS.NET 2003、2005和2008),则可以使用服务器资源管理器来更改模式。右键单击表格,选择“设计表”(2008)或“打开表定义”(2003、2005)。突出显示整个“列名”列。然后,您可以右键单击并选择“属性页面”或“属性”(2008)。从属性表中,您应该可以看到“所有者”(2003和2005)或“模式”(2008),并且有一个下拉列表可供选择可能的模式。

2

我使用这个方法来解决需要在不同模式下使用一堆表的情况,例如在dbo模式下。

declare @sql varchar(8000)
;

select
  @sql = coalesce( @sql, ';', '') + 'alter schema dbo transfer [' + s.name + '].[' + t.name + '];'
from 
  sys.tables t
  inner join
  sys.schemas s on t.[schema_id] = s.[schema_id]
where 
  s.name <> 'dbo'
;

exec( @sql )
;

-3
你需要首先停止所有连接到数据库的进程,然后通过运行命令改变那些拥有者为“db_owner”的表格的所有权。
sp_MSforeachtable @command1="sp_changeobjectowner ""?"",'dbo'"

其中 ? 是表名。


sp_changedbowner存储过程已经被弃用,而sp_MSforeachtable和sp_MSforeachdatabase也不可靠。我开始使用Bertrand的版本。 - Oliver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接