次の方法で共有


Microsoft SQL Server 分散クエリ: OLE DB 接続

この記事では、Microsoft SQL Server クエリ プロセッサと OLE DB プロバイダーのやり取りによって分散クエリと異種クエリがどのように実現されるかについて説明します。 主に OLE DB プロバイダーの開発者を対象としており、OLE DB の仕様を確実に理解していることを前提としています。 SQL Server クエリ プロセッサと OLE DB プロバイダーの間の OLE DB インターフェイスに重点を置いており、分散クエリ機能自体には重点を置いていません。 分散クエリ機能の詳細については、「リンク サーバー」を参照してください。

概要と用語

Microsoft SQL Server では、分散クエリを使用することで、SQL Server ユーザーが、SQL Server をベースにしたサーバーの外部にあるデータ、つまり SQL Server を実行している他のサーバー内、または OLE DB インターフェイスを公開している他のデータ ソース内のいずれかにあるデータにアクセスできます。 OLE DB によって、異種データ ソースから表形式データへの統一されたアクセス方法が提供されます。

この記事で使用する分散クエリとは、1 つ以上の外部 OLE DB データ ソースにあるテーブルや行を参照する SELECTINSERTUPDATE、または DELETE ステートメントのことです。

リモート テーブルとは、OLE DB データ ソースに格納されており、クエリを実行する SQL Server が実行されているサーバーの外部にあるテーブルのことです。 分散クエリでは、1 つ以上のリモート テーブルにアクセスします。

OLE DB プロバイダーのカテゴリ

以下は、SQL Server 分散クエリ実行の観点から、OLE DB プロバイダーを機能に基づいて分類したものです。 定義されているように、これらは相互に排他的ではありません。特定のプロバイダーが以下の複数のカテゴリに属することができます。

  • SQL コマンド プロバイダー

  • インデックス プロバイダー

  • シンプル テーブル プロバイダー

  • SQL 以外のコマンド プロバイダー

SQL コマンド プロバイダー

SQL Server によって認識される SQL 標準言語を使用して Command オブジェクトをサポートするプロバイダーは、このカテゴリに属します。 特定の OLE DB プロバイダーが SQL Server によって SQL コマンド プロバイダーとして扱われるための特定の要件は、次のとおりです。

  • Command オブジェクトと、そのすべての必須 OLE DB インターフェイス (ICommandICommandTextIColumnsInfoICommandProperties、および IAccessor) をプロバイダーでサポートする必要があります。

  • プロバイダーによってサポートされる SQL 言語は、少なくとも SQL Subminimum である必要があります。 その言語は、DBPROP_SQLSUPPORT プロパティを使用してプロバイダーによって報告される必要があります。

SQL コマンド プロバイダーの例として、Microsoft OLE DB Provider for SQL Server と Microsoft OLE DB Provider for ODBC があります。

インデックス プロバイダー

インデックス プロバイダーとは、OLE DB に従ってインデックスをサポートおよび公開し、インデックス ベースでベース テーブルを参照できるようにするプロバイダーです。 特定の OLE DB プロバイダーが SQL Server によってインデックス プロバイダーとして扱われるための特定の要件は、次のとおりです。

  • TABLES、COLUMNS、INDEXES の各スキーマ行セットを含む IDBSchemaRowset インターフェイスをプロバイダーでサポートする必要があります。

  • IOpenRowset を使用して (インデックス名および対応するベース テーブル名を指定することによって) インデックスに基づいて行セットを開くことを、プロバイダーでサポートする必要があります。

  • Index オブジェクトによって、そのすべての必須インターフェイス (IRowsetIRowsetIndexIAccessorIColumnsInfoIRowsetInfo、および IConvertTypes) がサポートされている必要があります。

  • インデックス付きのベース テーブルに対して (IOpenRowset を使用して) 開かれた行セットでは、ブックマークに基づいて行に位置付けるための IRowsetLocate インターフェイスがサポートされている必要があります。

OLE DB プロバイダーが上記の要件を満たしている場合、ユーザーは Index As Access Path プロバイダー オプションを設定して、SQL Server がプロバイダーのインデックスを使用してクエリを評価できるようにすることができます。 既定では、このオプションが設定されない限り、SQL Server でプロバイダーのインデックスは使用されません。

SQL Server では、SQL Server から OLE DB プロバイダーへのアクセス方法に影響するさまざまなオプションがサポートされています。 SQL Server Enterprise Manager の Linked Server Properties ダイアログ ボックスを使用して、これらのオプションを設定できます。

シンプル テーブル プロバイダー

IOpenRowset インターフェイスを介してベース テーブルに対して行セットを開くことを公開するプロバイダーです。 このようなプロバイダーは、SQL コマンド プロバイダーでもインデックス プロバイダーでもありません。そうではなく、SQL Server 分散クエリで使用できる最もシンプルなプロバイダーのクラスです。

このようなプロバイダーに対して、SQL Server によるテーブル スキャンは分散クエリの評価中にのみ実行できます。

SQL 以外のコマンド プロバイダー

Command オブジェクトとその必須インターフェイスをサポートしているが、SQL Server で認識される SQL 標準言語をサポートしていないプロバイダーは、このカテゴリに分類されます。

SQL 以外のコマンド プロバイダーの 2 つの例として、Microsoft OLE DB Provider for Indexing Service と、Microsoft OLE DB Provider for Microsoft Active Directory Service があります。

Transact-SQL サブセット

必須の OLE DB インターフェイスをプロバイダーでサポートしている場合、次の各クラスの Transact-SQL ステートメントが分散クエリ用にサポートされます。

  • リモート テーブルを対象テーブルとする SELECT INTO ステートメントを除き、すべての SELECT ステートメントを使用できます。

  • 挿入に必要なインターフェイスをプロバイダーでサポートしている場合は、リモート テーブルに対して INSERT ステートメントを使用できます。 INSERT の OLE DB 要件の詳細については、この記事で後述する「INSERT ステートメント」を参照してください。

  • プロバイダーが、指定されたテーブルに対する OLE DB インターフェイス要件を満たしている場合、リモート テーブルに対して UPDATE ステートメントと DELETE ステートメントを使用できます。 リモート テーブルを更新または削除できる OLE DB インターフェイスの要件と条件については、この記事で後述する「UPDATE ステートメントと DELETE ステートメント」を参照してください。

カーソルのサポート

必要な OLE DB 機能をプロバイダーでサポートしている場合は、分散クエリに対してスナップショット カーソルとキーセット カーソルの両方がサポートされます。 動的カーソルは、分散クエリに対してはサポートされていません。 分散クエリに対する動的カーソルのユーザー要求は、キーセット カーソルにダウングレードされます。

スナップショット カーソルはカーソルを開いたときに設定され、結果セットは変更されません。基になるテーブルに対する更新、挿入、削除は、カーソルに反映されません。

キーセット カーソルはカーソルを開いたときに設定され、結果セットはカーソルの有効期間全体にわたって未変更のままです。 ただし、基になるテーブルに対する更新と削除は、行がアクセスされるときにカーソル内で参照可能になります。 カーソルのメンバーシップに影響する可能性がある基になるテーブルへの挿入は、参照可能になりません。

