2

私は C++ 用の sqlite3 ライブラリを数日間しか使っていませんが、かなりのフラストレーションを感じています。

パラメータ化された CREATE TABLE を定義し、後でパラメータをそれにバインドしたいと考えています。次のようになります。

const char[] CREATE_SQL = 
  "CRAETE TABLE t1 ("
  "  name VARCHAR(:NAME_LEN)"
  "  other VARCHAR(:OTHER_LEN)"
  ");";

アイデアは、別のファイル (このヘッダー ファイルへの .cpp) で、これらのパラメーターを次のようにバインドできるということです。

int index = sqlite3_bind_parameter_index(stmt, ":NAME_LEN");
sqlite3_bind_int(stmt, index, _DB_FIELD_SIZE_NAME);

ここで、_DB_FIELD_SIZE_NAME は別の場所でも定義されています。

パラメーターの順序を変更したり、新しいパラメーターを追加したりする可能性があり、バインドを明示的に維持したいため、andの代わりに含むsprintf()と一緒に使用したくありません。CREATE_SQL%d:NAME_LEN:OTHER_LEN

ここで、問題について説明します。私の準備は を返しませんSQLITE_OKが、 の null ポインターになりsqlite3_stmtます。ここに私が持っているものがあります:

sqlite3_stmt *stmt;
const char *pStmt = 0;
if( SQLITE_OK != sqlite3_prepare_v2(*db, CREATE_SQL, -1, &stmt, &pStmt) )
    // throws exception with the sqlite3_errmsg(*db) text

だから、私が得ているエラーはこれです:

near ":NAME_LEN": syntax error

私は何を間違っていますか?データベース接続が正常に開くと確信しています。

4

1 に答える 1

0

あなたの質問に答えないために、sqlite には厳密なテキスト列のサイズ設定がありません。互換性のために VARCHAR 型を受け入れますが、動作に違いはありません。

あなたは常にこれに相当するものになります:

const char *sql = 
  "CREATE TABLE t1 ("
  "  name TEXT"
  "  ,other TEXT"
  ");";

あなたの質問に答えるために、私はあなたがこれをすることを許されているとは思わない。Sqlite の置換メカニズムは、通常は値パラメーターと見なされるものに対してのみ機能します。

たとえば、 INSERTorステートメントで通常見られるもの。UPDATE

const char *sql = "INSERT INTO foo (a,b) VALUES (?1,?);";

CREATEおそらくデフォルトのパラメータのために、ステートメントでそれらを実行できるかどうか覚えていませんか? お久しぶりです。

boost::format値以外のパラメーターを変更する必要がある場合に、私が試した他のどのソリューションよりも、破損してより明確なコードを作成する可能性がはるかに低いことがわかりました。

#include <boost/format.hpp>

// ... 

int instance_id = 42;
const char *sql = "CREATE TABLE type_%1% (a,b);";
boost::str( boost::format(sql) % instance_id );

絶対に必要でない限り、値のないパラメーターの置換を避けることを強くお勧めします。メンテナンスが面倒で、エラーが発生しやすいです。

于 2012-01-24T21:38:32.230 に答える