2012-01-24 8 views
2

私は数日間、C++用のsqlite3ライブラリで遊んできましたが、それは私に大きな欲求不満をもたらしています。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他の場所でも定義されています。

私は、パラメータの順序を変更したり、新しいものを追加し、私は結合明示を維持したいかもしれないので、代わりに:NAME_LEN:OTHER_LEN%dを含むCREATE_SQLsprintf()を使用する必要はありません。

問題:私の準備はSQLITE_OKを返しませんでしたが、結果として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 

何をしているのですか?私はデータベース接続がOKを開くと確信しています。

+2

あなたがタイプミスを持っています。これは間違っている可能性があります。 – zwol

答えて

0

質問に答えないように、sqliteには厳密なテキスト列サイズ設定がありません。互換性のためにVARCHAR型を受け取りますが、その振る舞いには違いはありません。

あなたはいつもこれに同等なものになってしまいます:

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

は、あなたの質問に答えるために、私はあなたがこれを行うには許可されているとは思いません。 Sqliteの置換メカニズムは、通常は値のパラメータとみなされるものに対してのみ機能します。あなたは一般的に、たとえば、INSERTまたは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); 

私は間違いなくあなたは絶対にのにを持っていない限り、非値パラメータの交換を行うことを避けることをお勧めします。メンテナンスが面倒でエラーが起こりやすいです。 - > "CREATE" "CRAETE":

+0

ああ、そうだ。あなたは正しいです、私はちょうど 'TEXT'フィールドがすべて同じであることを認識しませんでした。 ありがとうございました! – StokedOver9k

関連する問題