最近我们的数据库服务器出现了问题,经过长时间的努力,决定更换数据库服务器。所以我们设法将数据库恢复到另一台服务器上,更改了连接字符串等。一切都按计划进行,直到我们尝试从Web浏览器访问网站时发生了错误。
我们开始收到有关找不到数据库对象的错误。后来我们发现这是由于修改的模式名称导致的。由于在Kentico数据库中有数百个数据库对象(表、视图和存储过程),因此手动逐个更改所有这些对象是不可行的。是否有实用的方法可以解决这个问题?
最近我们的数据库服务器出现了问题,经过长时间的努力,决定更换数据库服务器。所以我们设法将数据库恢复到另一台服务器上,更改了连接字符串等。一切都按计划进行,直到我们尝试从Web浏览器访问网站时发生了错误。
我们开始收到有关找不到数据库对象的错误。后来我们发现这是由于修改的模式名称导致的。由于在Kentico数据库中有数百个数据库对象(表、视图和存储过程),因此手动逐个更改所有这些对象是不可行的。是否有实用的方法可以解决这个问题?
是的,这是可能的。
要更改数据库对象的模式,您需要运行以下SQL脚本:
ALTER SCHEMA NewSchemaName TRANSFER OldSchemaName.ObjectName
ObjectName可以是表、视图或存储过程的名称。问题似乎在于获取具有给定架构名称的所有数据库对象的列表。幸运的是,有一个名为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;
现在您可以运行所有这些生成的查询来完成转移操作。
这是我运行的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
Phew!
您可以通过复制/粘贴以下脚本来处理所有对象
注意:您需要在脚本中更改模式名称!
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 ***'
感谢您的提示。这是我的更新版本,我在输出中添加了换行符,并在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'))
SELECT
'ALTER SCHEMA NewSchemaName TRANSFER [' + ss.name + '].[' + so.name + '];' + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10)
FROM
sys.objects so
INNER JOIN sys.schemas ss ON
so.schema_id = ss.schema_id
WHERE
ss.name = 'OldSchemaName'
AND (so.type IN ('U', 'P', 'V'))