OLE DB コマンドを作成します。
構文
[ db_command(command, name, source_name, hresult, bindings, bulk_fetch) ]
パラメーター
command
OLE DB コマンドのテキストを含むコマンド文字列。 簡単な例を次に示します。
[ db_command ( command = "Select * from Products" ) ]
command構文は次のとおりです。
バインドするパラメーター ブロック 1
OLE DB コマンド
バインドするパラメーター ブロック 2
OLE DB コマンドの続き
バインドするパラメーター ブロック 3
...
binding parameter block は次のように定義します。
(bindtypeszVar1 [,szVar2 [,nVar3 [,...]]])
どこで:
(は、データ バインディング ブロックの先頭をマークします。bindtypeは、大文字と小文字を区別しない次のいずれかの文字列です。[db_column]は、各メンバー変数を行セット内の列にバインドします。[bindto]([db_column]と同じです)。[in]は、メンバー変数を入力パラメーターとしてバインドします。[out]は、メンバー変数を出力パラメーターとしてバインドします。[in,out]は、メンバー変数を入力/出力パラメーターとしてバインドします。
szVarN、 nVarN 現在のスコープ内のメンバー変数に解決されます。
)は、データ バインディング ブロックの末尾をマークします。
コマンド文字列に、 [in]、 [out]、 [in/out]などの 1 つ以上の指定子が含まれている場合は、パラメーター マップ db_command ビルドされます。
コマンド文字列に [db_column] や [bindto] などの 1 つ以上のパラメーターが含まれている場合、 db_command は、これらのバインドされた変数をサービスするために行セットとアクセサー マップの両方を生成します。 詳細については、「db_accessor」を参照してください。
Note
bindtype 構文と bindings パラメーターは、クラス レベルで db_command を使用する場合は無効です。
バインディング パラメーター ブロックの例を次にいくつか示します。 次の例では、pubs データベースの authors テーブルのau_fname列とau_lname列に、m_au_fnameとm_au_lnameのデータ メンバーをそれぞれバインドします。
TCHAR m_au_fname[21];
TCHAR m_au_lname[41];
TCHAR m_state[3] = 'CA';
[db_command (command = "SELECT au_fname([bindto]m_au_fname), au_lname([bindto]m_au_lname) " \
"FROM dbo.authors " \
"WHERE state = ?([in]m_state)")
]
name
(省略可能) 行セットの操作に使用するハンドルの名前。 nameを指定した場合、db_commandは指定されたnameを持つクラスを生成します。これは、行セットを走査したり、複数のアクション クエリを実行したりするために使用できます。 nameを指定しない場合、複数行の結果をユーザーに返すことはできません。
source_name
(省略可能) コマンドが実行される db_source 属性が適用されているクラスの CSession 変数またはインスタンス。 以下を参照してください。db_source
db_command は、 source_name に使用される変数が有効であることを確認するため、指定された変数が関数スコープまたはグローバル スコープ内に存在することを確認します。
hresult
(省略可能) このデータベース コマンドの HRESULT を受け取る変数を識別します。 変数が存在しない場合は、属性によって自動的に挿入されます。
bindings
(省略可能) OLE DB コマンドからバインディング パラメーターを分離できます。
bindingsの値を指定した場合、db_commandは関連付けられた値を解析し、bindtype パラメーターは解析しません。 これにより、OLE DB プロバイダーの構文を使用できます。 バインド パラメーターを指定せずに解析を無効にするには、 Bindings=""を指定します。
bindingsの値を指定しない場合、db_commandはバインド パラメーター ブロックを解析します。 "(" が検索され、その後に角かっこで囲まれた bindtype が続き、前に宣言された 1 つ以上の C++ メンバー変数が続き、その後に ')' が続きます。 結果のコマンドからかっこの間のすべてのテキストが削除されます。 これらのパラメーターは、このコマンドの列とパラメーターのバインドを構築するために使用されます。
bulk_fetch
(省略可能) フェッチする行数を指定する整数値。
既定値は 1 で、1 行のフェッチを指定します (行セットは CRowset型になります)。
1 より大きい値は、バルク行フェッチを指定します。 一括行フェッチとは、複数の行ハンドルをフェッチする一括行セットの機能を指します (行セットは CBulkRowset 型になり、指定した行数で SetRows を呼び出します)。
bulk_fetchが 1 未満の場合、SetRowsは 0 を返します。
解説
db_command は、OLE DB コンシューマーがコマンドを実行するために使用する CCommand オブジェクトを作成します。
クラススコープまたは関数スコープで db_command を使用できます。主な違いは、 CCommand オブジェクトのスコープです。 関数スコープでは、バインディングなどのデータは関数の終了時に終了します。 クラスと関数のいずれのスコープを使用しても OLE DB コンシューマー テンプレート クラスの CCommand<> が関係しますが、テンプレート引数は関数とクラスのスコープで異なります。 関数の場合、バインディングはローカル変数を構成する Accessor に対して行われますが、クラスを使用すると引数として CAccessor 派生クラスが予期されます。 クラス属性として使用する場合、 db_command は db_columnと連携します。
db_command は、結果セットを返さないコマンドを実行するために使用できます。
コンシューマー属性プロバイダーがこの属性をクラスに適用すると、コンパイラはクラスの名前を _[YourClassName]Accessor に変更します。ここで、 [YourClassName] はクラスに指定した名前です。 コンパイラは、_[YourClassName]Accessorから派生する [YourClassName] というクラスも作成します。 クラス ビューには、両方のクラスが表示されます。
例
この例では、テーブルから state 列が 'CA' と一致する姓と名を選択するコマンドを定義しています。 db_commandでは、OpenAllやCloseAllなどのウィザードで生成された関数や、MoveNext などのメンバー関数CRowset呼び出すことができる行セットが作成および読み取られます。
このコードでは、pubs データベースに接続する独自の接続文字列を提供する必要があります。 開発環境で接続文字列を提供する方法については、「方法: データベースに接続し、既存のオブジェクトを参照する方法新しい接続を追加するを参照してください。
ソース ファイル db_command.h:
// db_command.h
#include <atlbase.h>
#include <atlplus.h>
#include <atldbcli.h>
#pragma once
[ db_source(L"your connection string"), db_command(L" \
SELECT au_lname, au_fname \
FROM dbo.authors \
WHERE state = 'CA'") ]
struct CAuthors {
// In order to fix several issues with some providers, the code below may bind
// columns in a different order than reported by the provider
DBSTATUS m_dwau_lnameStatus;
DBSTATUS m_dwau_fnameStatus;
DBLENGTH m_dwau_lnameLength;
DBLENGTH m_dwau_fnameLength;
[ db_column("au_lname", status="m_dwau_lnameStatus", length="m_dwau_lnameLength") ] TCHAR m_au_lname[41];
[ db_column("au_fname", status="m_dwau_fnameStatus", length="m_dwau_fnameLength") ] TCHAR m_au_fname[21];
[ db_param("7", paramtype="DBPARAMIO_INPUT") ] TCHAR m_state[3];
void GetRowsetProperties(CDBPropSet* pPropSet) {
pPropSet->AddProperty(DBPROP_CANFETCHBACKWARDS, true, DBPROPOPTIONS_OPTIONAL);
pPropSet->AddProperty(DBPROP_CANSCROLLBACKWARDS, true, DBPROPOPTIONS_OPTIONAL);
}
};
ソース ファイル db_command.cpp:
// db_command.cpp
// compile with: /c
#include "db_command.h"
int main(int argc, _TCHAR* argv[]) {
HRESULT hr = CoInitialize(NULL);
// Instantiate rowset
CAuthors rs;
// Open rowset and move to first row
strcpy_s(rs.m_state, sizeof(rs.m_state), _T("CA"));
hr = rs.OpenAll();
hr = rs.MoveFirst();
// Iterate through the rowset
while( SUCCEEDED(hr) && hr != DB_S_ENDOFROWSET ) {
// Print out the column information for each row
printf("First Name: %s, Last Name: %s\n", rs.m_au_fname, rs.m_au_lname);
hr = rs.MoveNext();
}
rs.CloseAll();
CoUninitialize();
}
この例では、データ ソース クラス db_source で CMySourceを使用し、コマンド クラス db_command と CCommand1 で CCommand2を使用します。
// db_command_2.cpp
// compile with: /c
#include <atlbase.h>
#include <atlplus.h>
#include <atldbcli.h>
// class usage for both db_source and db_command
[ db_source(L"your connection string"), db_command(L" \
SELECT au_lname, au_fname \
FROM dbo.authors \
WHERE state = 'CA'") ]
struct CMySource {
HRESULT OpenDataSource() {
return S_OK;
}
};
[db_command(command = "SELECT * FROM Products")]
class CCommand1 {};
[db_command(command = "SELECT FNAME, LNAME FROM Customers")]
class CCommand2 {};
int main() {
CMySource s;
HRESULT hr = s.OpenDataSource();
if (SUCCEEDED(hr)) {
CCommand1 c1;
hr = c1.Open(s);
CCommand2 c2;
hr = c2.Open(s);
}
s.CloseDataSource();
}
要件
| 属性コンテキスト | 値 |
|---|---|
| 適用対象 | class、struct、メンバー、メソッド、ローカル |
| 反復可能 | いいえ |
| 必要な属性 | なし |
| 無効な属性 | なし |
属性コンテキストの詳細については、「 Attribute コンテキスト」を参照してください。