sql >> データベース >  >> RDS >> Sqlserver

リンクサーバーを参照するエンティティを返すSQLServerのsys.dm_sql_referenced_entities()の例

    sys.dm_sql_referenced_entities()に関することの1つ システム動的管理機能は、クロスデータベースおよびクロスサーバーエンティティで使用できることです。

    これは、別のデータベースや別のサーバーにある参照エンティティを見つけることができることを意味します。

    この記事では、sys.dm_sql_referenced_entities()の例を示します。 リンクサーバー上のデータベースを照会するストアドプロシージャを返します。

    例1-ストアドプロシージャ

    まず、リンクサーバーからデータを返すストアドプロシージャを作成しましょう。

    CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS
    SELECT AlbumName
    FROM [Homer].[Music].[dbo].[Albums]
    WHERE ArtistId = @ArtistId;
    

    ストアドプロシージャがデータベーステーブルを参照するために4つの部分からなる名前を使用していることがわかります。これは、データベースが、ストアドプロシージャが配置されているサーバーとはリンクサーバーとして構成されている別のサーバー上にあるためです。

    つまり、このストアドプロシージャは、リンクされたサーバーからデータを返します。

    この例では、Homer リンクサーバーであり、Music はデータベースです。

    例2–ストアドプロシージャに対してsys.dm_sql_referenced_entities()を実行します

    それでは、sys.dm_sql_referenced_entities()を使用しましょう。 ストアドプロシージャで参照されているエンティティを返します。

    SELECT 
        referenced_server_name AS [Server],
         referenced_database_name AS [Database],
         referenced_schema_name AS [Schema],
         referenced_entity_name AS [Entity],
         referenced_minor_name AS [Minor],
         referenced_class_desc AS [Class]
    FROM sys.dm_sql_referenced_entities (
        'dbo.uspGetAlbumsByArtist', 
        'OBJECT');
    

    結果:

    +----------+------------+----------+----------+---------+------------------+
    | Server   | Database   | Schema   | Entity   | Minor   | Class            |
    |----------+------------+----------+----------+---------+------------------|
    | Homer    | Music      | dbo      | Albums   | NULL    | OBJECT_OR_COLUMN |
    +----------+------------+----------+----------+---------+------------------+
    

    そのため、参照されているテーブルが正常に返されました(ただし、列/マイナー名は返されませんでした)。サーバー名( Homer )も含まれます )とデータベース名( Music

    簡潔にするために、この例ではすべての列を返さなかったことに注意してください。

    例3–リンクサーバーでsys.dm_sql_referenced_entities()を実行する

    これらの結果は、ストアドプロシージャが実際の(リモート)リンクサーバー上にある場合に得られる結果とは異なるように見えますか?

    試してみよう。

    ここで、他のサーバーにジャンプして、次のコードを実行します。

    CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS
    SELECT AlbumName
    FROM [dbo].[Albums]
    WHERE ArtistId = @ArtistId;
    

    同じサーバーでテーブルをクエリしているので、4つの部分からなる名前を使用する必要がないことに注意してください。

    次に、sys.dm_sql_referenced_entities()を実行します リンクサーバー上:

    SELECT 
        referenced_server_name AS [Server],
         referenced_database_name AS [Database],
         referenced_schema_name AS [Schema],
         referenced_entity_name AS [Entity],
         referenced_minor_name AS [Minor],
         referenced_class_desc AS [Class]
    FROM sys.dm_sql_referenced_entities (
        '[dbo].uspGetAlbumsByArtist', 
        'OBJECT');
    

    結果:

    +----------+------------+----------+----------+-----------+------------------+
    | Server   | Database   | Schema   | Entity   | Minor     | Class            |
    |----------+------------+----------+----------+-----------+------------------|
    | NULL     | NULL       | dbo      | Albums   | NULL      | OBJECT_OR_COLUMN |
    | NULL     | NULL       | dbo      | Albums   | AlbumName | OBJECT_OR_COLUMN |
    | NULL     | NULL       | dbo      | Albums   | ArtistId  | OBJECT_OR_COLUMN |
    +----------+------------+----------+----------+-----------+------------------+
    

    この場合、列は結果に含まれます。

    また、サーバーとデータベースの列はすべての行でNULLであることに注意してください。これは、どちらもストアドプロシージャの定義に含まれていないためです。サーバーとデータベースを含むようにストアドプロシージャの定義を変更すると、ここに表示されます。ただし、サーバーは最初の行にのみ表示されます。

    ALTER PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS
    SELECT AlbumName
    FROM [SQLServer007].[Music].[dbo].[Albums]
    WHERE ArtistId = @ArtistId;
    

    結果:

    +--------------+------------+----------+----------+-----------+------------------+
    | Server       | Database   | Schema   | Entity   | Minor     | Class            |
    |--------------+------------+----------+----------+-----------+------------------|
    | SQLServer007 | Music      | dbo      | Albums   | NULL      | OBJECT_OR_COLUMN |
    | NULL         | Music      | dbo      | Albums   | AlbumName | OBJECT_OR_COLUMN |
    | NULL         | Music      | dbo      | Albums   | ArtistId  | OBJECT_OR_COLUMN |
    +--------------+------------+----------+----------+-----------+------------------+
    

    この場合、サーバーの名前はSQLServer007であるため、Homer(他のサーバーからリンクサーバーを作成するときに付けた名前)の代わりにSQLServer007を使用する必要がありました。

    OPENQUERY()を使用することもできます ローカルサーバーに戻って、リンクサーバーに対して実行する場合:

    SELECT * FROM OPENQUERY(
        Homer,
        'SELECT 
        referenced_server_name AS [Server],
         referenced_database_name AS [Database],
         referenced_schema_name AS [Schema],
         referenced_entity_name AS [Entity],
         referenced_minor_name AS [Minor],
         referenced_class_desc AS [Class]
    FROM sys.dm_sql_referenced_entities (
        ''[dbo].uspGetAlbumsByArtist'', 
        ''OBJECT'');'
    );
    

    結果:

    +--------------+------------+----------+----------+-----------+------------------+
    | Server       | Database   | Schema   | Entity   | Minor     | Class            |
    |--------------+------------+----------+----------+-----------+------------------|
    | SQLServer007 | Music      | dbo      | Albums   | NULL      | OBJECT_OR_COLUMN |
    | NULL         | Music      | dbo      | Albums   | AlbumName | OBJECT_OR_COLUMN |
    | NULL         | Music      | dbo      | Albums   | ArtistId  | OBJECT_OR_COLUMN |
    +--------------+------------+----------+----------+-----------+------------------+
    

    この場合、すべての一重引用符をエスケープする必要があることに注意してください。

    また、(OPENQUERY()を使用せずに、分散クエリを介して関数を実行しようとした場合 )、エラーメッセージ4122が表示されます:

    SELECT 
        referenced_server_name AS [Server],
         referenced_database_name AS [Database],
         referenced_schema_name AS [Schema],
         referenced_entity_name AS [Entity],
         referenced_minor_name AS [Minor],
         referenced_class_desc AS [Class]
    FROM [Homer].[Music].[sys].dm_sql_referenced_entities (
        '[dbo].[uspGetAlbumsByArtist]', 
        'OBJECT');
    

    結果:

    Msg 4122, Level 16, State 1, Line 10
    Remote table-valued function calls are not allowed.
    

    1. AndroidwithRoom-外部キーをnull許容に設定する方法

    2. TSQLを使用してデータベース内のすべてのテーブルのリストを取得するにはどうすればよいですか?

    3. SQL Server(T-SQL)でユーザー定義データ型の名前を変更する

    4. 関係なく、IN値のデフォルトの結果を返します