web-dev-qa-db-ja.com

MSSQLですべてのテーブル、ビュー、ストアドプロシージャのスキーマを変更する方法

最近、データベースサーバーに問題が発生し、長い間努力してデータベースサーバーを変更することにしました。そのため、別のサーバーでデータベースを復元したり、接続文字列を変更したりすることができました。WebブラウザーからWebサイトにアクセスしようとするまで、すべてが計画どおりに進行していました。

データベースオブジェクトが見つからないというエラーが表示されるようになりました。後で、変更されたスキーマ名の結果として発生したことがわかりました。 Kenticoデータベースには何百ものデータベースオブジェクト(テーブル、ビュー、ストアドプロシージャ)があるため、それらをすべて手動で1つずつ変更することはできません。これを行う実用的な方法はありますか?

24
anar khalilov

はい、可能です。

データベースオブジェクトのスキーマを変更するには、次の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;

これで、生成されたこれらすべてのクエリを実行して、転送操作を完了できます。

84
anar khalilov

データベース内のすべてのテーブル(複数のスキーマにまたがる)を「dbo」スキーマに移動するために実行したSQLは次のとおりです。

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
Mike Gledhill

ヒントに感謝します。同じものへの私のアップデートは、出力に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'))
2
Hank Freeman

すべてのオブジェクトのコピー/貼り付けだけで次のスクリプトを使用できます

[〜#〜] note [〜#〜]:変更する必要がありますスクリプトのスキーマ名!

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 ***'
1
Haseeb Ahmed