基本的なコンセプトは、実際には非常に簡単です:あなたは、スクリプトを生成sys.objects
し、sys.schemas
構築することALTER SCHEMA TRANSFER
のステートメントを。たとえば、dbo
スキーマに3つのオブジェクトがあり、それらすべてをblat
スキーマに移動したいとします。
Table: dbo.foo
Table: dbo.bar
View: dbo.vFooBar
次のコード:
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;
このスクリプトを生成します(ただし、おそらくこの順序ではありません)。
ALTER SCHEMA blat TRANSFER dbo.bar;
ALTER SCHEMA blat TRANSFER dbo.foo;
ALTER SCHEMA blat TRANSFER dbo.vFooBar;
(追加のフィルターを追加して、移動したくない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;
外部キーは実際には予想よりもスムーズに移行します(ただし、あなたよりも新しいバージョンでテストしていることに注意してください)。ただし、コードはblat.pX
まだ参照しているためdbo.bar
、明らかにプロシージャを実行します。
EXEC blat.pX;
このエラーが発生します:
メッセージ208、レベル16、状態1、手順pX
無効なオブジェクト名 'dbo.bar'。
そして、次のような依存クエリ:
SELECT * FROM sys.dm_sql_referenced_entities('blat.pX', N'OBJECT');
このエラーが発生します:
メッセージ2020、レベル16、状態1
エンティティ「blat.pX」について報告される依存関係には、すべての列への参照が含まれていない場合があります。これは、エンティティが存在しないオブジェクトを参照しているか、エンティティ内の1つ以上のステートメントのエラーが原因です。クエリを再実行する前に、エンティティにエラーがないこと、およびエンティティによって参照されるすべてのオブジェクトが存在することを確認してください。
そしてビューをクエリします:
SELECT a, barA FROM blat.vFooBar;
次のエラーが発生します:
メッセージ208、レベル16、状態1、プロシージャvFooBar
無効なオブジェクト名 'dbo.foo'。
メッセージ4413、レベル16、状態1
バインドエラーのため、ビューまたは関数 'blat.vFoobar'を使用できませんでした。
したがって、これには多くのクリーンアップが含まれる可能性があります。また、すべてのオブジェクト参照を修正したら、すべてのモジュールを再コンパイルして、新しいスキーマのすべてのビューを更新する必要があります。上記の例とよく似たスクリプトを生成できます。