SQL Server には、クエリをリモートで実行する方法が 3 つあります。
OPENQUERY
OPENROWSET
EXECUTE AT
この記事では、これら 3 つの方法について説明します。
OPENQUERY
指定されたパススルー クエリを、指定されたリンク サーバーで実行します。 このサーバーは OLE DB データ ソースです。 クエリでは、FROM
の OPENQUERY
をテーブル名であるかのように使います。 また、OPENQUERY
を INSERT
、UPDATE
、または DELETE
ステートメントのターゲット テーブルとして参照することもできます。 これは OLE DB プロバイダーの機能により制限されます。 クエリからは複数の結果セットが返される場合がありますが、OPENQUERY
からは最初の 1 つだけが返されます。
OPENQUERY
には、事前に追加され構成済みであるリンク サーバーと、リモート サーバーへの要求テキストが必要です。
OPENQUERY
では、オブジェクトにアクセスするために 4 部構成の名前の規則は必要ありません。
OPENROWSET
OLE DB データ ソースからリモート データへのアクセスに必要な、すべての接続情報をインクルードします。 このメソッドは、リンク サーバー内のテーブルにアクセスする代わりに、OLE DB を使用してリモート データに接続しアクセスするアドホック メソッドです。 OLE DB データ ソースへの参照をより頻繁に行う場合は、リンク サーバー、PolyBase、または SQL Server Integration Services (SSIS) やカスタム アプリケーションなどのツールを介した 2 つのデータ ソース間の直接接続を使うことを検討してください。
クエリでは、クエリの FROM
句で OPENROWSET
を使います。 また、INSERT
、UPDATE
、または DELETE
ステートメントのターゲット テーブルとして OPENROWSET
を使うこともできます。これは OLE DB プロバイダーの機能により制限されます。 クエリでは複数の結果セットが返される場合がありますが、OPENROWSET
では最初の 1 つだけが返されます。
OPENROWSET
では、組み込みの BULK
プロバイダーによる一括操作もサポートされ、ファイルのデータを行セットとして読み取り、返すことができます。
追加情報のために、OPENROWSET
では明示的に書き込まれた接続文字列を使います。
EXECUTE AT
リンク サーバーに対して動的 SQL を実行できます。
EXECUTE
呼び出しのパラメーターの 1 つは AT
です。これは、OPENQUERY
と OPENROWSET
の制限をバイパスするように設計されています。
EXECUTE (``<query>``) AT [<linked server>]
は、リモート サーバーから任意の数の結果セットを返すことができる動的 SQL です。
動的 SQL に関するガイダンス
アプリケーションでは動的 SQL コマンドを使わないようにし、動的 SQL コマンドにアクセスできるユーザーに対してアクセス許可を制限してください。
EXECUTE
を使って実行するクエリを構築することは、SQL インジェクション攻撃を介した Web サイトやアプリケーションに対する脆弱性につながるおそれがあります。 詳細については、「 SQL Injection」を参照してください。
パフォーマンスが問題になる場合は、リモート クエリをテストします。
- できるだけ多くのロジックがリモート サーバーで実行されるようにします
- クエリをサポートするために、リモート サーバーのインデックス テーブルのインデックスを適切に確認します
- コードベースでリモート クエリを使うと、データベース コードのバージョン コントロール、および開発環境とテスト環境のメンテナンスが複雑になる点に注意してください
例
A. OPENQUERY を使った SELECT パススルー クエリを実行する
次の例では、OPENQUERY
と共に SELECT パススルー クエリを使って行を選択します。
SELECT *
FROM OPENQUERY ([linkedserver],
'SELECT * FROM AdventureWorksLT.SalesLT.Customer');
B. OPENROWSET を使った SELECT パススルー クエリを実行する
次の例では、OPENROWSET
と共に SELECT
パススルー クエリを使って行を選択します
SELECT a.*
FROM OPENROWSET('MSOLEDBSQL', [linkedserver],
'SELECT * FROM AdventureWorksLT.SalesLT.Customer') AS a;
SQL Server Native Client (SNAC と略されることがよくあります) は、SQL Server 2022 (16.x) と SQL Server Management Studio 19 (SSMS) から削除されました。 SQL Server Native Client OLE DB プロバイダー (SQLNCLI または SQLNCLI11) とレガシ Microsoft OLE DB Provider for SQL Server (SQLOLEDB) はどちらも、新しい開発には推奨されません。 今後は、新しい Microsoft OLE DB Driver (MSOLEDBSQL) for SQL Server に切り替えてください。
C. EXECUTE AT を使った SELECT パススルー クエリを実行する
次の例では、EXECUTE ... AT
と共に SELECT
パススルー クエリを使って行を選択します
EXECUTE ('SELECT * FROM AdventureWorksLT.SalesLT.Customer') AT [linkedserver]
D. 複数の SELECT ステートメントを実行する
次の例では、SELECT
パススルー クエリを使って、複数の結果セットを取得します
EXECUTE ('SELECT TOP 10 * FROM AdventureWorksLT.SalesLT.Customer;
SELECT TOP 10 * FROM AdventureWorksLT.SalesLT.CustomerAddress;') AT [linkedserver];
E. SELECT を実行し、2 つの引数を渡す
次の例では、2 つの引数を指定するパススルー SELECT
を使います
EXECUTE ('SELECT TOP 10 * FROM AdventureWorksLT.SalesLT.Customer
WHERE CustomerID = ? AND LastName = ?', 10, 'Garza') AT [linkedserver];
F. SELECT を実行し、変数を使って 2 つの引数を渡す
次の例では、変数を使って 2 つの引数を指定するパススルー SELECT を使います
DECLARE @CustomerID AS INT
DECLARE @LastName AS VARCHAR(100)
SET @CustomerID = 10
SET @LastName = 'Garza'
EXECUTE ('SELECT TOP 10 * FROM AdventureWorksLT.SalesLT.Customer
WHERE CustomerID = ? AND LastName = ?', @CustomerID, @LastName) AT [linkedserver];
G. リンク サーバーを使って EXECUTE で DDL ステートメントを実行する
次の例では、リンク サーバーで DDL ステートメントを使います
EXECUTE (
'USE TempDB
IF OBJECT_ID(''dbo.Table1'') IS NOT NULL
DROP TABLE dbo.Table1
CREATE TABLE dbo.Table1
(
Column1 INT
)' ) AT [linkedserver];
テストが完了したら、作成したオブジェクトをクリーンアップします
EXECUTE (
'USE TempDB
IF OBJECT_ID(''dbo.Table1'') IS NOT NULL
DROP TABLE dbo.Table1'
) AT [linkedserver];
EXECUTE sp_dropserver 'linkedserver'
その他の例
INSERT...SELECT * FROM OPENROWSET(BULK...)
のその他の使用例については、次のトピックをご覧ください。
- XML ドキュメントの一括インポートと一括エクスポートの例 (SQL Server)
- データの一括インポート時の ID 値の保持 (SQL Server)
- 一括インポート中の NULL の保持または既定値の使用 (SQL Server)
- データの一括インポートでのフォーマット ファイルの使用 (SQL Server)
- 文字形式を使用したデータのインポートまたはエクスポート (SQL Server)
- フォーマット ファイルを使用したテーブル列のスキップ (SQL Server)
- フォーマット ファイルを使用したデータ フィールドのスキップ (SQL Server)
- フォーマット ファイルを使用したテーブル列とデータ ファイル フィールドのマッピング (SQL Server)
参照
- DELETE (Transact-SQL)
- FROM (Transact-SQL)
- データの一括インポートと一括エクスポート (SQL Server)
- INSERT (Transact-SQL)
- OPENDATASOURCE (Transact-SQL)
- OPENQUERY (Transact-SQL)
- OPENROWSET (Transact-SQL)
- SELECT (Transact-SQL)
- sp_addlinkedserver (Transact-SQL)
- sp_serveroption (Transact-SQL)
- UPDATE (Transact-SQL)
- WHERE (Transact-SQL)