0

In most examples for SOCI, the caller must know the fields and types in a query and specifies them through a soci::rowset<> of boost::tuple<> or through some other means.

Is there a way to code without knowing the types and number of columns beforehand, as in a SELECT * FROM ... query?

If so, could you post a short example?

4

2 に答える 2

3

soci::rowset<soci::row>まさに必要なものです —soci::row動的バインディングを提供します。

ドキュメントから:

特定のアプリケーションでは、任意に構造化されたテーブルからデータを選択し (たとえば、"select * from ..." を介して)、結果のデータをその型に基づいてフォーマットできることが望ましい場合があります。SOCI は、soci::row および soci::column_properties クラスを通じてこれをサポートします。

見る:

http://soci.sourceforge.net/doc/3.2/exchange.html#dynamic
http://soci.sourceforge.net/doc/3.2/statements.html#rowset

詳細については。

ドキュメントからの抜粋:

たとえば、次のコードは、任意のテーブルから選択されたデータ行から XML ドキュメントを作成します。

row r;
sql << "select * from some_table", into(r);

std::ostringstream doc;
doc << "<row>" << std::endl;
for(std::size_t i = 0; i != r.size(); ++i)
{
    const column_properties & props = r.get_properties(i);

    doc << '<' << props.get_name() << '>';

    switch(props.get_data_type())
    {
    case dt_string:
        doc << r.get<std::string>(i);
        break;
    case dt_double:
        doc << r.get<double>(i);
        break;
    case dt_integer:
        doc << r.get<int>(i);
        break;
    case dt_long_long:
        doc << r.get<long long>(i);
        break;
    case dt_unsigned_long_long:
        doc << r.get<unsigned long long>(i);
        break;
    case dt_date:
        std::tm when = r.get<std::tm>(i);
        doc << asctime(&when);
        break;
    }

    doc << "</" << props.get_name() << '>' << std::endl;
}
doc << "</row>";

row::get() に渡す必要があるタイプ T パラメーターは、column_properties::get_data_type() から返される SOCI データ型によって異なります。

于 2012-10-31T09:14:35.000 に答える
0

方法はないと思います。おそらく「select *」は一般的に危険と見なされているためです。列を追加したり、並べ替えたりすることができ、クエリは壊れています。将来の自分のデバッグを保存し、列をリストします。

于 2012-10-31T01:30:48.443 に答える