2016-06-08 4 views
1

Мы анализируем поведение Informix в производстве. При попытке обновить строку, которая отсутствует, приложение получает сообщение «-346: Не удалось обновить строку в таблице».Informix не бросает ошибку при попытке обновить строку, которой нет?

Однако, когда мы пытаемся сделать то же самое в области dev, приложение работает нормально.

Должен ли Informix всегда бросать ошибку при обновлении строки, которая отсутствует или настраивается на уровне Informix?

Приложение написано на C, и соответствующие запросы обновления присутствуют в программе «.ec».

Кроме того, есть ли другой способ, которым Informix выдает ошибку -346?

Edit: The SQL is as follows:

update <table> set serial_number = <number1> where serial_number = <number2> 

The SQL Error is:

Execute SQL ERROR 

    SQL CODE = -346 
    SQLERM = 
    SQLERRP = 
    SQLERRD[0] = 1 
    SQLERRD[1] = -100 
    SQLERRD[2] = 0 
    SQLERRD[3] = 1 
    SQLERRD[4] = 56 
    SQLERRD[5] = 0 
    SQLWARN = 

Редактировать снова:

Исходный код выглядит следующим образом:

const char *sql = "update table_not_named set serial_number = ? where serial_number = ?"; 

if (prepared_sql == 0) 
{ 
    exec sql prepare update_sql from :sql; 
    if (sqlca.sqlcode != SQL_OK) 
    { 
     logSqlError(log_err, __func__, "Prepare"); 
     return FAIL; 
    } 
    prepared_sql = 1; 
} 

exec sql execute update_sql using :db_new_serial_number, :db_old_serial_number; 

if (sqlca.sqlcode != SQL_OK) 
{ 
    logSqlError(log_err, __func__, "Execute"); 
    return FAIL; 
} 
+0

Ошибка -346 не является проблемой при наличии/отсутствии. Инструкции от 'finderr -346' say _ Пока сервер базы данных обрабатывал UPDATE, он получил непредвиденную ошибку . Проверьте сопроводительный код ошибки ISAM для получения дополнительной информации о причине . Возможные причины включают аппаратное обеспечение ошибки и блокировку конфликтов. Для получения дополнительной информации вам необходимо отслеживать ошибку ISAM ('sqca.sqlerrd [1]' в ESQL/C); это должен быть номер ошибки с абсолютным значением от 100 до 199. Это, вероятно, означает, что в вашей производственной системе есть какая-то проблема. Показать SQL. –

+0

Обратите внимание, что обновление несуществующей строки с запрошенным UPDATE должно просто сообщать об обновлении нулевых строк. В базе данных MODE ANSI вы получите статус 100 (SQLNOTFOUND) вместо 0 (без ошибок). Если вы делаете обновление WHERE CURRENT OF, и строка не пропала, то происходит что-то странное: этого не должно быть (потому что это означает, что вы не получили блокировку строки, когда вы ее выбрали, но кто-то удалось удалить строку, даже если вы ее заблокировали). Если вы не использовали предложение FOR UPDATE, то WHERE CURRENT OF должен иметь определенную ошибку. –

+0

Спасибо, Джонатан. Я также обновил ошибку SQL. Мы не уверены, создана ли наша Informix DB в ANSI MODE или нет. –

ответ

1

Комментарии становятся слишком большими, чтобы быть комментарии - на довольно края.

Ошибка -346 не является проблемой при наличии/отсутствии. Инструкции от finderr -346 говорят:

While the database server was processing an UPDATE, it received an unexpected error. Check the accompanying ISAM error code for more detailed information on the cause. Possible causes include hardware errors and locking conflicts.

Вам нужно будет отслеживать ошибки ISAM (sqca.sqlerrd [1] в ESQL/C), чтобы получить более подробную информацию; это должен быть номер ошибки с абсолютным значением от 100 до 199. Это, вероятно, означает, что в вашей производственной системе есть какая-то проблема.

Обратите внимание, что обновление несуществующей строки с запрошенным UPDATE должно просто сообщать о нулевых строках, обновленных успешно. В базе данных MODE ANSI вы получите статус 100 (SQLNOTFOUND) вместо 0 (без ошибок). Если вы делаете обновление WHERE CURRENT OF, и строка не пропала, то происходит что-то странное: этого не должно быть (потому что это означает, что вы не получили блокировку строки, когда вы ее выбрали, но кто-то удалось удалить строку, даже если вы ее заблокировали). Если вы не использовали предложение FOR UPDATE, тогда WHERE CURRENT OF должен иметь более конкретную ошибку.

На этом этапе вопрос был обновлен, чтобы отобразить информацию об ошибке.

Любопытное сообщение: Я побежал

create table sample 
(
    serial_number integer not null primary key, 
    value varchar(30) not null 
); 
insert into sample values(123, 'one hundred and twenty-three'); 
update sample set serial_number = 124 where serial_number = 99; 

, который дает статус 0 (и отчеты 0 строк обновленному). Ваше сообщение имеет -100 как ошибку ISAM; это сообщение для «Ошибка ISAM: дублирующее значение для записи с уникальным ключом».

Но когда я пытаюсь:

insert into sample values(99, 'ninety-nine'); 
update sample set serial_number = 123 where serial_number = 99; 

Я получаю сообщение об ошибке:

SQL -268: Unique constraint (jleffler.u160_350) violated. 
ISAM -100: ISAM error: duplicate value for a record with unique key. 

Вот о чем я ожидал.Я отмечаю, что вы не можете напрямую обновлять столбец типа SERIAL (или SERIAL8 или BIGSERIAL): вы получаете SQL -232: A SERIAL column (s) may not be updated (где s было именем последовательного столбца, который я пытался обновить, чтобы сгенерировать сообщение - это не плохое число в сообщение).

Поскольку первичное сообщение об ошибке -346 указывает на то, что в базе данных может быть проблема, было бы целесообразно запустить в системе ON-Check (oncheck), чтобы убедиться, что эта таблица в порядке. Если у вас нет привычки запускать ON-Check, вам нужно будет найти варианты. Я, вероятно, проведу некоторые общие проверки (например, oncheck -cr, чтобы проверить зарезервированные страницы), прежде чем продолжать проверять таблицу и индексы, в которых возникает проблема (oncheck -ci и oncheck -cd). Для получения дополнительной информации можно использовать -cR, -cI, -cD.

+0

Большое вам спасибо за подробное объяснение. У меня нет разрешения на запуск «oncheck», и я запросил помощь в DBA. Ваше объяснение помогло передать сообщение о том, насколько серьезной может быть проблема.Еще раз спасибо, и я обновлю ошибку, полученную из приведенных выше команд. –

+0

Справедливо. Можете ли вы воспроизвести проблему с другими таблицами или просто с одной таблицей? Можете ли вы создать аналогичную таблицу в производственной базе данных и столкнуться с этой проблемой? –

+0

У меня нет доступа к продуктам, и я не могу сделать много R & D там из-за огромного объема данных. В области dev его не воспроизводимо. Во всяком случае, завтра у меня будет DBA, и он может найти что-то из ваших комментариев, я надеюсь. –

Смежные вопросы