リモート テーブルに対する更新および削除の条件をプロバイダーが満たしている場合は、分散クエリ上で定義されてリモート テーブルを参照するカーソルによって、リモート テーブルを更新または削除できます (たとえば、テーブルの UPDATE | DELETE <remote-table>WHERE CURRENT OF <cursor-name>。 詳細については、この記事で後述する「UPDATE ステートメントと DELETE ステートメント」を参照してください。

キーセット カーソルのサポート要件

キーセット カーソルは、Transact-SQL 構文のすべての要件が満たされていて、次のいずれかが存在する場合に、分散クエリでサポートされます。

  • OLE DB プロバイダーによって、すべてのリモート テーブル上の再利用可能なブックマークがクエリ内でサポートされている。 再利用可能なブックマークは、特定のテーブル上の行セットから使用でき、同じテーブルの別の行セット上で使用できます。 再利用可能なブックマークのサポートは、IDBSchemaRowset の TABLES_INFO スキーマ行セットを使用して、BOOKMARK_DURABILITY 列を BMK_DURABILITY_INTRANSACTION またはより高い持続性に設定することによって示されます。

  • すべてのリモート テーブルで IDBSchemaRowset インターフェイスの INDEXES 行セットを通じて一意のキーが公開されている。 UNIQUE 列が VARIANT_TRUE に設定されたインデックス エントリが必要です。

キーセット カーソルは、OpenQuery 関数を含む分散クエリに対してはサポートされていません。

更新可能なキーセット カーソルの必要条件

リモート テーブルは、分散クエリで定義されたキーセット カーソルを使用して更新または削除できます (たとえば、UPDATE | DELETE <remote-table>WHERE CURRENT OF <cursor-name>)。 次に、更新可能なカーソルが分散クエリに許可される条件を示します。

  • 更新可能なカーソルは、プロバイダーがリモート テーブルに対する更新と削除の条件も満たしている場合に許可されます。 詳細については、この記事で後述する「UPDATE ステートメントと DELETE ステートメント」を参照してください。

  • すべての更新可能なキーセット カーソル操作は、読み取り繰り返し可能の分離レベルまたはそれより高い分離レベルを持つユーザー定義のトランザクション内に存在する必要があります。 さらに、プロバイダーで、ITransactionJoin インターフェイスを使用して分散トランザクションをサポートする必要があります。

OLE DB プロバイダーの相互作用フェーズ

すべての分散クエリの実行シナリオに共通する 6 つの操作があります。

  • 接続の確立およびプロパティ取得の操作では、SQL Server が OLE DB プロバイダーに接続する方法と、使用されるプロバイダーのプロパティを示します。

  • テーブル名の解決およびメタデータ取得操作では、SQL Server によってリモート テーブル名 (リンク サーバー ベースの名前またはアドホック名という 2 つの方法のいずれかで指定) がどのようにプロバイダー内の適切なデータ オブジェクトに解決されるかを示します。 これには、分散クエリをコンパイルおよび最適化するためにプロバイダーから SQL Server に取得されるテーブル メタデータも含まれます。

  • トランザクション管理操作では、OLE DB プロバイダーとのトランザクションに関連したすべての操作を指定します。

  • データ型の処理操作では、分散クエリの処理中に SQL Server で OLE DB プロバイダーからデータを使用するとき、または OLE DB プロバイダーにデータをエクスポートするときに、SQL Server によって OLE DB データ型がどのように処理されるかを示します。

  • エラー処理操作では、SQL Server がプロバイダーからの拡張エラー情報を使用する方法を示します。

  • セキュリティ操作では、SQL Server のセキュリティとプロバイダーのセキュリティがどのように相互作用するかを指定します。

接続の確立とプロパティの取得

SQL Server では 2 つのリモート データ オブジェクト名前付け規則がサポートされています。リンク サーバー ベースの 4 部構成の名前と、OPENROWSET 関数を使用したアドホック名です。

リンク サーバー ベースの名前

リンク サーバーは、OLE DB データ ソースに対する抽象化として機能します。 リンク サーバー ベースの名前は 4 部構成の名前で、形式は、<linked-server>.<catalog>. <schema>.<object> (<linked-server> はリンク サーバーの名前) です。 SQL Server では、<linked-server> を解釈することで、OLE DB プロバイダーと、そのプロバイダーに対してデータ ソースを識別する接続属性が派生されます。 名前を構成する他の 3 つの部分は、特定のリモート テーブルを識別するために、OLE DB データ ソースによって解釈されます。 :::

アドホック名

アドホック名は、OPENROWSET 関数または OPENDATASOURCE 関数に基づく名前です。 これには、分散クエリでリモート テーブルが参照されるたびに、すべての接続情報 (使用する OLE DB プロバイダー、データ ソースを識別するために必要な属性、ユーザー ID、パスワード) が含まれます。

既定では、sysadmin ロールのメンバーを除き、アドホック名を使用することはできません。 OLE DB プロバイダーに対してアドホック名を使用するには、プロバイダー オプション DisallowAdhocAccess0 に設定する必要があります。

リンク サーバー名が使用されている場合、SQL Server によって、リンク サーバーの定義から OLE DB プロバイダー名とプロバイダーの初期化プロパティが抽出されます。 アドホック名が使用されている場合は、同じ情報が OPENROWSET 関数の引数から SQL Server によって抽出されます。

4 部構成の名前とアドホック名ベースの構文を使用してリンク サーバーを設定する方法の詳細については、「リンク サーバーの作成」を参照してください。

OLE DB プロバイダーへの接続

次に示すのは、SQL Server から OLE DB プロバイダーへの接続時に SQL Server によって実行される手順の概要です。

  1. SQL Server によってデータ ソース オブジェクトが作成されます。

    SQL Server で、プロバイダーの ProgID を使用して、そのプロバイダーのデータ ソース オブジェクト (DSO) がインスタンス化されます。 ProgID では、リンク サーバー構成の provider_name パラメーターとして指定するか、アドホック名の場合は OPENROWSET 関数の最初の引数として指定します。

    SQL Server で、OLE DB サービス コンポーネント インターフェイス IDataInitialize を使用して、プロバイダーの DSO がインスタンス化されます。 これにより、サービス コンポーネント マネージャーで、プロバイダーのネイティブ機能を上回る、スクロールや更新のサポートなどのサービスを集約できます。 さらに、IDataInitialize を使用してプロバイダーをインスタンス化すると、OLE DB サービス コンポーネントでプロバイダーへの接続をプールできるようになり、接続と初期化のオーバーヘッドの一部が減少します。

    特定のプロバイダーを SQL Server と同じプロセスで、または独自のプロセスでインスタンス化されるように構成できます。 別のプロセスでインスタンス化すると、SQL Server のプロセスがプロバイダーでのエラーから保護されます。 同時に、SQL Server からプロセス外の OLE DB 呼び出しをマーシャリングすることに関連したパフォーマンスのオーバーヘッドが発生します。 Allow In Process プロバイダー オプションを設定することにより、プロバイダーをプロセス内またはプロセス外でインスタンス化されるように構成できます。 詳細については、プロバイダーのオプションの設定に関する記事を参照してください。

    OLE DB サービス コンポーネントとセッション プールの詳細については、プロバイダーの要件に関する OLE DB のドキュメントを参照してください。

  2. データ ソースが初期化されます。

    DSO が作成された後、サーバー構成オプション IDBProperties が 0 よりも大きい場合は、remote login timeout インターフェイスによって DBPROP_INIT_TIMEOUT 初期化プロパティが設定されます。これは必須プロパティです。

    これらのプロパティが設定されるのは、リンク サーバー定義において、または OPENROWSET 関数の 2 番目の引数において、指定されているか暗黙的に示されている場合です。

    • DBPROP_INIT_PROVIDERSTRING

    • DBPROP_INIT_DATASOURCE

    • DBPROP_INIT_LOCATION

    • DBPROP_INIT_CATALOG

    • DBPROP_AUTH_USERID

    • DBPROP_AUTH_PASSWORD

    これらのプロパティが設定された後、指定されたプロパティを使用して DSO を初期化するために、IDBInitialize::Initialize が呼び出されます。

  3. SQL Server によってプロバイダー固有の情報が収集されます。

    SQL Server によって、分散クエリ評価で使用されるいくつかのプロバイダー プロパティが収集されます。これらのプロパティは、IDBProperties::GetProperties を呼び出すことによって取得されます。 これらのプロパティはすべてオプションです。ただし、関連するすべてのプロパティをサポートすることで、SQL Server がプロバイダーの機能を最大限に活用できるようになります。 たとえば、SQL Server からプロバイダーにクエリを送信できるかどうかを判別するには、DBPROP_SQLSUPPORT が必要です。 このプロパティがサポートされていない場合、SQL Server ではリモート プロバイダーが (SQL コマンド プロバイダーであったとしても) SQL コマンド プロバイダーとして使用されません。 次の表の「既定値」列は、プロパティがプロバイダーでサポートされていない場合に、SQL Server によって想定される値を示しています。

プロパティ 規定値 使用
DBPROP_DBMSNAME なし エラー メッセージに使用されます。
DBPROP_DBMSVER なし エラー メッセージに使用されます。
DBPROP_PROVIDERNAME なし エラー メッセージに使用されます。
DBPROP_PROVIDEROLEDBVER1 1.5 2.0 機能が使用できるかどうかを判別するために使用されます。
DBPROP_CONCATNULLBEHAVIOR なし プロバイダーの NULL 連結動作が SQL Server の動作と同じかどうかを判別するために使用されます。
DBPROP_NULLCOLLATION なし NULLCOLLATION が SQL Server インスタンスの null 照合順序の動作と一致する場合にのみ、並べ替え/インデックス使用を許可します。
DBPROP_OLEOBJECTS なし ラージ データ オブジェクト列用の構造化ストレージ インターフェイスをプロバイダーがサポートしているかどうかを判別します。
DBPROP_STRUCTUREDSTORAGE なし ラージ オブジェクト型に対して、(ILockBytesIstream、および ISequentialStream のうち) どの構造化ストレージ インターフェイスがサポートされているかを判別します。
DBPROP_MULTIPLESTORAGEOBJECTS いいえ 複数のラージ オブジェクト列を同時に開くことができるかどうかを判別します。
DBPROP_SQLSUPPORT なし SQL クエリをプロバイダーに送信できるかどうかを判別します。
DBPROP_CATALOGLOCATION DBPROPVAL_CL_START マルチパート テーブル名を作成するために使用されます。
SQLPROP_DYNAMICSQL いいえ SQL Server 固有のプロパティ: VARIANT_TRUE が返された場合は、パラメーター化クエリの実行で ? パラメーター マーカーがサポートされることを示します。
SQLPROP_NESTEDQUERIES いいえ SQL Server 固有のプロパティ: VARIANT_TRUE が返された場合、SELECT 句内の入れ子になった FROM ステートメントをプロバイダーでサポートしていることを示します。
SQLPROP_GROUPBY いいえ SQL Server 固有のプロパティ: VARIANT_TRUE が返された場合、SQL-92 標準の指定どおりに SELECT ステートメント内の GROUP BY 句をプロバイダーでサポートしていることを示します。
SQLPROP_DATELITERALS いいえ SQL Server 固有のプロパティ: VARIANT_TRUE が返された場合、SQL Server Transact-SQL 構文に従って datetime リテラルをプロバイダーでサポートしていることを示します。
SQLPROP_ANSILIKE いいえ SQL Server 固有のプロパティ: このプロパティは、SQL の最小限のレベルをサポートするプロバイダーにとって重要です。このプロパティでは、LIKE 演算子が SQL-92 エントリ レベル (ワイルドカード文字としての "%" と "_") に従ってサポートされています。
SQLPROP_SUBQUERIES いいえ SQL Serverプロパティ: このプロパティは、SQL の最小限のレベルをサポートするプロバイダーで重要です。 このプロパティは、プロバイダーが SQL-92 エントリ レベルで指定されたサブクエリをサポートしていることを示します。 これには、相関サブクエリ、SELECTWHEREIN、および EXISTS 演算子をサポートする、ALL リスト内および ANY 句内でのサブクエリが含まれます。
SQLPROP_INNERJOIN いいえ SQL Server 固有のプロパティ: このプロパティは、SQL の最小限のレベルをサポートするプロバイダーにとって重要です。 このプロパティは、FROM 句での複数のテーブルを使用した結合のサポートを示します。 ------ ---

次の 3 つのリテラルは、 IDBInfo::GetLiteralInfoから取得されます。 DBLITERAL_CATALOG_SEPARATORDBLITERAL_SCHEMA_SEPARATOR (カタログ、スキーマ、およびオブジェクト名の部分を指定して完全なオブジェクト名を構築するため)、 DBLITERAL_QUOTE (プロバイダーに送信された SQL クエリの識別子名を引用符で囲む)。

プロバイダーで区切りリテラルがサポートされていない場合、SQL Server ではピリオド (.) が既定の区切り文字として使用されます。 プロバイダーでカタログ区切り文字だけがサポートされ、スキーマ区切り文字がサポートされていない場合、SQL Server では、カタログ区切り文字がスキーマ区切り文字としても使用されます。 プロバイダーで DBLITERAL_QUOTE がサポートされていない場合、SQL Server では引用記号として単一引用符 (') が使用されます。

プロバイダーの名前の区切りリテラルがこれらの既定値と一致しない場合、4 つの部分で構成される名前を使用して SQL Server からテーブルにアクセスするためには、プロバイダーによってそれらの区切りリテラルが IDBInfo を使用して公開されている必要があります。 これらのリテラルが公開されていない場合、そのようなプロバイダーに対してはパススルー クエリのみを使用できます。

SQLPROP_DYNAMICSQL および SQLPROP_NESTEDQUERIES プロパティを公開する方法の詳細については、「SQL Server 固有のプロパティ」を参照してください。

テーブル名の解決とメタデータ取得

SQL Server では、分散クエリ内の指定されたリモート テーブル名が、OLE DB データ ソース内の特定のテーブルまたはビューに解決されます。 リンク サーバー ベースとアドホック命名スキームは両方とも、プロバイダーによって解釈される、3 つの部分で構成される名前になります。 リンク サーバー ベースの名前の場合、4 つの部分で構成される名前の最後の 3 つの部分は、カタログ、スキーマ、およびオブジェクトの名前を形成します。 アドホック名の場合、OPENROWSET 関数の 3 番目の引数に、カタログ名、スキーマ名、およびオブジェクト名を定義する 3 つの部分で構成される名前を指定します。 カタログ名とスキーマ名の一方または両方を空にすることができます (空のカタログ名とスキーマ名を持つ 4 部構成の名前は、<server-name>...<object-name>のようになります)。このような場合、SQL Server は、スキーマ行セット テーブルで検索する対応する値として NULL を使用します。

SQL Server によって適用される名前解決規則およびメタデータ取得手順は、プロバイダーで IDBSchemaRowset オブジェクトに対する Session インターフェイスがサポートされているかどうかによって異なります。

IDBSchemaRowset がサポートされている場合は、TABLESCOLUMNSINDEXESTABLES_INFO の各スキーマ行セットが IDBSchemaRowset インターフェイスから使用されます (TABLES_INFO スキーマ行セットは OLE DB 2.0 で定義されます。) SQL Server では、IDBSchemaRowset インターフェイスによって返されたスキーマ行セットを制約して、指定されたリモート テーブル名の部分に一致するスキーマ行を検索します。 次に、スキーマ行セットに対する、プロバイダーによってサポートされる制約に関連した規則と、それらを使用してリモート テーブルのメタデータが SQL Server で取得される方法について説明します。

  • TABLE_NAME および COLUMN_NAME 列に対する制約は、常に必須です。

  • プロバイダーで TABLE_CATALOG (または TABLE_SCHEMA) がサポートされている場合、SQL Server では TABLE_CATALOG (または TABLE_SCHEMA) に対してその制約が使用されます。 リモート テーブル名にカタログ (またはスキーマ) 名が指定されていない場合、対応する制約の値として NULL 値が使用されます。 カタログ (またはスキーマ) 名が指定されている場合、TABLE_CATALOG (または TABLE_SCHEMA) での対応する制約がプロバイダーによってサポートされている必要があります。

  • TABLE_SCHEMA 列に対する制約は、プロバイダーによって TABLESCOLUMNS の両方でサポートされているか、どちらでもサポートされていない必要があります。 カタログ名の制約は、プロバイダーによって TABLESCOLUMNS の両方の行セットに対してサポートされているか、どちらに対してもサポートされていない必要があります。

  • INDEXES で何らかの制限がサポートされている場合、プロバイダーは、INDEXES の行セットTABLESTABLESor support them on neither. The provider must either support catalog name restriction on bothand と INDEXES の両方でスキーマ制限をサポートするか、どちらもサポートしていない必要があります。

上記の規則に従って制約を設定することで、TABLES スキーマ行セットから TABLE_CATALOGTABLE_SCHEMATABLE_NAMETABLE_TYPETABLE_GUID の各列が SQL Server によって取得されます。

COLUMNS スキーマ行セットからは、TABLE_CATALOGTABLE_SCHEMATABLE_NAMECOLUMN_NAMECOLUMN_GUIDORDINAL_POSITIONCOLUMN_FLAGSIS_NULLABLEDATA_TYPETYPE_GUIDCHARACTER_MAXIMUM_LENGTHNUMERIC_PRECISIONNUMERIC_SCALE の各列が SQL Server によって取得されます。 COLUMN_NAMEDATA_TYPEORDINAL_POSITION からは、null 以外の有効な値が返される必要があります。 DATA_TYPEDBTYPE_NUMERIC または DBTYPE_DECIMAL の場合、対応する NUMERIC_PRECISIONNUMERIC_SCALE は null 以外の有効な値である必要があります。

前の規則に従って制約を設定することで、オプションの INDEXES スキーマ行セットから、指定されたリモート テーブルのインデックスが SQL Server によって検索されます。 見つかった一致するインデックス エントリから、TABLE_CATALOGTABLE_SCHEMATABLE_NAMEINDEX_CATALOGINDEX_SCHEMAINDEX_NAMEPRIMARY_KEYUNIQUECLUSTEREDFILL_FACTORORDINAL_POSITIONCOLUMN_NAMECOLLATIONCARDINALITYPAGES の各列が SQL Server によって取得されます。

オプションの TABLES_INFO 行セットから、ブックマークのサポート、ブックマークの種類と長さなど、指定されたリモート テーブルに関する追加情報が SQL Server によって検索されます。 DESCRIPTION 行セットの TABLES_INFO 列を除くすべての列が使用されます。 TABLES_INFO 行セット内の情報は、次のように使用されます。

  • BOOKMARK_DURABILITY 列は、より効率的なキーセット カーソルを実装するために使用されます。 この列の値が BMK_DURABILITY_INTRANSACTION またはより高い持続性の値である場合、SQL Server では、キーセット カーソルを実装するためにブックマーク ベースの取得とリモート テーブル行の更新が使用されます。

  • BOOKMARK_TYPEBOOKMARK_DATA TYPEBOOKMARK_MAXIMUM_LENGTH の各列は、クエリのコンパイル時にブックマーク メタデータを判別するために使用されます。 これらの列がサポートされていない場合、SQL Server ではコンパイル時に IOpenRowset を使用してベース テーブルの行セットが開かれ、ブックマーク情報が取得されます。

IDBSchemaRowset がサポートされておらず、リモート テーブル名にカタログ名またはスキーマ名が含まれている場合、SQL Server によって IDBSchemaRowset が要求され、エラーが返されます。 ただし、カタログ名もスキーマ名も指定されていない場合、SQL Server では、リモート テーブルに対応する行セットが開かれ、行セット オブジェクトの必須 IColumnsInfo インターフェイスから列のメタデータが取得されます。

SQL Server では、IOpenRowset::OpenRowset を呼び出すことで、テーブルに対応する行セットが開かれます。 OPENROWSET に提供されるテーブル名は、カタログ、スキーマ、およびオブジェクト名の各部分から構築されます。

  • 名前の各部分 (catalogschemaobject name) は、プロバイダーの引用記号 (DBLITERAL_QUOTE) で囲まれてから、それらの間に DBLITERAL_CATALOG_SEPARATOR 文字と DBLITERAL_SCHEMA_SEPARATOR 文字が埋め込まれて連結されます。 名前の構築は、IOpenRowset 内の OLE DB 規則に従います。

  • テーブルの列メタデータは、行セット オブジェクトが開かれた後に、IColumnsInfo::GetColumnInfo によって取得されます。

IDBSchemaRowset が TABLES、COLUMNS、TABLES_INFO 行セットでサポートされていない場合、SQL Server によってベース テーブルに対して行セットが 2 回開かれます。1 回はクエリのコンパイル時で、メタデータが取得されます。もう 1 回はクエリ実行時です。 行セットを開くことにより副作用が発生するプロバイダー (たとえば、リアルタイム デバイスの状態を変更するコードを実行する、電子メールを送信する、任意のユーザー提供コードを実行するなど) では、この動作を認識しておく必要があります。

統計情報の取得

プロバイダーでベース テーブルの分布統計をサポートしている場合、SQL Server ではこれらの統計が使用されます。 SQL Server クエリ プロセッサには、次の 2 種類の統計情報が必要です。

  • 列 (または組) のカーディナリティ。 これは、テーブルの 1 つの列 (または列の組み合わせ) 内にある一意の値の数です。 これを使用して、列に対する述語の選択度を見積もることができます。 分布統計をサポートするプロバイダーでは、少なくとも 1 種類のカーディナリティがサポートされている必要があります。

  • ヒストグラム。 値の分布が一様でない場合、一意の値の数は、述語の選択度を正確に見積もるためには不十分です。 この場合、ヒストグラムを使用して、テーブル内の列の値の分布に関するより詳細な情報を提供できます。

統計を使用できるようにすることで、SQL Server クエリ オプティマイザーは、クエリ内の中間操作のカーディナリティをより正確に推定できるようになります。これにより、クエリの実行プランがより適切に生成されます。

OLE DB プロバイダーでは、次のように分布統計がサポートされている必要があります。

  • 必須。 (1) と (2) のプロパティをサポートします。(1) 列または組のカーディナリティがサポートされているかどうか、およびヒストグラムがサポートされているかどうかを示す DBPROP_TABLESTATISTICS と、(2) DBPROP_OPENROWSETSUPPORT ビットを使用して、ヒストグラムがサポートされているかどうかを示す DBPROPVAL_ORS_HISTOGRAM

  • 必須TABLE_STATISTICS スキーマ行セット。 TABLE_STATISTICS スキーマ行セットでは、指定したデータベースで使用可能な統計が一覧表示されます。 また、スキーマ行セット自体に列と組のカーディナリティが含まれており、特定の列でヒストグラムがサポートされているかどうかを示しています。 SQL Server で統計が使用されるためには、このスキーマ行セット内に列 TABLE_NAMESTATISTICS_NAMESTATISTICS_TYPECOLUMN_NAMEORDINAL_POSITION が必須です。 COLUMN_CARDINALITY または TUPLE_CARDINALITY の少なくとも 1 つは必須です。 ヒストグラムをサポートする場合には、NO_OF_RANGES も必須です。

  • 省略可。 必要に応じて、プロバイダーでヒストグラムをサポートする場合は、対応する統計の IOpenRowset::OpenRowset を指定してヒストグラムの行セットを開くことができるようにする、DBID メソッドの拡張機能をサポートする必要があります。

統計インターフェイスの詳細については、OLE DB 2.6 の仕様を参照してください。

制約

また、OLE DB プロバイダーで OLE DB 2.6 のスキーマ行セットである CHECK をサポートしている場合、リモート データ ソース内のベース テーブルに定義されている CHECK_CONSTRAINTS_BY_TABLE 制約も、SQL Server クエリ オプティマイザーによって使用されます。 スキーマ行セットの CHECK_CLAUSE 列では、SQL-92 に準拠した構文で CHECK 句の述語を返す必要があります。 クエリ オプティマイザーでは、テーブルにチェック制約が存在するため、常に false であるか、常に true であることがわかっている述語を排除または簡略化するために、制約情報が使用されます。

トランザクション管理

SQL Server では、プロバイダーの ITransactionLocal (ローカル トランザクション用) および ITransactionJoin (分散トランザクション用) の各 OLE DB インターフェイスを使用することで、分散データへのトランザクション ベースのアクセスがサポートされます。 プロバイダーに対してローカル トランザクションを開始すると、SQL Server によってアトミック書き込み操作が保証されます。 SQL Server では、分散トランザクションを使用することにより、複数のノードに関係するトランザクションの結果 (コミットまたは中止) がすべてのノードで同じになるようにします。 プロバイダーで必要な OLE DB のトランザクション関連のインターフェイスをサポートしていない場合、ローカル トランザクション コンテキストによっては、そのプロバイダーに対する更新操作は許可されません。

次の表では、プロバイダーの機能とローカル トランザクション コンテキストを特定して、ユーザーが分散クエリを実行した場合の動作について説明します。 プロバイダーに対する読み取り操作では、SELECT ステートメントか、リモート テーブルが SELECT INTO の入力側に読み込まれるときは、INSERTUPDATE、または DELETE ステートメントを参照します。 プロバイダーに対する書き込み操作では、リモート テーブルを対象とする INSERTUPDATE、または DELETE ステートメントを参照します。

プロバイダーの機能とトランザクション コンテキストに基づく分散クエリの結果:

分散クエリの発生 プロバイダーで ITransactionLocal をサポートしていない プロバイダーで ITransactionLocal をサポートしているが、ITransactionJoin をサポートしていない プロバイダーで ITransactionLocalITransactionJoin の両方をサポートしている
トランザクション内で、トランザクション自体によって (ユーザー トランザクションなし)。 既定では、読み取り操作のみが許可されます。 プロバイダー レベルのオプション Nontransacted Updates が有効になっている場合は、書き込み操作が許可されます (このオプションが有効になっている場合、SQL Server では、プロバイダーのデータに対する原子性と一貫性を保証できません。これにより、書き込み操作の部分的な影響がリモート データ ソースに反映され、元に戻すことができなくなる可能性があります)。 すべてのステートメントがリモート データに対して許可されます。 キーセット カーソルは読み取り専用です。 ローカル トランザクションは、現在の SQL Server セッションの分離レベルを使用してプロバイダーで開始され、ステートメントの評価が正常に終了した時点でコミットされます (READ COMMITTED ステートメントを使用して変更されていない限り、SQL Server セッションの既定の分離レベルは SET TRANSACTION ISOLATION LEVEL です。プロバイダーでは、要求される分離レベルをサポートしている必要があります)。 すべてのステートメントを使用できます。 キーセット カーソルは読み取り専用です。 ローカル トランザクションは、現在の SQL Server セッションの分離レベルを使用してプロバイダーで開始され、ステートメントの評価が正常に終了した時点でコミットされます。
ユーザー トランザクション内 (つまり、BEGIN TRAN または BEGIN DISTRIBUTED TRANCOMMIT との間)。 トランザクションの分離レベルが READ COMMITTED (既定値) 以下の場合は、読み取り操作が許可されます。 より高い分離レベルの場合、分散クエリは許可されません。 読み取り操作のみが許可されます。 現在の SQL Server セッションの分離レベルを使用して、新しい分散トランザクションがプロバイダーで開始されます。 すべてのステートメントを使用できます。 新しい分散トランザクションは、現在の SQL Server セッションの分離レベルを使用してプロバイダーで開始され、ユーザー トランザクションのコミット時にコミットされます。 データ変更ステートメントの場合、既定では、分散トランザクションで入れ子になったトランザクションが SQL Server によって開始されます。これにより、データ変更ステートメントを、周囲のトランザクションを停止せずに特定のエラー条件下で停止させることができます。 XACT_ABORT SET オプションがオンの場合、SQL Server では、入れ子になったトランザクションのサポートは不要であり、データ変更ステートメントの実行中にエラーが発生した場合は、周囲のトランザクションを停止します。

分散クエリでのデータ型の処理

OLE DB プロバイダーでは、OLE DB で定義されたデータ型 (OLE DB の DBTYPE によって示される) に関連したデータを公開します。 SQL Server では、サーバー内部の外部データをネイティブ SQL Server 型として処理します。この結果、データが SQL Server によって消費されるか SQL Server によってエクスポートされるときに、OLE DB データ型から SQL Server ネイティブ型へのマッピング、およびその逆のマッピングがそれぞれ行われます。 このマッピングは、特に明記されていない限り、暗黙的に行われます。

分散クエリ内のデータ型は、次の 2 つのマッピング方法のいずれかを使用して処理されます。

  • 消費側のマッピングでは、SELECT ステートメント内および INSERT、UPDATE、DELETE ステートメントの入力側にリモート テーブルが示されている場合、OLE DB のデータ型から SQL Server のネイティブ データ型に消費側で型がマッピングされます。

  • エクスポート側のマッピングでは、INSERT または UPDATE ステートメントの対象テーブルとしてリモート テーブルが示されている場合、SQL Server データ型から OLE DB データ型にエクスポート側で型がマッピングされます。

SQL Server と OLE DB のデータ型マッピング テーブル。

OLE DB 型 DBCOLUMNFLAG SQL Server データ型
DBTYPE_I1* numeric(3, 0)
DBTYPE_I2 smallint
DBTYPE_I4 int
DBTYPE_I8 numeric(19,0)
DBTYPE_UI1 tinyint
DBTYPE_UI2* numeric(5,0)
DBTYPE_UI4* numeric(10,0)
DBTYPE_UI8* numeric(20,0)
DBTYPE_R4 float
DBTYPE_R8 real
DBTYPE_NUMERIC numeric
DBTYPE_DECIMAL decimal
DBTYPE_CY money
DBTYPE_BSTR DBCOLUMNFLAGS_ISFIXEDLENGTH=true
または
最大長 > 4000 文字
ntext
DBTYPE_BSTR DBCOLUMNFLAGS_ISFIXEDLENGTH=true nchar
DBTYPE_BSTR DBCOLUMNFLAGS_ISFIXEDLENGTH=false nvarchar(エヌヴァーチャー)
DBTYPE_IDISPATCH エラー
DBTYPE_ERROR エラー
DBTYPE_BOOL bit
DBTYPE_VARIANT* nvarchar(エヌヴァーチャー)
DBTYPE_IUNKNOWN エラー
DBTYPE_GUID uniqueidentifier
DBTYPE_BYTES DBCOLUMNFLAGS_ISLONG=true
または
最大長 > 8000
image
DBTYPE_BYTES DBCOLUMNFLAGS_ISROWVER=trueDBCOLUMNFLAGS_ISFIXEDLENGTH=true、列サイズ = 8
または
最大長は報告されない。
timestamp
DBTYPE_BYTES DBCOLUMNFLAGS_ISFIXEDLENGTH=true binary
DBTYPE_BYTES DBCOLUMNFLAGS_ISFIXEDLENGTH=true varbinary
DBTYPE_STR DBCOLUMNFLAGS_ISFIXEDLENGTH=true char
DBTYPE_STR DBCOLUMNFLAGS_ISFIXEDLENGTH=true varchar
DBTYPE_STR DBCOLUMNFLAGS_ISLONG=true
または
最大長 > 8000 文字
または
最大長は報告されない。
text
DBTYPE_WSTR DBCOLUMNFLAGS_ISFIXEDLENGTH=true nchar
DBTYPE_WSTR DBCOLUMNFLAGS_ISFIXEDLENGTH=false nvarchar
DBTYPE_WSTR DBCOLUMNFLAGS_ISLONG=true
または
最大長 > 4000 文字
または
最大長は報告されない。
ntext
DBTYPE_UDT エラー
DBTYPE_DATE* datetime
DBTYPE_DBDATE datetime (明示的な変換が必要)
DBTYPE_DBTIME datetime (明示的な変換が必要)
DBTYPE_DBTIMESTAMP* datetime
DBTYPE_ARRAY エラー
DBTYPE_BYREF 無視
DBTYPE_VECTOR エラー
DBTYPE_RESERVED エラー

* SQL Server 型の表記への何らかの形式の変換を示します。これは、SQL Server に正確な同等のデータ型がないためです。 このような変換によって、精度の損失、オーバーフロー、またはアンダーフローが生じる可能性があります。 対応するデータ型が SQL Server の将来のバージョンでサポートされた場合、既定の暗黙的なマッピングは将来変更される可能性があります。

numeric(p,s) は、精度が numeric で小数点以下桁数が p の SQL Server データ型 s を示しています。 DBTYPE_NUMERICDBTYPE_DECIMAL に許容される最大精度は 38 です。 プロバイダーは、アクセサーの作成時に DBTYPE_BSTR 列へのバインディングを DBTYPE_WSTRとしてサポートする必要があります。 DBTYPE_VARIANT 列は Unicode 文字列 nvarcharとして処理されます。 これには、プロバイダーからDBTYPE_VARIANTDBTYPE_WSTRの変換がサポートされている必要があります。 プロバイダーは、OLE DB で定義されているように、この変換を実装することが想定されています。 詳細については、OLE DB 仕様のデータ型を参照してください。

データ型マッピングの解釈

SQL Server 型へのマッピングは、OLE DB データ型と、列またはスカラー値を記述する DBCOLUMNFLAGS 値によって決まります。 COLUMNS スキーマ行セットの場合、DATA_TYPE 列と COLUMN_FLAGS 列でこれらの値を表します。 IColumnsInfo::GetColumnInfo インターフェイスの場合、wType 構造体の dwFlags メンバーと DBCOLUMNINFO メンバーでこの情報を表します。

特定の DBTYPE および DBCOLUMNFLAG 値を持つ特定の列に対して消費側マッピングを使用するには、テーブル内で対応する SQL Server 型を探します。 式に含まれるリモート テーブルの列の型の規則は、次の単純な規則によって記述できます。

テーブル内の対応するマップされた SQL Server 型が同じコンテキストで有効である場合、Transact-SQL 式では、指定されたリモート列の値が有効です。

テーブルとルールでは、次のものが定義されます。

  • 比較と式。

一般に、X <op> <remote-column> は、<op>X のデータ型と <remote-column> のマップ先のデータ型で有効な演算子である場合に、有効な式です。

  • 明示的な変換。

Convert(X, <remote-column>) は、DBTYPE<remote-column> がネイティブ データ型である Y に (上の表に従って) マップされ、Y から X への明示的な変換が許可されている場合に使用できます。

ユーザーがリモート データを既定以外のネイティブ データ型に変換する場合は、明示的な変換を使用する必要があります。

リモート テーブルに対して UPDATE および INSERT ステートメントでエクスポート側マッピングを使用するには、ネイティブの SQL Server データ型を同じテーブルを使用して OLE DB データ型にマップします。 次のいずれかが存在する場合には、SQL Server 型である S1 から特定の OLE DB 型 T へのマッピングが可能です。

  • 対応するマッピングがマッピング テーブル内に直接見つかる。

  • S1 がマッピング テーブル内の型 S2 にマップされるように、S2 から別の SQL Server 型 T への暗黙的な変換が可能である。

ラージ オブジェクト (LOB) の処理

マッピング テーブルに示されているように、DBTYPE_STRDBTYPE_WSTRDBTYPE_BSTR 型の列でも DBCOLUMNFLAGS_ISLONG が報告される場合、または最大長が 4,000 文字を超えている場合 (または最大長が報告されない場合)、SQL Server ではそれらを必要に応じて text または ntext として扱います。 同様に、DBTYPE_BYTES 列の場合、DBCOLUMNFLAGS_ISLONG が設定されているか、最大長が 8,000 バイトを超えている場合 (または最大長が報告されない場合)、列は image 列として扱われます。 Textntextimage の各列は、LOB 列と呼ばれます。

SQL Server では、OLE DB プロバイダーの LOB に対してテキストとイメージのフル機能は公開されません。 TEXTPTRS は、OLE DB プロバイダーのラージ オブジェクトに対してサポートされていません。そのため、関連する機能はどれもサポートされません (たとえば、TEXTPTR システム関数や、READTEXTWRITETEXTUPDATETEXT の各ステートメント)。 SELECT LOB 列全体を取得するステートメントは、リモート テーブルのラージ オブジェクト列全体の UPDATE ステートメントと INSERT ステートメントと同様にサポートされます。

プロバイダーでサポートされている場合、SQL Server では LOB 列に対して、構造化ストレージ インターフェイスを使用します。 構造化ストレージ インターフェイスは、優先順位と機能の低い方から、ISequentialStreamIstream、または ILockBytes となります。 これらのインターフェイスが 1 つ以上サポートされている場合、プロバイダーでは、DBPROP_OLEOBJECTS インターフェイスを使用してクエリが実行されたときに、IDBProperties プロパティの値として DBPROPVAL_OO_BLOB を返す必要があります。 また、プロバイダーでは、サポートしているインターフェイスに対するサポートを DBPROP_STRUCTUREDSTORAGE プロパティで示す必要があります。

LOB 列の構造化ストレージ インターフェイスをプロバイダーがサポートしていない場合、SQL Server では、このインターフェイスを独自に具体化し、textntext、または image 列として公開します。

LOB 列へのアクセス

プロバイダーが構造化ストレージ インターフェイスのいずれかをサポートしている場合、SQL Server では次の手順を実行してクエリの実行中に LOB 列を取得します。

  1. SQL Server では、IOpenRowset::OpenRowset を使用して行セットを開く前に、ラージ オブジェクト列について 1 つ以上の構造化ストレージ インターフェイス (ISequentialStreamIstreamILockBytes) のサポートを要求します。 プロバイダーでサポートされている 1 つ目のインターフェイスは必須です。追加のインターフェイスは、対応する DBPROP 構造体の dwOptions 要素を DBPROPOPTIONS_SETIFCHEAP に設定することによって、"低コストの場合は設定される" ものとして要求されます。 たとえば、プロバイダーで ISequentialStreamILockBytes の両方をサポートしている場合、ISequentialStream は必須であり、ILockBytes は、"低コストの場合は設定される" ものとして要求されます。

  2. 行セットが開かれた後、SQL Server では IRowsetInfo::GetProperties を使用して、行セットで使用可能な実際のインターフェイスを識別します。 プロバイダーから返された最後の、つまり最も適したインターフェイスが使用されます。 SQL Server でラージ オブジェクト列に対してアクセサーを作成するとき、その列はインターフェイスに設定されたバインディングの DBOBJECT 構造体の iid 要素を使用して、DBTYPE_IUNKNOWN としてバインドされます。

LOB 列からの読み取り

ラージ オブジェクト列から読み取るには、IRowset::GetData から行バッファーに返される、要求された構造化ストレージ インターフェイスのインターフェイス ポインターを使用します。 プロバイダーが同時に複数の開かれた LOB をサポートしていない場合 (つまり、DBPROP_MULTIPLE_STORAGEOBJECTS をサポートしていない場合)、および行に複数のラージ オブジェクト列がある場合、SQL Server では LOB 列がローカル作業テーブルにコピーされます。

LOB 列に対する UPDATE ステートメントと INSERT ステートメント

SQL Server では、プロバイダーが提供するインターフェイスを使用してストレージ オブジェクトを変更するのではなく、新しいストレージ オブジェクトへのポインターをプロバイダーに渡します。 LOB 列ごとに、ストレージ オブジェクトに対して更新または挿入される値が、選択した構造化ストレージ インターフェイスを使用して作成されます。 UPDATE操作とINSERT操作のどちらであるかに応じて、ストレージ オブジェクトへのポインターはそれぞれ、IRowsetChange::SetDataまたはIRowsetChange::InsertRowを介してプロバイダーに渡されます。

エラー処理

OLE DB プロバイダーに対する特定のメソッド呼び出しによってエラー コードが返されると、SQL Server エラー状態に関する情報をユーザーに返す前に、プロバイダーの拡張エラー情報が検索されます。

SQL Server では、OLE DB で指定された OLE DB エラー オブジェクトが使用されます。 大まかな手順の一部を次に示します。

  1. メソッドの呼び出しによってプロバイダーからエラー コードが返されると、SQL Server によって ISupportErrorInfo インターフェイスが検索されます。 このインターフェイスがサポートされている場合、SQL Server では、ISupportErrorInfo::InterfaceSupportsErrorInfo を呼び出して、エラー コードを生成したインターフェイスによってエラー オブジェクトがサポートされているかどうかを確認します。
  1. インターフェイスによってエラー オブジェクトがサポートされている場合、SQL Server では、GetErrorInfo 関数を呼び出して、現在のエラー オブジェクトの IErrorInfo インターフェイス ポインターを取得します。

  2. SQL Server により、IErrorInfo インターフェイスを使用して IErrorRecords インターフェイスへのポインターが取得されます。

  3. SQL Server により、IErrorRecords を使用してオブジェクト内のすべてのエラー レコードがループ処理され、各レコードに対応するエラー メッセージ テキストが取得されます。

プロバイダーのエラー オブジェクトがどのように使用されるかについて詳しくは、OLE DB のドキュメントを参照してください。

セキュリティ

コンシューマーが OLE DB プロバイダーに接続するとき、コンシューマーが統合セキュリティ ユーザーとして認証されることを望まない限り、通常はプロバイダーによってユーザー ID とパスワードが要求されます。 分散クエリの場合、分散クエリを実行する SQL Server ログインの代わりに、SQL Server が OLE DB プロバイダーのコンシューマーとして機能します。 SQL Server により、現在の SQL Server ログインがリンク サーバー上のユーザー ID とパスワードにマップされます。

これらのマッピングは、ユーザーが特定のリンク サーバーに対して指定することができ、システム ストアド プロシージャである sp_addlinkedsrvloginsp_droplinkedsrvlogin によって設定および管理できます。 IDBProperties::SetProperties を使用して DBPROP_AUTH_USERID および DBPROP_AUTH_PASSWORD という初期化グループ プロパティを設定することにより、マッピングによって決定されるユーザー ID とパスワードが接続の確立時にプロバイダーに渡されます。

クライアントが Windows 認証を使用して SQL Server に接続し、ログインに self を使用した sp_addlinkedsrvlogin マッピングが設定されている場合、SQL Server では、クライアントのセキュリティ コンテキストを借用し、接続の確立時にプロバイダーに対して DBPROP_AUTH_INTEGRATED プロパティを設定しようとします。 この処理は "委任" と呼ばれます。

接続に使用するセキュリティ コンテキストが決定された後、このセキュリティ コンテキストの認証と、データ ソース内のデータ オブジェクトに対するそのコンテキストのアクセス許可のチェックは、完全に OLE DB プロバイダーに任されます。

詳細については、次のトピックを参照してください。 sp_addlinkedsrvlogin および sp_droplinkedsrvlogin

クエリ実行のシナリオ

分散クエリを評価するとき、次の 1 つまたは複数のシナリオで SQL Server と OLE DB プロバイダーのやり取りが行われます。

  • リモート クエリ

  • インデックス アクセス

  • 純粋なテーブル スキャン

  • UPDATEDELETE のステートメント

  • INSERT 明細書

  • パススルー クエリ

リモート クエリ

SQL Server は、プロバイダー全体で評価できる元のクエリの一部を評価する SQL クエリを生成します。 このシナリオは、SQL コマンド プロバイダーに対してのみ可能です。 SQL クエリを生成して SQL Server がプロバイダーに操作をプッシュする範囲は、プロバイダーがサポートする SQL 文法によって異なります。 プロバイダーでは、次の方法で SQL サポートのレベルを示す必要があります。

  1. DBPROP_SQLSUPPORT プロパティを使用して、SQL の最小限、ODBC コア、または SQL-92 エントリ レベルのサポートを指定します。 SQL の最小限の構文レベルは、SQL Server でサポートされている新しいレベルで、これにより、SQL の単純なサブセットをサポートするシンプルなプロバイダーに SQL Server からリモート クエリを送信できます。 このレベルには、サブクエリを含まない、SELECT 句に複数のテーブルを含まない (したがって結合がない)、および GROUP BY を含まない基本的な FROM ステートメントが該当します。 これらの各構文レベルのプロバイダーに対してリモート クエリを生成するために SQL Server によって使用される SQL 文法のサブセットについては、「リモート クエリの生成に使用される SQL サブセット」を参照してください。

  2. DBPROP_SQLSUPPORT によって報告される、構文レベルに含まれていない個々の SQL 機能のサポートを示すために、さまざまな SQL Server 固有のプロパティをサポートします。 プロパティの一覧と、各プロパティが SQL Server によってどのように使用されるかについては、このセクションで後述します。

SQL Server では、Transact-SQL 文字列内のパラメーター マーカーとして疑問符 (?) を指定して、パラメーター化クエリの実行が使用されます。 パラメーター化クエリの実行は、SQL Server、Microsoft Jet、および Oracle OLE DB プロバイダーに対して使用されます。 他のプロバイダーに対して、プロバイダーが ICommandWithParameters オブジェクトで Command をサポートし、次の条件のうち少なくとも 1 つが満たされている場合は、パラメーター化クエリの実行が使用されます。

  • プロバイダーでは、DBPROP_SQLSUPPORT プロパティを使用して SQL Server サポートの ODBC コア レベルを示します。

  • プロバイダーでは、IDBPProperties を使用して SQLPROP_DYNCMICSQL SQL Server 固有のプロパティをサポートすることによって、疑問符 (?) パラメーター マーカーのサポートを示します。 詳細については、プロバイダーのプロパティに関する次のセクションを参照してください。

  • 管理者は、プロバイダーに対して Dynamic Parameters プロバイダー オプションを設定して、SQL Server でパラメーター化クエリを生成できるようにします。

リモートで実行される SQL テキストが SQL Server によって生成されるとき、DBLITERAL_QUOTE インターフェイスの IDBInfo リテラルによって報告される引用記号でテーブル名と列名が囲まれます。 このリテラルがサポートされていない場合、テーブル名と列名は引用記号で囲まれません。

プロバイダーでパラメーター化クエリの実行をサポートしている場合、SQL Server により、パラメーター化クエリの実行方法が考慮され、ローカル テーブルとリモート テーブルの結合が評価されます。 パラメーター化クエリは、ローカル テーブルの各行から生成されたパラメーター値に対して繰り返し実行されます。 この方法では、プロバイダーから取得される行の数を減らすことができ、少数の行を含むローカル テーブルを多数の行を含むリモート テーブルと結合する場合に便利です。 このリモート結合方法は、REMOTE 結合オプティマイザー ヒントによって適用できます。 パラメーター化クエリの実行の詳細については、「方法:パラメーター化クエリを実行」を参照してください。

リモート クエリ シナリオにおけるプロバイダーに対する大まかな手順を次に示します。

  1. SQL Server により、Command を使用して Session オブジェクトから IDBCreateCommand::CreateCommand オブジェクトが作成されます。

  2. Remote Query Timeout サーバー構成オプションが 0 より大きい値に設定されている場合、SQL Server により、> オブジェクトの DBPROP_COMMANDTIMEOUT プロパティが、Command を使用して同じ値に設定されます。コマンド テキストを、生成された Transact-SQL 文字列に設定するために、ICommandProperties::SetProperties が呼び出される必要があります。

  3. コマンドを準備するために、SQL Server によって ICommandPrepare::Prepare が呼び出されます。 プロバイダーでこのインターフェイスがサポートされていない場合、SQL Server の手順 4 に進みます。

  4. 生成されたクエリがパラメーター化されている場合、SQL Server では、ICommandWithParameters::SetParameterInfo を使用してパラメーターを記述し、IAccessor::CreateAccessor を使用してパラメーターのアクセサーを作成します。

  5. SQL Server によって ICommand::Execute が呼び出されて、コマンドが実行され、行セットが作成されます。

  6. SQL Server では、IRowset インターフェイスを使用してテーブルの行を移動し、使用します。 行をフェッチするには IRowset::GetNextRows、行セットの先頭に位置変更するには IRowset::RestartPosition、行を解放するには IRowset::ReleaseRows を使用します。

リモート クエリの実行に関連するプロバイダー プロパティ

プロバイダーで、DBPROP_SQLSUPPORT によって報告される構文レベルに含まれていない SQL 機能をサポートしている場合は、プロバイダー固有のさまざまなプロパティを使用してそれらを示すことができます。

  • SQLPROP_GROUPBY。 このプロパティは、SQL の最小限のレベルをサポートするプロバイダーにとって重要です。 このプロパティで、プロバイダーが SELECT ステートメント内の GROUP BY 句と HAVING 句をサポートしていることを示します。 また、このプロパティでは、プロバイダーが次の 5 つの集計関数、つまり MIN、MAX、SUM、COUNT、および AVG をサポートしていることも示します。 これらの集計関数の引数で、プロバイダーによって DISTINCT がサポートされていない可能性があります。

  • SQLPROP_SUBQUERIES。 このプロパティは、SQL の最小限のレベルをサポートするプロバイダーで重要です。 プロバイダーが SQL-92 エントリ レベルに指定されているサブクエリをサポートしていることを示します。 これには、SELECT リスト内のサブクエリと、WHERE 句内のサブクエリが含まれ、相関サブクエリ、INEXISTSALL、および ANY 演算子がサポートされます。

  • SQLPROP_DATELITERALS。 このプロパティは、あらゆるプロバイダー (SQL-92 エントリ レベルをサポートするプロバイダーを含む) にとって重要です。 datetime リテラルに対する標準リテラル構文のサポートは、SQL-92 エントリ レベルに含まれていません。 この SQL Server 固有のプロパティでは、プロバイダーが SQL-92 標準で指定されている datetime リテラル構文をサポートしていることを示します。

  • SQLPROP_ANSILIKE。 SQL の最小限のレベルをサポートするプロバイダーにとって重要です。 このプロパティでは、プロバイダーが SQL-92 エントリ レベルに従って LIKE 演算子を ("%" および "_" をワイルドカード文字として) サポートしていることを示します。 SQL の最小限のレベルには LIKE のサポートが含まれていないため、これは SQL の最小限のレベルをサポートしているプロバイダーに対して有用です。

  • SQLPROP_INNERJOIN。 このプロパティは、SQL の最小限のレベルをサポートするプロバイダーにとって重要です。 FROM 句内の複数のテーブルがサポートされていることを示します。 SQL の最小限のレベルのみをサポートしているプロバイダーに対して有用です (SQL の最小限のレベルには結合のサポートが含まれていないため)。 これは、明示的な JOIN キーワードに対するサポートや、OUTER 結合に対するサポートを示すものではありません。 FROM 句での、テーブルのリストを使用した暗黙的な結合のみをサポートしていることを示します。

  • SQLPROP_DYNAMICSQL。 パラメーター マーカーとしての ? に対するサポートを示します。 パラメーター マーカーは、WHERE 句または SELECT リスト内のスカラー項目の代わりにサポートされる必要があります。 パラメーター マーカー ? のサポートによって、SQL Server からプロバイダーにパラメーター化クエリを送信できます。

  • SQLPROP_NESTEDQUERIES。 FROM 句での入れ子になった SELECT (たとえば、SELECT * FROM (SELECT * FROM T))) のサポートを示します。 多くの場合、SQL Server では、リモートで実行されるクエリ文字列を生成するときに、クエリの SELECT 句で入れ子になった FROM ステートメントを使用します。 入れ子になった SELECT のサポートは SQL-92 エントリ レベルでは必須ではないため、SQL Server では、プロバイダーもこのプロパティを設定していない限り、入れ子になった SELECT ステートメントを持つクエリをプロバイダーに委任しません。 または、管理者がプロバイダーに Nested Queries プロバイダー オプションを設定することで、SQL Server でプロバイダーに対して入れ子になったクエリを生成させることもできます。

プロバイダーでは、SQLPROPSET_OPTHINTS という SQL Server 固有のプロパティ セットを使用してこれらのプロパティをサポートでき、PROPID の値を定義できます。 プロパティ セット SQLPROPSET_OPTHINTS と 2 つのプロパティは、次の定数を使用して定義されます。

extern const GUID `SQLPROPSET_OPTHINTS` = { 0x2344480c, 0x33a7, 0x11d1, { 0x9b, 0x1a, 0x0, 0x60, 0x8, 0x26, 0x8b, 0x9e } };
enum SQLPROPERTIES {
SQLPROP_NESTEDQUERIES = 0x4,
SQLPROP_DYNAMICSQL = 0x5,
SQLPROP_GROUPBY = 0x6,
SQLPROP_DATELITERALS = 0x7,
SQLPROP_ANSILIKE = 0x8,
SQLPROP_INNERJOIN = 0x9,
SQLPROP_SUBQUERIES = 0x10
};

文字セットと並べ替え順序の影響

SQL Server では、列レベルごとに文字データの照合順序を指定できます。 照合順序には、文字セットと、Unicode 以外の文字データ用の並べ替え順序指定の両方 (char 列と varchar 列) が含まれます。 Unicode データの場合 (nchar 列と nvarchar 列)、照合順序では並べ替え順序のみが指定されます。

SQL Server では、リンク サーバーで使用される文字セット (Unicode 以外のデータの場合)、並べ替え順序、文字列比較のセマンティクスがローカル サーバーで使用されているものと同じ場合にのみ、プロバイダーに対して文字列比較を委任します。

SQL Server リンク サーバーの場合は、SQL Server によって照合順序の互換性が自動的に決定されます。 他のプロバイダーについては、管理者が、特定のリンク サーバーからの文字データの照合順序を SQL Server に示す必要があります。 SQL Server では、Collation Name という新しいリンク サーバー オプションがサポートされています。 リンク サーバーで採用されている照合順序セマンティクスが SQL Server 標準の照合順序の 1 つと同じであると管理者が判断した場合は、Collation Name オプションをその照合順序名に設定できます。 Collation Name オプションを設定するには、sp_serveroption システム ストアド プロシージャを使用します。 このオプションは、次の両方の条件が満たされている場合にのみ設定する必要があります。

  • リモートの並べ替え順序と文字セットが、指定された SQL Server の照合順序と同じである。

  • OLE DB プロバイダーによって使用される文字列比較のセマンティクスが、SQL-92 標準仕様の比較セマンティクスに従っているか、SQL Server の比較セマンティクスに同等に従っている。

SQL Server 7.0 でサポートされている Collation Compatible オプションは、旧バージョンとの互換性のために引き続きサポートされています。 それを True に設定することは、Collation Name オプションを SQL Server マスター データベースの既定の照合順序に設定することと同じです。 新しいアプリケーションでは、Collation Compatible オプションの代わりに Collation Name オプションを使用してください。

インデックス アクセス

SQL Server では、プロバイダーによって公開されているインデックスを使用して、分散クエリの特定の述語を評価します。 このシナリオが可能なのは、インデックス プロバイダーに対して、およびユーザーが Index as Access Path プロバイダー オプションを設定した場合のみです。 以下では、インデックスを使用してクエリを実行する際に、プロバイダーに対して SQL Server で実行される主要な手順を大まかに示します。

  1. 完全なテーブル名とインデックス名を指定した IOpenRowset::OpenRowset を使用して、インデックス行セットを開きます。 完全なテーブル名とインデックス名は、リモート クエリのシナリオで前述したとおりに生成されます。

  2. テーブルの完全名を指定した IOpenRowset::OpenRowset を使用して、ベース テーブルの行セットを開きます。

  3. IRowsetIndex::SetRange を使用し、クエリ述語に基づいてインデックス行セットの範囲を設定します。

  4. インデックス行セットに対して、IRowset を使用してインデックス行セットから行をスキャンします。

  5. 取得されたインデックス行のブックマーク列を使用して、ベース テーブルの行セットから対応する行を IRowsetLocate::GetRowsByBookmark でフェッチします。

ベース テーブルに対して開かれる行セットには、DBPROP_IRowsetLocateDBPROP_BOOKMARKS の行セット プロパティが必要です。

純粋なテーブル スキャン

SQL Server でプロバイダーからリモート テーブル全体をスキャンし、すべてのクエリ評価をローカルで実行します。 テーブルに対応する行セットは、IOpenRowset::OpenRowset を呼び出すことによって開かれます。 SQL Server により、カタログ、スキーマ、およびオブジェクト名の各部分から OPENROWSET に提供されるテーブル名が次のように構築されます。

  1. 名前の各部分をプロバイダーの引用記号 (DBLITERAL_QUOTE) で囲んでから、DBLITERAL_CATALOG_SEPARATOR 文字を間に埋め込んで連結します。

  2. 行セット オブジェクトを開くと、SQL Server では IColumnsInfo インターフェイスを使用して、実行時のメタデータがテーブルのコンパイル時のメタデータと同じであることが確認されます。

  3. SQL Server では、IRowset インターフェイスを使用してテーブルの行を移動し、使用します。 行をフェッチするには IRowset::GetNextRows、行セットの先頭に位置変更するには IRowset::RestartPosition、行を解放するには IRowset::ReleaseRows を使用します。

UPDATE ステートメントと DELETE ステートメント

リモート テーブルを SQL Server 分散クエリから更新または削除するには、次の条件が満たされている必要があります。

  • プロバイダーで、更新または削除の対象となるテーブルの IOpenRowset で開かれた行セットについて、ブックマークをサポートしている必要があります。

  • プロバイダーで、更新または削除の対象となるテーブルの IRowsetLocate で開かれた行セットについて、IRowsetChange インターフェイスと IOpenRowset インターフェイスをサポートしている必要があります。

  • IRowsetChange インターフェイスで、更新 (SetData) と削除 (DeleteRows) のメソッドをサポートしている必要があります。

  • プロバイダーで ITransactionLocal がサポートされていない場合、UPDATE ステートメントと DELETE ステートメントは、そのプロバイダーに対して Non-transacted オプションが設定されていて、ステートメントがユーザー トランザクションに含まれていない場合にのみ使用できます。

  • プロバイダーで ITransactionJoin がサポートされていない場合、UPDATE ステートメントまたは DELETE ステートメントは、ユーザー トランザクションに含まれていない場合にのみ使用できます。

更新されたテーブルに対して開かれる行セットには、DBPROP_IRowsetLocateDBPROP_IRowsetChange、および DBPROP_BOOKMARKS の各行セット プロパティが必要です。 DBPROP_UPDATABILITY 行セット プロパティは、実行された操作が DBPROPVAL_UP_CHANGE または DBPROPVAL_UP_DELETE のどちらであるかに応じて、それぞれ UPDATE または DELETE に設定されます。

UPDATEまたはDELETE操作を処理するためのプロバイダーに対する次の大まかな手順が実行されます。

  1. SQL Server により、IOpenRowset インターフェイスを使用してベース テーブルの行セットが開かれます。 SQL Server では、行セットに前述のプロパティが必要です。

  2. SQL Server によって、更新または削除する条件を満たす行のセットが判別されます。

  3. SQL Server では、ブックマークを使用し、条件を満たす行に IRowsetLocate インターフェイスによって配置します。

  4. IRowsetChange::SetDataUPDATE操作に使用し、削除操作にはIRowsetChange::DeleteRowsを使用して、条件を満たす行に対して必要な変更を実行します。

INSERT ステートメント

リモート テーブルに対して INSERT ステートメントをサポートするための条件は、 UPDATE ステートメントや DELETE ステートメントよりも厳しくありません。

  • 挿入先のベース テーブルで開かれた行セットに対する IRowsetChange::InsertRow をプロバイダーでサポートしている必要があります。

  • プロバイダーで ITransactionLocal がサポートされていない場合、INSERT ステートメントは、そのリンク サーバーに対して Non-transacted updates オプションが設定されていて、ステートメントがユーザー トランザクションに含まれていない場合にのみ使用できます。

  • プロバイダーで ITransactionJoin がサポートされていない場合、INSERT ステートメントは、ユーザー トランザクションに含まれていない場合にのみ使用できます。

SQL Server では、IOpenRowset::OpenRowset を使用してベース テーブルで行セットを開き、IRowsetChange::InsertRow を呼び出して、ベース行セットに新しい行を挿入します。

パススルー クエリ

このシナリオは、リモート クエリのシナリオに似ていますが、ICommand に指定されたコマンド テキストがユーザーによって送信されたコマンド文字列であり、SQL Server によって解釈されないという点が異なります。 SQL Server では、DBGUID_DEFAULT を呼び出すときに、言語識別子として ICommandText::SetCommandText を使用します。 DBGUID_DEFAULT により、プロバイダーが既定の言語を使用する必要があることが示されます。 このコマンド テキストで複数の結果セットが返される場合、たとえば、複数の結果セットを返すストアド プロシージャをコマンドで呼び出した場合、コマンドの最初の結果セットのみが SQL Server によって使用されます。

SQL Server で使用されるすべての OLE DB インターフェイスの一覧については、「SQL Server によって使用される OLE DB インターフェイス」を参照してください。

まとめ

Microsoft SQL Server によって、異種データ ソースにあるデータにアクセスするための最も信頼性の高いツール セットが提供されます。 SQL Server によって公開されている OLE DB インターフェイスを理解することで、開発者は分散クエリの高度な制御と高度な処理を実現できます。

SQL Server によって使用される OLE DB インターフェイス

次の表は、SQL Server によって使用されるすべての OLE DB インターフェイスを示しています。 「必須」列は、インターフェイスが SQL Server に必要な最小限の OLE DB 機能の一部であるか、またはオプションかを示します。 特定のインターフェイスが必須としてマークされていない場合でも、SQL Server からプロバイダーへのアクセスは可能ですが、プロバイダーに対して特定の SQL Server 機能または最適化を実行することはできません。

オプションのインターフェイスの場合、「シナリオ」列には、指定したインターフェイスを使用する 6 つのシナリオのうち 1 つ以上が示されています。 たとえば、基本テーブル行セットの IRowsetChange インターフェイスは省略可能なインターフェイスです。このインターフェイスは、 UPDATE ステートメントと DELETE ステートメントおよび INSERT ステートメントのシナリオで使用されます。 このインターフェイスがサポートされていない場合、UPDATE、DELETE、INSERT の各ステートメントをそのプロバイダーに対してサポートすることはできません。 オプションであるその他のインターフェイスの一部には、「シナリオ」列に "パフォーマンス" とマークされています。これは、そのインターフェイスを使用すると全般的なパフォーマンスが高くなることを示しています。 たとえば、IDBSchemaRowset インターフェイスがサポートされていない場合、SQL Server では行セットを 2 回開く必要があります (メタデータのために 1 回、クエリ実行のために 1 回)。 IDBSchemaRowset をサポートすることにより、SQL Server のパフォーマンスが向上します。

オブジェクト インターフェイス 必須 コメント シナリオ
データ ソース オブジェクト IDBInitialize はい データおよびセキュリティ コンテキストの初期化とセットアップを行います。
IDBCreateSession はい DB セッション オブジェクトを作成します。
IDBProperties はい プロバイダーの機能に関する情報を取得し、初期化プロパティを設定します。必須プロパティ: DBPROP_INIT_TIMEOUT。
IDBInfo いいえ 引用符で囲んだリテラル、カタログ、名前、パーツ、区切り記号、文字などを取得します。 リモート クエリ。
DB セッション オブジェクト IDBSchemaRowset いいえ テーブルまたは列のメタデータを取得します。 必要な行セット: TABLESCOLUMNSPROVIDER_TYPES。その他 (使用可能な場合に使用される): INDEXESTABLE_STATISTICS パフォーマンス、インデックス アクセス。
IOpenRowset はい テーブル、インデックス、またはヒストグラムについての行セットを開きます。
IGetDataSource はい DB セッション オブジェクトから DSO に戻るために使用します。
IDBCreateCommand いいえ クエリをサポートするプロバイダー用のコマンド オブジェクト (クエリ) を作成するために使用します。 リモート クエリ、パススルー クエリ。
ITransactionLocal いいえ トランザクション更新に使用します。 UPDATE および DELETEINSERT ステートメント。
ITransactionJoin いいえ 分散トランザクション サポートに使用します。 ユーザー トランザクション内の場合、UPDATE および DELETEINSERT ステートメント。
行セット オブジェクト IRowset はい 行をスキャンします。
IAccessor はい 行セット内の列にバインドします。
IColumnsInfo はい 行セット内の列に関する情報を取得します。
IRowsetInfo はい 行セット プロパティに関する情報を取得します。
IRowsetLocate いいえ UPDATE / DELETE 操作のため、およびインデックス ベースの参照を実行するために必要です。ブックマークによって行を検索するために使用されます。 インデックス アクセス、UPDATE および DELETE ステートメント。
IRowsetChange いいえ 行セットに対する INSERTS/UPDATES/ DELETES に必要です。 ベース テーブルに対する行セットは、INSERTUPDATEDELETE の各ステートメントのために、このインターフェイスをサポートしている必要があります。 UPDATE および DELETEINSERT ステートメント。
IConvertType はい 行セットが、その行セット内の列の特定のデータ型変換をサポートしているかどうかを確認するために使用します。
インデックス IRowset はい 行をスキャンします。 インデックス アクセス、パフォーマンス。
IAccessor はい 行セット内の列にバインドします。 インデックス アクセス、パフォーマンス。
IColumnsInfo はい 行セット内の列に関する情報を取得します。 インデックス アクセス、パフォーマンス。
IRowsetInfo はい 行セット プロパティに関する情報を取得します。 インデックス アクセス、パフォーマンス。
IRowsetIndex はい インデックスについての行セットにのみ必要で、インデックス機能 (範囲の設定、シーク) に使用されます。 インデックス アクセス、パフォーマンス。
command ICommand はい リモート クエリ、パススルー クエリ。
ICommandText はい クエリ テキストの定義に使用します。 リモート クエリ、パススルー クエリ。
IColumnsInfo はい クエリ結果の列のメタデータを取得するために使用します。 リモート クエリ、パススルー クエリ。
ICommandProperties はい コマンドが返す行セットに対して必要なプロパティを指定するために使用します。 リモート クエリ、パススルー クエリ。
ICommandWithParameters いいえ パラメーター化クエリの実行に使用します。 リモート クエリ、パフォーマンス。
ICommandPrepare いいえ メタデータを取得するコマンド (使用可能な場合はパススルー クエリで使用される) を準備するために使用します。 リモート クエリ、パフォーマンス。
Error オブジェクト IErrorRecords はい 1 つのエラー レコードに対応する、IErrorInfo インターフェイスへのポインターを取得するために使用します。
IErrorInfo はい 1 つのエラー レコードに対応する、IErrorInfo インターフェイスへのポインターを取得するために使用します。
任意のオブジェクト ISupportErrorInfo いいえ 特定のインターフェイスがエラー オブジェクトをサポートしているかどうかを確認するために使用します。

Index オブジェクト、Command オブジェクト、および Error オブジェクトは必須ではありません。 ただし、サポートされている場合、「必須」列に示されているとおり、一覧にあるインターフェイスは必須です。

リモート クエリの生成に使用される SQL サブセット

SQL コマンド プロバイダーに対して SQL Server クエリ プロセッサによって生成される SQL サブセットは、DBPROP_SQLSUPPORTプロパティで示されているとおり、プロバイダーがサポートしている構文レベルによって異なります。

SQL エントリ レベルまたは ODBC コアをサポートする SQL コマンド プロバイダー

SQL Server では、SQL-92 エントリ レベルまたは ODBC コアのどちらかをサポートする SQL コマンド プロバイダーによって評価されるクエリに対して、SQL 言語の次のサブセットを使用します。

  1. SELECTSELECTFROMWHEREGROUP BYUNIONUNION ALLORDER BY DESCASC の各句を含む HAVING ステートメント。

  2. UNIONUNION ALL は、SQL-92 エントリ レベルをサポートするプロバイダーに対してのみ生成され、ODBC コアをサポートするプロバイダーに対しては生成されません。

  3. SELECT 句:

    • SELECT リスト内のスカラー サブクエリ。

    • AS キーワードを含まない列の別名。

  4. FROM 句:

    • 明示的な結合キーワードは使用されません。コンマ区切りのテーブル名が内部結合を指定するために使用され、外部結合はリモート クエリでは指定されません。

    • FROM ( <nested query> ) <alias>という形式の入れ子になったクエリ。

    • AS キーワードを使用しないテーブルの別名。

  5. WHERE 句では、NOTEXISTSANYALL でサブクエリを使用します。

  6. 式:

    • 使用される集計関数: MIN([DISTINCT])MAX([DISTINCT])COUNT([DISTINCT])SUM([DISTINCT])AVG([DISTINCT])COUNT(*)

    • 比較演算子: <=<=><>>=IS NULLIS NOT NULL

    • ブール演算子: ANDORNOT

  • 算術演算子: +-*/
  1. 定数:
  • 数値リテラルと通貨リテラルは、常に ( ) で囲まれます。

  • 文字リテラルは、引用符 ' ' で囲まれます。

SQL の最小限のレベルをサポートする SQL コマンド プロバイダー

SQL の最小限のレベルをサポートする SQL コマンド プロバイダーに対して、SQL Server では次の文法を使用して SQL が生成されます。

この文法は、ODBC 3.0 で説明されている SQL の最小限の文法を使用して派生しました。 この文法との違いはすべて強調表示されています。 *bold italics* (太字斜体) で示されている項目は、ODBC 3.0 で説明されている SQL の最小限の文法に追加された項目です。 緑色で削除済みと表示されている項目は、この文法から削除された項目です。

select-statement ::=

SELECT [ALL | DISTINCT] *select-list* FROM *table-reference-list*[WHERE *search-condition*] [order-by-clause]

SELECT

select-list ::= * | select-sublist [, select-sublist]...

select-sublist ::= 式 * [alias]*

*alias ::= user-defined-name*

FROM clause

table-reference-list ::= table-reference

テーブル識別子 ::= ユーザー定義名

table-name ::= table-identifier

テーブル参照 ::= table-name

WHERE clause

検索条件 ::= ブール項 [OR 検索条件]

boolean-term ::= boolean-factor [AND boolean-term] (ブール式構文:ブール因子[AND ブール項])

ブール因子 ::= [否定] ブール基数

boolean-primary ::= comparison-predicate | (検索条件)

comparison-predicate (比較述部) ::= expression comparison-operator expression

| expression IS \[NOT\] NULL

comparison-operator ::= < \| > | <= \| >= | = | <>

ORDER BY clause

order-by-clause ::= 注文順句 ORDER BY 並べ替え仕様 [, 並べ替え仕様]...

sort-specification ::= { | column-name } [ASC |DESC]

Common syntactic elements

式 ::= term | 式 {+|--} term

term ::= factor |term {*|/} factor

factor ::= [+|--] primary

primary ::= column-name

文字通り

| (式)

カラム名 ::= [テーブル名.]カラム識別子

リテラル ::= 文字列リテラル

|整数リテラル

|exact-numeric-literal

character-string-literal ::= '{文字}...'

(character は、ドライバーまたはデータ ソースの文字セットに含まれる任意の文字です。 1 つのリテラル引用符文字 (') を character-string-literal に含めるには、リテラル引用符文字を 2 個 ('') 使用します。)

*integer-literal ::=* \[*+ \| -*\] *unsigned-integer*

*exact-numeric-literal::=* \[*+ \| -*\] *unsigned-integer* \[*period unsigned-integer*\]

*\| period unsigned-integer*

base-table-name ::= base-table-identifier

base-table-identifier ::= user-defined-name

列識別子 ::= ユーザー定義名

ユーザー定義名 ::= 文字[数字 | 文字 | _]...

unsigned-integer ::= {digit}...

digit ::= 0 |1 |2 |3 |4 |5 |6 |7 |8 |9

period ::= .

SQL Server 固有のプロパティ

enum SQLPROPERTIES
       {
       SQLPROP_NOHPNEEDED = 0x1,
       SQLPROP_FREETHREADED = 0x2,
       SQLPROP_UMSENABLED = 0x3,
       SQLPROP_NESTEDQUERIES = 0x4,
       SQLPROP_DYNAMICSQL = 0x5,
       SQLPROP_GROUPBY = 0x6,
       SQLPROP_DATELITERALS = 0x7,
       SQLPROP_ANSILIKE = 0x8,
       SQLPROP_INNERJOIN = 0x9,
       SQLPROP_SUBQUERIES = 0x10, 
       SQLPROP_PARALLELSCAN = 0x11,
       SQLPROP_COLUMNCOLLATION = 0x12,
       SQLPROP_CARDINALITY = 0x13,
       SQLPROP_SIMPLEUPDATES = 0x14,
       SQLPROP_SQLLIKE = 0x15,
       SQLPROP_BITREMOTING = 0x16,
       SQLPROP_UNICODELITERALS = 0x17,
       SQLPROP_USELATESTCOLLATIONVERSION = 0x18
       };