SQL Serverの2つの異なるサーバーからのデータの選択


363

SQL Serverの2つの異なるサーバー上にある2つの異なるデータベースから同じクエリ内のデータを選択するにはどうすればよいですか?


6
エリックとレイジングブルからの回答は非常に便利です。これを使用して、DEVからPRODに大量のデータをコピーして、5時間から18時間、17秒までの時間を削減できました。
Chris Aldrich

@Eric、わずかにあいまいな質問を編集して170問の質問にすることに対する称賛:)
Eric Wu

回答:


345

探しているのはリンクサーバーです。オブジェクトエクスプローラーのツリーの次の場所からSSMSでそれらにアクセスできます。

Server Objects-->Linked Servers

または、sp_addlinkedserverを使用できます。

設定する必要があるのは1つだけです。それができたら、他のサーバーのテーブルを次のように呼び出すことができます。

select
    *
from
    LocalTable,
    [OtherServerName].[OtherDB].[dbo].[OtherTable]

所有者は常にdboであるとは限らないため、使用するスキーマに必ず置き換えてください。


13
リンクサーバーなしでそれを行うことができますか?
Steam

5
@ Eric、SSMSのサーバーオブジェクトはどこにありますか?
Tsahi Asher 2014

9
@TsahiAsher-サーバーに接続すると、サーバーオブジェクトはオブジェクトエクスプローラーのツリー内のフォルダーになります。
Eric

2
不明な場合は、スキーマを省略してデフォルトを使用することもできます。たとえば[OtherServerName].[OtherDB]..[OtherTable]、わかっている場合はそれを含めるのが最善です。
Tom Bowers

92

リンクサーバーを使用して実行できます。

通常、リンクサーバーは、データベースエンジンがSQL Serverの別のインスタンス、またはOracleなどの別のデータベース製品のテーブルを含むTransact-SQLステートメントを実行できるように構成されています。Microsoft AccessやExcelなど、多くの種類のOLE DBデータソースをリンクサーバーとして構成できます。

リンクサーバーには次の利点があります。

  • SQL Serverの外部からデータにアクセスする機能。
  • 企業全体の異種データソースに対して分散クエリ、更新、コマンド、およびトランザクションを発行する機能。
  • 同様に多様なデータソースに対処する機能。

リンクサーバーの詳細については、こちらをご覧ください。

リンクサーバーを作成するには、次の手順に従います。

  1. サーバーオブジェクト->リンクサーバー->新しいリンクサーバー

  2. リモートサーバー名を指定します。

  3. リモートサーバーの種類(SQLサーバーまたはその他)を選択します。

  4. [セキュリティ]-> [このセキュリティコンテキストを使用して作成]を選択し、リモートサーバーのログインとパスワードを入力します。

  5. [OK]をクリックすると完了です。

リンクサーバーを作成するための簡単なチュートリアルを次に示します。

または

クエリを使用してリンクサーバーを追加できます。

構文:

sp_addlinkedserver [ @server= ] 'server' [ , [ @srvproduct= ] 'product_name' ] 
     [ , [ @provider= ] 'provider_name' ]
     [ , [ @datasrc= ] 'data_source' ] 
     [ , [ @location= ] 'location' ] 
     [ , [ @provstr= ] 'provider_string' ] 
     [ , [ @catalog= ] 'catalog' ] 

sp_addlinkedserverの詳細をご覧ください

リンクサーバーは一度だけ作成する必要があります。リンクサーバーを作成したら、次のようにクエリを実行できます。

select * from LinkedServerName.DatabaseName.OwnerName.TableName

注:サーバー名をホスト名/ポート以外にする方法については、こちらをご覧ください。
Richard

1
ここで、sp_addlinkedserverに問題がある場合のヒントを示します。ダイアログでサーバーを作成します-サーバーが機能することを確認してから、接続を右クリックしてスクリプトを選択します。リンクサーバーAS create
Richard Housham

25
SELECT
        *
FROM
        [SERVER2NAME].[THEDB].[THEOWNER].[THETABLE]

リンクサーバーの使用についても確認できます。リンクサーバーは、DB2プラットフォームなど、他の種類のデータソースにもなります。これは、SQL Server TSQLまたはSproc呼び出しからDB2にアクセスしようとする1つの方法です...


2
このメソッドは常に機能しますか?失敗する可能性のあるシナリオは何ですか?
Steam

3
これは私の環境で失敗することを確認しました、エラーはaddlinkedserverを使用する必要があることを示しています
gorlaz

1
リンクサーバーを使用しなくても、これは誰でも機能しますか?
Doug S

