SQLite multi insert из C ++ просто добавив первый - PullRequest
3 голосов
/ 06 января 2012

У меня есть следующий код для SQLite:

std::vector<std::vector<std::string> > InternalDatabaseManager::query(std::string query)
{
    sqlite3_stmt *statement;
    std::vector<std::vector<std::string> > results;

    if(sqlite3_prepare_v2(internalDbManager, query.c_str(), -1, &statement, 0) == SQLITE_OK)
    {
        int cols = sqlite3_column_count(statement);
        int result = 0;
        while(true)
        {
            result = sqlite3_step(statement);

            std::vector<std::string> values;
            if(result == SQLITE_ROW)
            {
                for(int col = 0; col < cols; col++)
                {
                    std::string s;
                    char *ptr = (char*)sqlite3_column_text(statement, col);
                    if(ptr) s = ptr;

                    values.push_back(s);
                }
                results.push_back(values);
            } else
            {
                break;
            }
        }

        sqlite3_finalize(statement);
    }

    std::string error = sqlite3_errmsg(internalDbManager);
    if(error != "not an error") std::cout << query << " " << error << std::endl;

    return results;
}

Когда я пытаюсь передать строку запроса, например:

INSERT INTO CpuUsage (NODE_ID, TIME_ID, CORE_ID, USER, NICE, SYSMODE, IDLE, IOWAIT, IRQ, SOFTIRQ, STEAL, GUEST) VALUES (1, 1, -1, 1014711, 117915, 175551, 5908257, 112996, 2613, 4359, 0, 0); INSERT INTO CpuUsage (NODE_ID, TIME_ID, CORE_ID, USER, NICE, SYSMODE, IDLE, IOWAIT, IRQ, SOFTIRQ, STEAL, GUEST) VALUES (1, 1, 0, 1014711, 117915, 175551, 5908257, 112996, 2613, 4359, 0, 0); INSERT INTO CpuUsage (NODE_ID, TIME_ID, CORE_ID, USER, NICE, SYSMODE, IDLE, IOWAIT, IRQ, SOFTIRQ, STEAL, GUEST) VALUES (1, 1, 1, 1014711, 117915, 175551, 5908257, 112996, 2613, 4359, 0, 0); 

В результате просто вставляется первая вставка. Используя какой-нибудь другой инструмент lite SQLiteStudio, он работает нормально.

Есть идеи, чтобы помочь мне, пожалуйста?

Спасибо

Pedro

EDIT

Мой запрос является std :: string.

const char** pzTail;
const char* q = query.c_str();

int result = -1;
do {
    result = sqlite3_prepare_v2(internalDbManager, q, -1, &statement, pzTail);
    q = *pzTail;
}
while(result == SQLITE_OK);

Это дает мне описание: невозможно преобразовать const char * в const char ** для аргумента 5 в int sqlite3_prepare_v2 (sqlite3 *, const char *, int, sqlite3_stmt *, const char *) '

1 Ответ

7 голосов
/ 06 января 2012

SQLite prepare_v2 будет создавать оператор только из первой вставки в вашей строке.Вы можете думать об этом как о «поп-фронте» механизма.

int sqlite3_prepare_v2(
  sqlite3 *db,            /* Database handle */
  const char *zSql,       /* SQL statement, UTF-8 encoded */
  int nByte,              /* Maximum length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);

С http://www.sqlite.org/c3ref/prepare.html

Если pzTail не равен NULL, то * pzTail делается для указания на первый байт после конца первого оператора SQL в zSql.Эти подпрограммы компилируют только первый оператор в zSql, поэтому * pzTail остается указывающим на то, что остается некомпилированным.

Параметр pzTail будет указывать на остальные вставки, поэтому вы можете проходить через них все довсе они были подготовлены.

Другой вариант - делать только одну вставку за раз, что делает остальную часть вашего кода обработки немного проще обычно .

Обычно я видел, как люди совершали подобные вещи под впечатлением, что они будут оцениваться по одной и той же сделке.Это не тот случай, хотя.Второй может потерпеть неудачу, а первый и третий все равно будут успешными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...