約10年前に非常に古いソフトウェアが作成されており、ソースコードはありません。
ソフトウェアは、同じSQL Server 2012インスタンスでDB01
とDB02
の2つのデータベースを使用します。
db01..table1 join db02..table2
などのSQLステートメントがありますが、主な問題は、プロセスがデータベース名としてdb02
を使用できないことです。
問題は、データベースのエイリアスをどのように作成できるかです。
CREATE SYNONYM
を使用しようとしていました
CREATE SYNONYM [db02] FOR [db02_new_name];
ただし、データベース名では機能しません。
SQLステートメントを修正するためにバイナリファイルにパッチを適用せずに解決する方法を提案してください。
偽装する名前でデータベースを作成します。 DDLコードジェネレーターを再度ジグして、ハードコーディングされた名前でアクセスする必要があるテーブルがあるデータベース内のすべてのテーブルのビューを作成します。基本的に、各ビューには次のようなステートメントがあります。
CREATE VIEW schemaname.tablename as SELECT * FROM targetdbname.schemaname.tablename
例:
ハードコーディングされたターゲットデータベース名はProdDBV1
と呼ばれ、所有するソースDBはProductDatabaseDatabaseV1
、スキーマはdbo
、テーブル名はcustomer
と呼ばれます。
ProdDBV1
というデータベースを作成します。CREATE VIEW dbo.customer as SELECT * FROM ProductDatabaseDatabaseV1.dbo.customer
「ソース」データベースの各テーブルを列挙し、上記のようにDDLを作成できる場合。必要に応じて、コード例を使用してこの投稿を更新できます。 (可能であればsp_msforeachtable
プロシージャを使用)
同様の問題がありました。
これは 回避策 で解決され、同義語を使用しています。
短いバージョン:参照する必要があるすべてのオブジェクトの同義語でデータベースをあふれさせます。後で、他のデータベース名ですべての同義語を再作成します。
これを行うストアドプロシージャを次に示します。データベースに追加して、ターゲットデータベースで呼び出すだけです。ターゲットデータベース内のすべてのテーブルの同義語を作成し、スキーマが存在しない場合は作成します。誰かがカーソルなしでスキーマを作成する方法を知っている場合に備えて、コメントアウトされたセクションを残しました。
CREATE PROCEDURE CreateSynonymsForTargetDatabase (
@databaseName sysname
)
AS BEGIN
DECLARE @TSQL nvarchar(max) = N''
DECLARE @rn char(2),
@SchemaName sysname;
SET @rn = char(13) + char(10)
CREATE TABLE #DBSynonym(
[Schema] sysname NOT NULL,
[Table] sysname NOT NULL
)
SET @TSQL = N'
INSERT INTO #DBSynonym ([Schema], [Table])
SELECT Schemas.name, Tables.name
FROM [' + @databaseName + '].sys.tables
INNER JOIN [' + @databaseName + '].sys.schemas on tables.schema_id = schemas.schema_id
'
EXEC (@TSQL)
SET @TSQL = N''
DECLARE MissingSchemasCursor CURSOR
READ_ONLY
FOR
SELECT newSchemas.[Schema]
FROM #DBSynonym newSchemas
LEFT JOIN sys.schemas on newSchemas.[Schema] = schemas.name
WHERE schemas.schema_id is null
GROUP BY newSchemas.[Schema]
OPEN MissingSchemasCursor
FETCH NEXT FROM MissingSchemasCursor INTO @SchemaName
WHILE (@@fetch_status <> -1)
BEGIN
IF (@@fetch_status <> -2)
BEGIN
SET @TSQL = N'CREATE SCHEMA ' + QUOTENAME(@SchemaName) + N';'
EXEC sp_executesql @TSQL
END
FETCH NEXT FROM MissingSchemasCursor INTO @SchemaName
END
CLOSE MissingSchemasCursor
DEALLOCATE MissingSchemasCursor
/*
SELECT @TSQL = @TSQL +
N'
GO
CREATE SCHEMA ' + QUOTENAME([Schema]) + N';'
FROM #DBSynonym newSchemas
LEFT JOIN sys.schemas on newSchemas.[Schema] = schemas.name
WHERE schemas.schema_id is null
GROUP BY newSchemas.[Schema]
PRINT 'CREATE SCHEMAS : ' + ISNULL(@TSQL,'')
EXEC sp_executesql @TSQL
*/
SET @TSQL = N''
SELECT @TSQL = @TSQL +
N'
CREATE SYNONYM ' + QUOTENAME([Schema]) + N'.' + QUOTENAME([Table]) + N'
FOR ' + QUOTENAME(@databaseName) + N'.' + QUOTENAME([Schema]) + N'.' + QUOTENAME([Table]) + N';'
FROM #DBSynonym
EXEC sp_executesql @TSQL
SET @TSQL = N''
END
GO
次のように使用します。
EXEC CreateSynonymsForTargetDatabase 'targetDbName'
問題は、データベースのエイリアスをどのように作成できるかです。
私はこれが古い投稿であることを知っていますが...
これが、SQLオブジェクトに2部構成の命名規則のみを使用する理由です。それは私がいる環境に応じて異なる名前のデータベースを指す2つの部分の同義語を持つことができます。あまりうまく動作しない場所がありますが、ほとんどの場合、それらの場所は非常にまれです。
あなたがソースコードを持っていないソフトウェアについては、そのソフトウェアが3つの部分の命名規則を使用している場合、各オブジェクトの3つの部分の命名規則が何であるかを知らず、3つの部分を作成しない限り、おそらく運が悪いでしょう各オブジェクトの同義語。
エイリアスを作成するデータベースに移動し、
優先設計でエイリアスフォルダーテーブルを作成し、
一意のIDのテーブルに移動し、作成されたテーブルの最後のコードシーケンスを確認します。
たとえば、最後のコードが10の場合、11に更新します。
キャビネットテーブルを開き、右下に移動して、必要なエイリアスキャビネットの名前を作成します。
Charlesの答え(およびmaxcastanedaによるコメントのリンクされた回避策)が非常に役立つことがわかりました。私はこのアプローチに従いましたが、私にとってはうまくいきます。少し合理化し、作成する必要なすべての同義語を表示する次のクエリを作成しました。
このスニペットの前提条件として、元のDBとシノニム/エイリアスdbの両方が同じサーバー上になければなりません。これを小さなspに入れて同義語を自動的に更新するのはかなり簡単です。
USE <SYNONYMDB>
SELECT
'[' + TABLE_NAME + ']',
'[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']',
'IF EXISTS (SELECT * FROM sys.synonyms WHERE name = ''' + TABLE_NAME + ''') DROP SYNONYM ['+ TABLE_NAME + ']; CREATE SYNONYM [' + TABLE_NAME + '] FOR <ORIGINALDB>.' + TABLE_SCHEMA + '.[' + TABLE_NAME + ']' AS SynonymUpdateScript FROM <ORIGINALDB>.INFORMATION_SCHEMA.TABLES
<...>スポットでDb名を入力することを忘れないでください。
SynonymUpdateScript
列の内容をコピーして同義語DBで実行するか、このタスクのストアドプロシージャを作成します。
2部の命名規則を使用せずにテーブルまたは他のdbオブジェクトを参照するビューを配置している場合、問題があることに注意してください。これらの同義語は機能しません。元のオブジェクト/ビューでこれを修正する必要があります。