テストとエラーの受信はCould not find server '88.208.229.164' in sys.servers. Verify that the correct server name was specified. If necessary, execute the stored procedure sp_addlinkedserver to add the server to sys.servers.
WhatsThePoint

22

2つの異なるデータベースにわたるクエリは、分散クエリです。ここにいくつかのテクニックと長所と短所のリストがあります:

  1. リンクサーバー: SQL Serverレプリケーションよりも幅広いデータソースへのアクセスを提供
  2. リンクサーバー:レプリケーションでサポートされていない、またはアドホックアクセスが必要なデータソースに接続します
  3. リンクサーバー: OPENDATASOURCEまたはOPENROWSETよりも高いパフォーマンス
  4. OPENDATASOURCEおよびOPENROWSET関数:アドホックベースでデータソースからデータを取得するのに便利です。OPENROWSETにはBULK機能もあります。これは、扱いにくいフォーマットファイルを必要とする場合としない場合があります。
  5. OPENQUERY:変数をサポートしていません
  6. すべて T-SQLソリューションです。実装と設定が比較的簡単
  7. すべては、パフォーマンスとスケーラビリティに影響を与える可能性があるソースと宛先間の接続に依存しています

OPENQUERYには依然としてリンクサーバーが必要ですが、OPENDATASOURCEには必要ありません
CJ

16

これを試して:

SELECT * FROM OPENROWSET('SQLNCLI', 'Server=YOUR SERVER;Trusted_Connection=yes;','SELECT * FROM Table1') AS a
UNION
SELECT * FROM OPENROWSET('SQLNCLI', 'Server=ANOTHER SERVER;Trusted_Connection=yes;','SELECT * FROM Table1') AS a

16

これらはすべてすばらしい答えですが、これは欠落しており、独自の強力な用途があります。おそらくそれはOPが望んだものに適合しないかもしれませんが、質問は曖昧であり、私は他の人がここで彼らのやり方を見つけるかもしれないと感じています。基本的に、1つのウィンドウを使用して複数のサーバーに対してクエリを同時に実行できます。方法は次のとおりです。

SSMSで登録済みサーバーを開き、ローカルサーバーグループの下に新しいサーバーグループを作成します

このグループの下に、クエリを実行するサーバーごとに新しいサーバー登録を作成します。DB名が異なる場合は、プロパティでそれぞれにデフォルトを設定してください。

最初のステップで作成したグループに戻り、右クリックして[新しいクエリ]を選択します。新しいクエリウィンドウが開き、実行したクエリはグループ内の各サーバーで実行されます。結果は、レコードがどのサーバーからのものかを示す追加の列名が付いた単一のデータセットで表示されます。ステータスバーを使用すると、サーバー名が複数に置き換えられます


2
これは、クエリがすべてのデータベースで同じテーブルを使用すると想定しているようです。(これはsys.tablesのような標準のテーブルでは問題ありませんが、dbo.mycustomersのようなカスタムメイドのテーブルではそうではありません)
Dennis Jaheruddin 2017年

「2つの異なるデータベースからの同じクエリ」であることを考えると、同じテーブルを持つ可能性が非常に高くなります。しかし、はい、私はこの方法を、複数のサーバーに格納されている運用システムとMSDBテーブルのクエリに日常的に使用しています。
ポール、

実際に本当にクールな機能。欠点は、結果セットのスキーマが一致する必要があることです。これは、クエリを2回実行し、それらすべてを同時にマージするためです。結果セットをJOINできず、セットを個別に評価するために構築する必要があったとしても、リンクサーバーの場合と同様に、SQL自体の中でサーバーを参照できればすばらしいでしょう。
Kross

1
@Krossのようなものです。#outputテーブルを作成し、@@ SERVERNAMEに基づいてロジックを実行し、データを#outputに入力して、selectで終了します。情報のレベル/列が異なるSQL2000マシンとSQL2008R2マシンの組み合わせからログ情報をクエリするために同様のことを行いましたが、@@ SERVERNAMEの代わりにサーバーバージョン変数を使用していました。
ポール

9

SQL_server 2008をリモートサーバーでホストされているSQL_server 2016に接続するときに同じ問題が発生しました。他の答えは私には簡単にうまくいきませんでした。他の誰かに役立つかもしれないと思うので、ここに私の微調整したソリューションを書きます。

リモートIPデータベース接続の拡張回答:

手順1:サーバーをリンクする

EXEC sp_addlinkedserver @server='SRV_NAME',
   @srvproduct=N'',
   @provider=N'SQLNCLI',   
   @datasrc=N'aaa.bbb.ccc.ddd';

EXEC sp_addlinkedsrvlogin 'SRV_NAME', 'false', NULL, 'your_remote_db_login_user', 'your_remote_db_login_password'

