如何更改 MSSQL 中所有表、视图和存储过程的架构

Posted

技术标签:

【中文标题】如何更改 MSSQL 中所有表、视图和存储过程的架构【英文标题】:How to change schema of all tables, views and stored procedures in MSSQL 【发布时间】:2013-07-08 10:01:36 【问题描述】:

最近我们的数据库服务器出现问题,经过长时间的努力,我们决定更换数据库服务器。因此,我们设法在另一台服务器上恢复数据库,更改连接字符串等。一切都按计划进行,直到我们尝试从 Web 浏览器访问该网站。

我们开始收到有关未找到数据库对象的错误。后来我们发现它是由于修改了模式名称而发生的。由于 Kentico 数据库中有数百个数据库对象(表、视图和存储过程),因此手动一个一个地更改它们是不可行的。有没有实用的方法?

【问题讨论】:

您确定您的用户默认架构设置不正确吗? 这个问题已经有将近两年的历史了,但据我所知,它与用户的默认架构无关。 哦!由于某种原因,它出现在列表的顶部! 读者 - 另见微软回答:support.managed.com/kb/a100/… 我最近遇到了同样的问题。是什么导致在使用现有用户创建新数据库实例并向新实例分配权限时更改对象架构? 【参考方案1】:

是的,有可能。

要更改数据库对象的架构,您需要运行以下 SQL 脚本:

ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.ObjectName

其中 ObjectName 可以是表、视图或存储过程的名称。问题似乎是获取具有给定 shcema 名称的所有数据库对象的列表。值得庆幸的是,有一个名为 sys.Objects 的系统表存储所有数据库对象。以下查询将生成完成此任务所需的所有 SQL 脚本:

SELECT 'ALTER SCHEMA NewSchemaName TRANSFER [' + SysSchemas.Name + '].[' + DbObjects.Name + '];'
FROM sys.Objects DbObjects
INNER JOIN sys.Schemas SysSchemas ON DbObjects.schema_id = SysSchemas.schema_id
WHERE SysSchemas.Name = 'OldSchemaName'
AND (DbObjects.Type IN ('U', 'P', 'V'))

其中类型“U”表示用户表,“V”表示视图,“P”表示存储过程。

运行上述脚本将生成将对象从一种模式传输到另一种模式所需的 SQL 命令。像这样的:

ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.CONTENT_KBArticle;
ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.Proc_Analytics_Statistics_Delete;
ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.Proc_CMS_QueryProvider_Select;
ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.COM_ShoppingCartSKU;
ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.CMS_WebPart;
ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.Polls_PollAnswer;

现在您可以运行所有这些生成的查询来完成传输操作。

【讨论】:

不错的解决方案。我使用“WHERE SysSchemas.Name 'dbo'”来列出所有非 dbo 绑定对象。 而“SO”表示序列 对于 all Tables ,检查 this 和 this 在单个语句中执行此操作,希望对某些人有所帮助。 也想传递函数,可以在列表中添加'FN','TF'。 'FN' 用于标量函数,'TF' 用于表函数。更多信息,请参考:msdn.microsoft.com/en-us/library/ms177596.aspx 这只是完美的答案。感谢@anar 节省了我的时间。【参考方案2】:

这是我运行的 SQL,用于将我数据库中的所有表(分布在多个模式中)移动到“dbo”模式中:

DECLARE 
    @currentSchemaName nvarchar(200),
    @tableName nvarchar(200)

DECLARE tableCursor CURSOR FAST_FORWARD FOR 
SELECT TABLE_SCHEMA, TABLE_NAME
FROM information_schema.tables
ORDER BY 1, 2

DECLARE @SQL nvarchar(400)

OPEN tableCursor 
FETCH NEXT FROM tableCursor INTO @currentSchemaName, @tableName

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @SQL = 'ALTER SCHEMA dbo TRANSFER ' + @currentSchemaName + '.' + @tableName
    PRINT @SQL

    EXEC (@SQL)

    FETCH NEXT FROM tableCursor INTO @currentSchemaName, @tableName
END

CLOSE tableCursor 
DEALLOCATE tableCursor 

呼!

【讨论】:

【参考方案3】:

您可以通过复制/粘贴所有对象来使用以下脚本

注意:您需要在脚本中更改架构名称!

DECLARE @OldSchema VARCHAR(200)
DECLARE @NewSchema VARCHAR(200)
DECLARE @SQL nvarchar(4000)
SET @OldSchema = 'dbo'
SET @NewSchema = 'Inf'

DECLARE tableCursor CURSOR FAST_FORWARD FOR 
    SELECT 'ALTER SCHEMA  ['+ @NewSchema +'] TRANSFER [' + SysSchemas.Name + '].[' + DbObjects.Name + '];' AS Cmd
    FROM sys.Objects DbObjects
    INNER JOIN sys.Schemas SysSchemas ON DbObjects.schema_id = SysSchemas.schema_id
    WHERE SysSchemas.Name = @OldSchema
    AND (DbObjects.Type IN ('U', 'P', 'V'))
OPEN tableCursor 
FETCH NEXT FROM tableCursor INTO  @SQL
WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @SQL
    EXEC (@SQL)
    FETCH NEXT FROM tableCursor INTO  @SQL
END
CLOSE tableCursor 
DEALLOCATE tableCursor 
PRINT '*** Finished ***'

【讨论】:

【参考方案4】:

感谢您的提示.. 这是我的更新,我在输出中添加了一个 crlf,并在 SchemaName 和 ObjectName 周围放置了括号,因为某些对象的名称和括号中有一个“-”解决了命名错误。

SELECT 'ALTER SCHEMA NewSchemaName TRANSFER [' + SysSchemas.Name + '].[' +      DbObjects.Name + '];'
+ CHAR(13)+ CHAR(10)+ 'GO '+ CHAR(13)+ CHAR(10)
FROM sys.Objects DbObjects
INNER JOIN sys.Schemas SysSchemas ON DbObjects.schema_id =     SysSchemas.schema_id
WHERE SysSchemas.Name = 'OldSchemaName'
AND (DbObjects.Type IN ('U', 'P', 'V'))

【讨论】:

以上是关于如何更改 MSSQL 中所有表、视图和存储过程的架构的主要内容,如果未能解决你的问题,请参考以下文章

如何在 mssql 服务器视图中查询访问表

powershell 使用PowerShell导出MSSQL架构。此脚本将导出表,存储过程,触发器,函数和视图的模式定义

MSSQL 事务,视图,索引,存储过程,触发器

如何查询SqlServer和MySql数据库中某个数据库下面所有的视图信息和存储过程的信息,在java中操作

mssql 存储过程调用另一个存储过程中的结果的方法分享

MSSQL存储过程实现拼接sql的注意点