2012-01-24 6 views
2

Я играю с библиотекой sqlite3 для C++ в течение нескольких дней, но это вызывает у меня большое разочарование.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 также определяется в другом месте.

Я не хочу использовать sprintf() с CREATE_SQL содержащий %d вместо :NAME_LEN и :OTHER_LEN, потому что я мог бы изменить порядок параметров или добавить новые, и я хотел бы сохранить связывание явным.

Теперь проблема: моя подготовка не возвращает 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 

Что я делаю неправильно? Я уверен, что соединение с базой данных открывается нормально.

+2

У вас есть опечатка: «CRAETE» -> «CREATE». Это может быть не так. – 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); 

Я определенно рекомендую вам избегать замены параметра без значения, если вы не абсолютно придется. Это проблема обслуживания и склонность к ошибкам.

+0

А, я вижу. Вы правы, я просто не понимал, что поля TEXT одинаковы. Спасибо! – StokedOver9k