web-dev-qa-db-ja.com

SQL Serverでデータベースのエイリアスを作成する方法

約10年前に非常に古いソフトウェアが作成されており、ソースコードはありません。

ソフトウェアは、同じSQL Server 2012インスタンスでDB01DB02の2つのデータベースを使用します。

db01..table1 join db02..table2などのSQLステートメントがありますが、主な問題は、プロセスがデータベース名としてdb02を使用できないことです。

問題は、データベースのエイリアスをどのように作成できるかです。

CREATE SYNONYMを使用しようとしていました

CREATE SYNONYM [db02] FOR [db02_new_name];

ただし、データベース名では機能しません。

SQLステートメントを修正するためにバイナリファイルにパッチを適用せずに解決する方法を提案してください。

30
Dmitriy Sosunov

偽装する名前でデータベースを作成します。 DDLコードジェネレーターを再度ジグして、ハードコーディングされた名前でアクセスする必要があるテーブルがあるデータベース内のすべてのテーブルのビューを作成します。基本的に、各ビューには次のようなステートメントがあります。

CREATE VIEW schemaname.tablename as SELECT * FROM targetdbname.schemaname.tablename

例:

ハードコーディングされたターゲットデータベース名はProdDBV1と呼ばれ、所有するソースDBはProductDatabaseDatabaseV1、スキーマはdbo、テーブル名はcustomerと呼ばれます。

  1. SSMSまたはスクリプトを使用して、ProdDBV1というデータベースを作成します。
  2. CREATE VIEW dbo.customer as SELECT * FROM ProductDatabaseDatabaseV1.dbo.customer

「ソース」データベースの各テーブルを列挙し、上記のようにDDLを作成できる場合。必要に応じて、コード例を使用してこの投稿を更新できます。 (可能であればsp_msforeachtableプロシージャを使用)

11
Charles

同様の問題がありました。
これは 回避策 で解決され、同義語を使用しています。

短いバージョン:参照する必要があるすべてのオブジェクトの同義語でデータベースをあふれさせます。後で、他のデータベース名ですべての同義語を再作成します。

11
maxcastaneda

これを行うストアドプロシージャを次に示します。データベースに追加して、ターゲットデータベースで呼び出すだけです。ターゲットデータベース内のすべてのテーブルの同義語を作成し、スキーマが存在しない場合は作成します。誰かがカーソルなしでスキーマを作成する方法を知っている場合に備えて、コメントアウトされたセクションを残しました。

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'
3
Adam Hardy

問題は、データベースのエイリアスをどのように作成できるかです。

私はこれが古い投稿であることを知っていますが...

これが、SQLオブジェクトに2部構成の命名規則のみを使用する理由です。それは私がいる環境に応じて異なる名前のデータベースを指す2つの部分の同義語を持つことができます。あまりうまく動作しない場所がありますが、ほとんどの場合、それらの場所は非常にまれです。

あなたがソースコードを持っていないソフトウェアについては、そのソフトウェアが3つの部分の命名規則を使用している場合、各オブジェクトの3つの部分の命名規則が何であるかを知らず、3つの部分を作成しない限り、おそらく運が悪いでしょう各オブジェクトの同義語。

0
Jeff Moden
  1. エイリアスを作成するデータベースに移動し、

  2. 優先設計でエイリアスフォルダーテーブルを作成し、

  3. 一意のIDのテーブルに移動し、作成されたテーブルの最後のコードシーケンスを確認します。

    たとえば、最後のコードが10の場合、11に更新します。

  4. キャビネットテーブルを開き、右下に移動して、必要なエイリアスキャビネットの名前を作成します。

0
Suzie

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オブジェクトを参照するビューを配置している場合、問題があることに注意してください。これらの同義語は機能しません。元のオブジェクト/ビューでこれを修正する必要があります。

0
Magier