Как обновить и выбрать в одном запросе SQL - PullRequest
0 голосов
/ 02 октября 2018

У меня есть следующая функция, которая должна обновлять, а затем извлекать строку таблицы:

MyEntity setRemoteMyEntityGUIGByMyEntityGUID(long myEntityGUID, long remoteMyEntityGUID) {

    sqlite3 *db = myDb();

    sqlite3_stmt *stmt;

    char *sql = "UPDATE ENTITY_TABLE "
                "SET  REMOTE_ENTITY_GUID = ? " \
                "WHERE ENTITY_GUID = ?; " \
                 "SELECT " \
                 "ENTITY_GUID, " \
                 "ENTITY_TYPE, " \
                 "COLUMN_NAME_UPDATED_DATE " \
                 "FROM ENTITY_TABLE WHERE " \
                 "ENTITY_GUID = ?";

    int rc = sqlite3_prepare(db, sql, -1, &stmt, 0);

    sqlite3_bind_int(stmt, 1, remoteMyEntityGUID);
    sqlite3_bind_int(stmt, 2, myEntityGUID);
    sqlite3_bind_int(stmt, 3, myEntityGUID);

    if (rc != SQLITE_OK) {
        fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));

        __android_log_print(ANDROID_LOG_ERROR, "MyApp", "ERR : %s", sqlite3_errmsg(db));
    }

    rc = sqlite3_step(stmt);

    MyEntity myEntity;

    if (rc == SQLITE_ROW) {

        myEntityGUID = sqlite3_column_int(stmt, 0);
        char *myEntityType = strdup((const char *) sqlite3_column_text(stmt, 6));
        char *timeUpdated = strdup((const char *) sqlite3_column_text(stmt, 9));

        myEntity._myEntityGUID = myEntityGUID;
        myEntity._myEntityType = myEntityType;
        myEntity._timeUpdated = timeUpdated;

        sqlite3_finalize(stmt);
        sqlite3_close(db);
    }

    return myEntity;
}

Однако она выполняет только одно из двух: обновлять или извлекать строку таблицы:

char *sql = "UPDATE ENTITY_TABLE "
                "SET  REMOTE_ENTITY_GUID = ? " \
                "WHERE ENTITY_GUID = ?" ;  

ИЛИ

char *sql = "SELECT " \
                 "ENTITY_GUID, " \
                 "ENTITY_TYPE, " \
                 "COLUMN_NAME_UPDATED_DATE " \
                 "FROM ENTITY_TABLE WHERE " \
                 "ENTITY_GUID = ?";  

Это не будет работать полностью, но первая (обновление) часть будет:

char *sql = "UPDATE ENTITY_TABLE "
                "SET  REMOTE_ENTITY_GUID = ? " \
                "WHERE ENTITY_GUID = ?; " \
                 "SELECT " \
                 "ENTITY_GUID, " \
                 "ENTITY_TYPE, " \
                 "COLUMN_NAME_UPDATED_DATE " \
                 "FROM ENTITY_TABLE WHERE " \
                 "ENTITY_GUID = ?";  

Чтоя делаю не так?Как я могу заставить его работать?

1 Ответ

0 голосов
/ 02 октября 2018

Таким образом, поскольку вы можете использовать только один оператор SQL для каждого подготовленного оператора, вы должны разбить его на две части:

  • Подготовить оператор обновления.
  • Привязать все необходимоепараметры для него.
  • Выполните его с помощью sqlite3_step() (возвращает SQLITE_DONE, чтобы указать успех или код ошибки).
  • Отмените выделение подготовленного оператора с помощью sqlite3_finalize().
  • Подготовьте оператор выбора.
  • Свяжите все необходимые параметры для него.
  • Выполните его с помощью sqlite3_step().
  • Поскольку похоже, что вы получаете только одну строку назад, если sqlite3_step() вернул SQLITE_ROW, сделайте все, что вам нужно сделать с выбранными столбцами из этой строки.
  • Отмените выделение подготовленного оператора.
  • Включите соответствующую проверку и обработку ошибок во всевыше.

(Вы уже делаете большую часть этого; его просто нужно адаптировать к двум подготовленным утверждениям)

Вы также хотите убедиться, что вы не используетезаявления, если их подготовка не удалась - в вашем текущем коде уВы связываете параметры даже перед проверкой возвращаемого значения sqlite3_prepare().Я также предлагаю использовать sqlite3_prepare_v2() вместо этого - более старый sqlite3_prepare(), чтобы процитировать документацию , "является устаревшим и его следует избегать".

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