...ここSRV_NAMEで発明された名前です。これを使用して、クエリからリモートサーバーを参照します。aaa.bbb.ccc.dddSQLserver DBをホストしているリモートサーバーのIPアドレスです。

ステップ2:クエリを実行する たとえば、

SELECT * FROM [SRV_NAME].your_remote_db_name.dbo.your_table

...以上です!

構文の詳細:sp_addlinkedserverおよびsp_addlinkedsrvlogin


4

あるサーバーから別のサーバーへのリンクサーバー定義を作成し(これを行うにはSAが必要です)、4部構成の名前でそれらを参照するだけです(BOLを参照)。


4

サーバー2008:

SSMSでserver1.DB1に接続して、次のことを試してください。

SELECT  * FROM
[server2].[DB2].[dbo].[table1]

他の人が指摘したように、それが機能しない場合は、サーバーがリンクされていないことが原因です。

エラーが発生します:

sys.serversにサーバーDB2が見つかりませんでした。正しいサーバー名が指定されていることを確認してください。必要に応じて、ストアドプロシージャsp_addlinkedserverを実行して、サーバーをsys.serversに追加します。

サーバーを追加するには:

参照:sp_addlinkedserverリンクを使用してサーバーを追加するには[1]:sp_addlinkedserverを使用してサーバーを追加するには

sys.serversの内容を確認するには、クエリを実行します。

SELECT * FROM [sys].[servers]


2

@ Super9がデータプロバイダーSQLOLEDBでSQL Server認証を使用するOPENDATASOURCEについて語ったように 。1つのテーブルのコードスニペットが、現在コードが実行されている現在のサーバーデータベースにあり、別のテーブルが他のサーバー'192.166.41.123'にあることをここに投稿しています。

SELECT top 2 * from dbo.tblHamdoonSoft  tbl1 inner JOIN  
OpenDataSource('SQLOLEDB','Data Source=192.166.41.123;User ID=sa;Password=hamdoonsoft')
.[TestDatabase].[dbo].[tblHamdoonSoft1] tbl2 on tbl1.id = tbl2.id

0
sp_addlinkedserver('servername')

だから、このようになります-

select * from table1
unionall
select * from [server1].[database].[dbo].[table1]

0

これは古い質問であることは知っていますが、同義語を使用しています。おそらくクエリはデータベースサーバーA内で実行され、サーバーAに存在しないデータベースサーバーB内のテーブルを検索します。次に、サーバーBからテーブルを呼び出すデータベースにシノニムを追加します。クエリは、スキーマまたは異なるデータベース名を含め、通常どおりにテーブル名を呼び出すだけで機能します。

同義語は一種のリンクなので、サーバーをリンクする必要はありません。


1
さて、この文脈における「同義語」とは何ですか?
オスカーベルクグレン

これは、別のデータベースの基本オブジェクトを参照するデータベースオブジェクトです。詳細:docs.microsoft.com/en-us/sql/relational-databases/synonyms/...
ニクラスHenricson

その機能については知りませんでした。ただし、リンクサーバーの必要性を回避するとも述べていますが、その方法はわかりません。シノニム自体はそれ自体、シノニムであるように見え、それ自体は特定のリモート処理能力を含みません。docs.microsoft.com/en-us/sql/t-sql/statements/…の例Bでは、シノニムから参照する前にリンクサーバーを作成しています。
オスカーベルクグレン

確かに、データベースは同じサーバー環境にあると想定しました。もちろん、データベースが互いに離れている場合は、常にデータベースをリンクする必要があります。データベース間の関係でアクセスする他の方法はありません。
Niklas Henricson、2018年

0

サーバーオブジェクト--->リンクサーバー--->新しいリンクサーバー

リンクサーバーで他のサーバーのサーバー名またはIPアドレスを書き込み、SQL Serverを選択します。セキュリティで選択(このセキュリティコンテキストを使用して作成)他のサーバーのログインとパスワードを書き込みます

接続されてから使用

Select * from [server name or ip addresses ].databasename.dbo.tblname

0

リンクサーバーを追加するための簡素化されたソリューション

最初のサーバー

EXEC sp_addlinkedserver @server='ip,port\instancename'

2回目のログイン

EXEC sp_addlinkedsrvlogin 'ip,port\instancename', 'false', NULL, 'remote_db_loginname', 'remote_db_pass'

リンクされたローカルデータベースからクエリを実行する

INSERT INTO Tbl (Col1, Col2, Col3)
SELECT Col1, Col2, Col3
FROM [ip,port\instancename].[linkedDBName].[linkedTblSchema].[linkedTblName]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.