Предложение FOR UPDATE вызывает ошибку в программе esql

Мы разрабатываем программу миграции. В БД почти 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 показывает правильное использование.

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

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


person Liju Mathew    schedule 22.02.2010    source источник
comment
Функция memset () избыточна. Если все, что вам нужно сделать, это установить значения частоты и статуса равными нулю, почему бы не сделать простой оператор без выборки: UPDATE MyTable SET (frequency, status) = (0, 0);? Вы можете добавить «ГДЕ номер› =? И число ‹=? ' предложение тоже, если оно вам нужно (с 80 миллионами строк, вероятно, будет целесообразным).   -  person Jonathan Leffler    schedule 22.02.2010
comment
Мы показали это в качестве примера, но на самом деле есть некоторая логика, которую нужно проделать со значением. В настоящее время есть только 1 столбец "Частота". Мы должны разделить данные по частоте на столбцы частоты и статуса. Например: если частота равна 1, мы должны установить 01 для частоты и 00 для статуса. Итак, мы должны делать это при каждой трансляции.   -  person Liju Mathew    schedule 23.02.2010


Ответы (1)


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

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

Вам необходимо добавить НАЧАЛО РАБОТЫ, прежде чем открывать курсор с предложением FOR UPDATE. Затем вам нужно решить, следует ли периодически фиксировать транзакции, чтобы избежать слишком длительных транзакций. Тот факт, что вы используете курсор FOR HOLD, показывает, что вы думали об использовании суб-транзакций; если бы вы не собирались этого делать, вы бы не использовали это предложение.

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

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

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

person Jonathan Leffler    schedule 22.02.2010