SQL Server では、クエリをリモートで実行する 3 つの方法があります。
OPENQUERYOPENROWSETEXECUTE AT
この記事では、これら 3 つの方法について説明します。
OPENQUERY
指定されたパススルー クエリを、指定されたリンク サーバーで実行します。 このサーバーは OLE DB データ ソースです。 クエリでは、テーブル名のようにOPENQUERYでFROMを使用します。
OPENQUERY、INSERT、またはUPDATEステートメントのターゲット テーブルとしてDELETEを参照することもできます。 これは OLE DB プロバイダーの機能により制限されます。 クエリは複数の結果セットを返す場合がありますが、 OPENQUERY は最初の結果セットのみを返します。
OPENQUERY には、事前に追加および構成されたリンク サーバーと、リモート サーバーへの要求テキストが必要です。
OPENQUERY では、オブジェクトにアクセスするために 4 つの部分から構成される名前規則は必要ありません。
OPENROWSET
OLE DB データ ソースからリモート データにアクセスするために必要なすべての接続情報が含まれます。 このメソッドは、リンク サーバー内のテーブルにアクセスする代わりに、OLE DB を使用してリモート データに接続しアクセスするアドホック メソッドです。 OLE DB データ ソースへの参照を頻繁に行う場合は、SQL Server Integration Services (SSIS) やカスタム アプリケーションなどのツールを使用して、リンク サーバー、PolyBase、または 2 つのデータ ソース間の直接接続を使用することを検討してください。
クエリでは、クエリの OPENROWSET 句でFROMを使用します。 OLE DB プロバイダーの機能に従って、 OPENROWSET を INSERT、 UPDATE、または DELETE ステートメントのターゲット テーブルとして使用することもできます。 クエリでは複数の結果セットが返される場合がありますが、OPENROWSET では最初の 1 つだけが返されます。
OPENROWSET また、組み込みの BULK プロバイダーを介した一括操作もサポートしています。これにより、ファイルからのデータを行セットとして読み取って返すことができます。
詳細については、明示的に書き込まれた接続文字列を使用 OPENROWSET 。
指定された場所で実行する
リンク サーバーに対して動的 SQL を実行できるようにします。
EXECUTE呼び出しのパラメーターの 1 つはATであり、OPENQUERYとOPENROWSETの制限をバイパスするように設計されています。
EXECUTE (``<query>``) AT [<linked server>] は、リモート サーバーから任意の数の結果セットを返すことができる動的 SQL です。
動的 SQL のガイダンス
アプリケーションで動的 SQL コマンドを使用しないようにし、動的 SQL コマンドにアクセスできるユーザーに対するアクセス許可を制限します。
EXECUTEを介して実行するクエリを構築すると、SQL インジェクション攻撃を介して Web サイトやアプリケーションに脆弱性を生み出す可能性があります。 詳細については、「 SQL Injection」を参照してください。
パフォーマンスに問題がある場合は、リモート クエリをテストします。
- リモート サーバーで可能な限り多くのロジックが実行されるようにする
- クエリをサポートするために、リモート サーバー インデックス テーブルのインデックスを適切に確認する
- コードベースでリモート クエリを使用すると、データベース コードのバージョン管理と開発環境とテスト環境のメンテナンスが複雑になることに注意してください
例示
A。 OPENQUERY を使用して SELECT パススルー クエリを実行する
次の例では、パススルー SELECT クエリを使用して、 OPENQUERYの行を選択します。
SELECT *
FROM OPENQUERY ([linkedserver],
'SELECT * FROM AdventureWorksLT.SalesLT.Customer');
B. OPENROWSET を使用して SELECT パススルー クエリを実行する
次の例では、パススルークエリ SELECT を使用して OPENROWSET の行を選択します。
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 パススルー クエリを実行する
次の例では、パススルー SELECT クエリを使用して、EXECUTE ... ATで指定された行を選択します。
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)
- フォーマット ファイルを使用してテーブル列を Data-File フィールドにマップする (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)
- 更新(Transact-SQL)
- WHERE (Transact-SQL)