Mat*_*hew 8 schema sql-server-2008-r2
我们目前有多个数据库,但希望将它们组合起来,取而代之的是使用模式分离我们的域上下文。
在 MS SQL Server 2008 R2 中,如何将一个架构的所有内容批量重定位到另一个架构中?
例如,我们在dbo模式中创建的所有表、视图、过程、索引等……现在都将存在于foo模式中。
编辑:我想根据 AaronBertrand 的精彩评论进行澄清。这不是多租户情况。我们的情况是,内部工具插件是由开发人员单独开发的,他们没有将他们的表合并到工具的数据库中。
基本概念实际上非常简单:您可以从中生成脚本sys.objects并sys.schemas构建ALTER SCHEMA TRANSFER语句。例如,您在dbo架构中有三个对象,并且您希望将它们全部移动到blat架构中:
Table: dbo.foo
Table: dbo.bar
View: dbo.vFooBar
Run Code Online (Sandbox Code Playgroud)
以下代码:
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += N'
ALTER SCHEMA blat TRANSFER dbo.' + QUOTENAME(o.name) + ';'
FROM sys.objects AS o
INNER JOIN sys.schemas AS s
ON o.[schema_id] = s.[schema_id]
WHERE s.name = N'dbo';
PRINT @sql;
-- EXEC sp_executesql @sql;
Run Code Online (Sandbox Code Playgroud)
将产生此脚本(但可能不是按此顺序):
ALTER SCHEMA blat TRANSFER dbo.bar;
ALTER SCHEMA blat TRANSFER dbo.foo;
ALTER SCHEMA blat TRANSFER dbo.vFooBar;
Run Code Online (Sandbox Code Playgroud)
(您可能需要添加额外的滤镜来离开了对象的dbo模式,你不想要移动,离开了特定的对象类型(例如,也许您的所有功能都实用功能,并不需要移动),生成按对象类型排序的脚本等)
但是将所有对象移动到新模式存在一些问题:
可能很多你的代码仍然会引用这些对象dbo.object——除了蛮力之外,没有简单的方法来解决这个问题。您可能dbo.很容易找到所有出现的,但这些也可能返回误报,例如EXEC dbo.sp_executesql,dbo.在注释中,对保留在dbo.架构中的对象的真实引用等。
您的依赖项可能会完全不正常,但我还没有对此进行彻底测试。我知道在这种情况下:
CREATE SCHEMA blat AUTHORIZATION dbo;
GO
CREATE TABLE dbo.foo(a INT PRIMARY KEY);
CREATE TABLE dbo.bar(a INT FOREIGN KEY REFERENCES dbo.foo(a));
GO
CREATE PROCEDURE dbo.pX AS
BEGIN
SET NOCOUNT ON;
SELECT a FROM dbo.bar;
END
GO
CREATE VIEW dbo.vFooBar
AS
SELECT foo.a, bar.a AS barA
FROM dbo.foo
INNER JOIN dbo.bar
ON foo.a = bar.a;
GO
ALTER SCHEMA blat TRANSFER dbo.foo;
ALTER SCHEMA blat TRANSFER dbo.bar;
ALTER SCHEMA blat TRANSFER dbo.pX;
ALTER SCHEMA blat TRANSFER dbo.vFooBar;
Run Code Online (Sandbox Code Playgroud)
外键的迁移实际上比我预期的更顺利(需要注意的是,我正在测试比您更新的版本)。但是因为里面的代码blat.pX还是引用了dbo.bar,显然是在执行这个过程:
EXEC blat.pX;
Run Code Online (Sandbox Code Playgroud)
将产生此错误:
消息 208,级别 16,状态 1,过程 pX
无效的对象名称“dbo.bar”。
以及依赖查询,例如:
SELECT * FROM sys.dm_sql_referenced_entities('blat.pX', N'OBJECT');
Run Code Online (Sandbox Code Playgroud)
会产生这个错误:
消息 2020,级别 16,状态 1
为实体“blat.pX”报告的依赖关系可能不包括对所有列的引用。这要么是因为实体引用了一个不存在的对象,要么是因为实体中的一个或多个语句出错。在重新运行查询之前,请确保实体中没有错误并且实体引用的所有对象都存在。
并查询视图:
SELECT a, barA FROM blat.vFooBar;
Run Code Online (Sandbox Code Playgroud)
产生这些错误:
消息 208,级别 16,状态 1,过程 vFooBar
无效的对象名称“dbo.foo”。
消息 4413,级别 16,状态 1
由于绑定错误, 无法使用视图或函数“blat.vFoobar”。
因此,这可能涉及大量清理工作。在修复了所有对象引用之后,您可能希望重新编译所有模块并刷新新模式中的所有视图。您可以为该脚本生成与上述示例非常相似的脚本。