Предложение FOR UPDATE выдает ошибку в программе esql - PullRequest
1 голос
/ 22 февраля 2010

Мы разрабатываем программу миграции. В БД находится около 80 миллионов записей. Код выглядит следующим образом:

static int mymigration(struct progargs *args) 
{
  exec sql begin declare section;
    const char *selectQuery;
    const char *updateQuery;
    long cur_start;
    long cur_end;
    long serial;
    long number;
    char frequency[3];
  exec sql end declare section;

    selectQuery = "select * from mytable where number >= ? and number <= ? for update of frequency ,status";
    updateQuery = "update mytable set frequency = ?, "
    " status = ? "
    " where current of my_cursor";

    cur_start= args->start;
    cur_end = args->end;

    exec sql prepare my_select_query from :selectQuery;
    /* Verify the sql code for error here */

    exec sql declare my_select_cursor cursor with hold for my_select_query;

    exec sql open my_select_cursor using :cur_start, :cur_end;
    /* Verify the sql code for error here */

    exec sql prepare my_update_query from :updateQuery;
    /* Verify the sql code for error here */        

    while (1)
    {
            number = 0;
            serial = 0;
            memset(frequency,0,sizeof(frequency));

            exec sql fetch my_select_cursor into number,:serial,:frequency;
            if (sqlca.sqlcode != SQL_OK)
                    break;            

            exec sql execute my_update_query using :frequency, :frequency;

    }      
    exec sql close my_select_trade_cursor;

}

При реализации этого мы получаем сообщение об ошибке «-255». Мы нашли одно решение - добавить работу и зафиксировать работу. Поскольку у нас большой объем данных, это может загромождать журнал транзакций.

Есть ли другое решение для этой проблемы? На веб-сайте IBM для informix показано правильное использование.

Заранее признателен за помощь.

Спасибо, Мэтью Лию

1 Ответ

0 голосов
/ 22 февраля 2010

Ошибка -255: «Не в транзакции».

Я не вижу операторов BEGIN WORK (или COMMIT WORK или ROLLBACK WORK).

Вам необходимо добавить BEGIN WORK, прежде чем открывать курсор с помощью предложения FOR UPDATE. Затем вам нужно решить, следует ли совершать периодически, чтобы избежать чрезмерных транзакций. Тот факт, что вы используете курсор FOR HOLD, показывает, что вы думали об использовании субтранзакций; если бы вы не собирались это делать, вы бы не использовали это предложение.

Обратите внимание, что Informix имеет 3 основных режима ведения журнала базы данных:

  • Unlogged (без поддержки транзакций)
  • Записано (по умолчанию каждый оператор является одноэлементной транзакцией; явный BEGIN WORK запускает транзакцию с несколькими операторами, завершаемую COMMIT WORK или ROLLBACK WORK).
  • Зарегистрированный режим ANSI (немного упрощенно, вы автоматически участвуете в транзакции; вам нужен явный COMMIT или ROLLBACK, чтобы завершить транзакцию, и затем он может, необязательно, использовать явный BEGIN, но BEGIN на самом деле не нужен). 1014 *

Исходя из описанных вами симптомов, у вас есть зарегистрированная, но не MODE ANSI база данных. Поэтому вы должны явно кодировать операторы BEGIN WORK.

...