Страница 1 из 1
Вставка записей в таблицу из процедуры
Добавлено: 17 апр 2008, 18:35
Ingwar
Есть хранимая процедура с кодом:
Код: Выделить всё
FOR SELECT T_ID, SERT, TERM, CNT... FROM INDETAILS WHERE I_ID=-:GVI_ INTO :T_ID_, :SERT_, :TERM_, :CNT_... DO
BEGIN
SELECT COUNT(*) FROM STORAGE WHERE T_ID=:T_ID_ AND PRICE_RDR=:PRICE_RDR_ INTO :C_;
IF (C_=0) THEN
INSERT INTO STORAGE (...) VALUES (...);
ELSE
UPDATE STORAGE SET ... WHERE T_ID=:T_ID_ AND PRICE_RDR=:PRICE_RDR_;
END
То есть в цикле при каждой итерации цикла в таблице STORAGE должна или обновиться существующая запись, или вставиться новая. Но иногда новая запись не вставляется, хотя никакого исключения не возникает.
В чем может быть проблема?
Сервер Firebird 2.0
Добавлено: 17 апр 2008, 21:38
Slavik
Попробуй другой вариант:
Код: Выделить всё
update STORAGE set ... where ...;
if (row_count = 0) then insert into STORAGE (...) values (...);
Добавлено: 17 апр 2008, 21:56
Ingwar
Попробуй другой вариант
Спасибо, попробую

Re: Вставка записей в таблицу из процедуры
Добавлено: 17 апр 2008, 21:58
WildSery
Ingwar писал(а):В чем может быть проблема?
Вероятно, в непонимании терминов "версионность" и "уровень изоляции транзакций".
Re: Вставка записей в таблицу из процедуры
Добавлено: 17 апр 2008, 22:27
Ingwar
WildSery писал(а):Вероятно, в непонимании терминов "версионность" и "уровень изоляции транзакций".
Перед началом указанной операции транзакция подтверждается, и в конце- также. Правда, подтверждается методом CommitRetaining.
Параметры транзакции (Read Commited):
read_committed
rec_version
nowait
Буду благодарен если укажете в чем непонимание
Добавлено: 18 апр 2008, 08:47
kdv
Re: Вставка записей в таблицу из процедуры
Добавлено: 18 апр 2008, 11:52
WildSery
Ingwar писал(а):Буду благодарен если укажете в чем непонимание
Читай указанные Дмитрием статьи, и размышляй, в каких случаях
select count(*) from в многопользовательской среде может показать не то что ожидаешь.
Добавлено: 18 апр 2008, 22:31
Ingwar
Спасибо за коррекции самого запроса на вставку/ обновление. Но проблема наверное не в "непонимании"- с сутью использования транзакций я давно знаком.
Указанная проблема (т.е. "пропадание" записей, которые должны вставляться в таблицу) проявлялась даже в тех случаях, когда записей в таблице STORAGE заведомо не существовало, поэтому другие транзакции никак не могли повлиять на цикл, и запрос SELECT COUNT(*) должен бы возвращать гарантированно ноль. Но в таких случаях иногда новые записи не вставлялись.
У меня возникла идея о погрешности в связи с округлением- в поле PRICE_RDR типа DECIMAL(15, 2) записана цена. Может такое быть?
Добавлено: 18 апр 2008, 22:44
WildSery
Ingwar писал(а):У меня возникла идея о погрешности в связи с округлением- в поле PRICE_RDR типа DECIMAL(15, 2) записана цена. Может такое быть?
Думаю, нет. Если записи нет, то хоть какое условие ставь, она не появится, и count(*) вернёт 0.
Возможно, что проблема у тебя вообще не в этом месте. Внимательно осмотрись на предмет триггеров на эту таблицу, или удаление этой записи дальше в процедуре/цепочке процедур, а также ловли эксепшенов в приложении.
Например, не может такого быть, что вставка вернула ошибку, а ты её в программе втихую "проглотил"?
Добавлено: 19 апр 2008, 19:24
Ingwar
Спасибо всем кто откликнулся...
Из всего сказаного я понял что дело в другом месте... По крайней мере уверился, что с процедурой все нормально