Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Вниз

Ошибка при выполнении ХП   Найти похожие ветки 

 
Виталий Панасенко   (2009-04-17 16:54) [0]

При выполнении простенькой, казалось бы ХП, получаю эксцепшн
the cursor identified in the update or delete statement is not positioned on a row.

В инете нашел(тут, например http://www.sql.ru/forum/actualthread.aspx?tid=283188), что данная ошибка возникала в ФБ при смешивании явных и неявных джоинов или таблиц с ХП. Но в моем случае ХП на изменение.

CREATE PROCEDURE DOC_UPD (
   id bigint,
   num_id varchar(10),
   summa numeric(15,2),
   doc_status smallint,
   period_beg varchar(6),
   period_end varchar(6),
   opis_id bigint,
   client_id bigint,
   sujet varchar(50))
as
begin
 update doc
 set num_id = :num_id,
     summa = :summa,
     period_beg = :period_beg,
     period_end = :period_end,
     doc_status = :doc_status,
     --srok_date = :srok_date,
     opis_id = :opis_id,
     client_id = :client_id,
     --doc_date = :doc_date,
     sujet = :sujet
 where (id = :id);
end

Структура таблицы

CREATE GENERATOR GEN_DOC_ID;

CREATE TABLE DOC (
   ID             BIGINT NOT NULL,
   NUM_ID         VARCHAR(10) NOT NULL COLLATE WIN1251_UA,
   SUMMA          CURRENCY /* CURRENCY = NUMERIC(15,2) DEFAULT 0 NOT NULL */,
   DOC_STATUS     SMALLINT DEFAULT 0,
   PERIOD_BEG     VARCHAR(6) NOT NULL COLLATE WIN1251_UA,
   PERIOD_END     VARCHAR(6) NOT NULL COLLATE WIN1251_UA,
   MONTHSBETWEEN  SMALLINT,
   SROK_DATE      DATE,
   FULL_SUMMA     COMPUTED BY (summa * monthsbetween),
   OPIS_ID        BIGINT DEFAULT 1 NOT NULL,
   CLIENT_ID      BIGINT NOT NULL,
   DOC_DATE       DATE NOT NULL,
   USER_ID        VARCHAR(32) DEFAULT current_user NOT NULL,
   SUJET          VARCHAR(50) COLLATE WIN1251_UA,
   REPSTATUS      SMALLINT DEFAULT 0 NOT NULL,
   DOC_NUM        BIGINT
);

/******************************************************************************/
/***                              Primary Keys                              ***/
/******************************************************************************/

ALTER TABLE DOC ADD CONSTRAINT PK_DOC PRIMARY KEY (ID);

И самый больший прикол, что изменение значение поля DOC_STATUS с 1 на 2 происходит без проблем, а вот наоборот, с 2 на 1  - получаю исключение. Никто с подобным не сталкивался?
Изначально сервер был 2,1,1. только что стянул 2,1,2 - не помогло...Вызов ХП осуществляется с помощью FIBQuery.ExecuteProcedure("NAME", [param, param...])


 
Виталий Панасенко   (2009-04-17 16:56) [1]

не дописал полный текст сообщения об ошибке:
The cursor identified in the update or delete statement is not positioned on a row. At procedure "DOC_UPD" line: 15. col: 3


 
turbouser ©   (2009-04-17 17:28) [2]


> Виталий Панасенко   (17.04.09 16:56) [1]

Триггеров нет?
Перекомпилировать процедуру - не помогает?


 
Виталий Панасенко(дом)   (2009-04-17 17:42) [3]

триггеры есть.. перекомпиляция - не помогает... я уже грешным делом поменял порядок следования параметров, думал, как с джоинами поможет.. не помогло.. триггеры: получить ИД и если PERIOD_BEG<>PERIOD_END, то "наплодить" на каждый месяц отдельную запись(чтобы можно было заказ в любом месте периода освободить, так сказать)


 
turbouser ©   (2009-04-17 17:47) [4]


> Виталий Панасенко(дом)   (17.04.09 17:42) [3]

А если сделать
if exists(select * from doc where id = :id) then
begin
 update doc
...
end


 
Виталий Панасенко(дом)   (2009-04-17 17:54) [5]

сейчас попробую.. но весь прикол: сменить DOC_STATUS с 1 на 2 - без проблем, наоборот - указанный эксцепшн.. код отрабатывает один и тот же.. даже "прошил" 2 (может, думал, вычислил неправильно) в параметры  -эксцепшн


 
Виталий Панасенко(дом)   (2009-04-17 18:02) [6]

не помогло....теперь строка 13, колонка 47 в процедуре

CREATE PROCEDURE DOC_UPD (
   id bigint,
   num_id varchar(10),
   summa numeric(15,2),
   doc_status smallint,
   period_beg varchar(6),
   period_end varchar(6),
   opis_id bigint,
   client_id bigint,
   sujet varchar(50))
as
begin
if (exists(select * from doc where id = :id)) then
 update doc
 set num_id = :num_id,
     summa = :summa,
     period_beg = :period_beg,
     period_end = :period_end,
     doc_status = :doc_status,
     --srok_date = :srok_date,
     opis_id = :opis_id,
     client_id = :client_id,
     --doc_date = :doc_date,
     sujet = :sujet
 where (id = :id);
end


 
Виталий Панасенко(дом)   (2009-04-17 18:03) [7]

это где-то в районе then


 
Виталий Панасенко(дом)   (2009-04-17 18:16) [8]

наврал на счет триггеров.. вот на этом спотыкается.. отключаю, все нормально, включаю - эксцепшн


CREATE OR ALTER TRIGGER DOC_BI0 FOR DOC
ACTIVE BEFORE INSERT OR UPDATE POSITION 0
as
declare variable id bigint;
declare variable client_shortname varchar(50);
declare variable mb smallint;
BEGIN
 /*&#207;&#240;&#238;&#226;&#229;&#240;&#234;&#224; &#237;&#224; &#241;&#243;&#249;&#229;&#241;&#242;&#226;&#238;&#226;&#224;&#237;&#232;&#229; &#228;&#240;&#243;&#227;&#238;&#227;&#238; &#231;&#224;&#234;&#224;&#231;&#224;,&#234;&#238;&#242;&#238;&#240;&#251;&#233; &#239;&#229;&#240;&#229;&#241;&#229;&#234;&#224;&#229;&#242;&#241;&#255; &#241; &#237;&#224;&#248;&#232;&#236;*/
 if (updating) then
 IF (EXISTS (SELECT * FROM doc
             WHERE num_id=NEW.num_id AND id<>NEW.id and DOC_STATUS=1
             AND ((period_beg <= NEW.period_end)AND
             (period_end >= NEW.period_beg)) )) THEN
  BEGIN
    FOR
     SELECT MAX(id) FROM doc
     WHERE num_id=NEW.num_id AND id<>NEW.id
             AND ((period_beg <= NEW.period_end)AND
             (period_end >= NEW.period_beg))
      INTO :id
      DO
       BEGIN
        SELECT c.client_shortname FROM doc d
        JOIN clients c ON (c.client_id=d.client_id)
        WHERE d.id=:id
        INTO :client_shortname;
       END
     --&#194;&#251;&#231;&#251;&#226;&#224;&#229;&#236; &#232;&#241;&#234;&#235;&#254;&#247;&#229;&#237;&#232;&#229;
     EXCEPTION period_exception "&#197;&#241;&#242;&#252; &#228;&#240;&#243;&#227;&#238;&#233; &#231;&#224;&#234;&#224;&#231; &#241; &#242;&#224;&#234;&#232;&#236; &#239;&#229;&#240;&#232;&#238;&#228;&#238;&#236;: &#185;"||CAST(:id AS VARCHAR(18))||", &#234;&#235;&#232;&#229;&#237;&#242;: "||:client_shortname;
  END
 --&#194;&#241;&#242;&#224;&#226;&#234;&#224;
 if (inserting) then
 IF (EXISTS (SELECT * FROM doc
             WHERE num_id=NEW.num_id and DOC_STATUS=1
             AND ((period_beg <= NEW.period_end)AND
             (period_end >= NEW.period_beg)) )) THEN
  BEGIN
    FOR
     SELECT MAX(id) FROM doc
     WHERE num_id=NEW.num_id
             AND ((period_beg <= NEW.period_end)AND
             (period_end >= NEW.period_beg))
     INTO :id
      DO
       BEGIN
        SELECT c.client_shortname FROM doc d
        JOIN clients c ON (c.client_id=d.client_id)
        WHERE d.id=:id
        INTO :client_shortname;
       END
     --&#194;&#251;&#231;&#251;&#226;&#224;&#229;&#236; &#232;&#241;&#234;&#235;&#254;&#247;&#229;&#237;&#232;&#229;
     EXCEPTION period_exception "&#197;&#241;&#242;&#252; &#228;&#240;&#243;&#227;&#238;&#233; &#231;&#224;&#234;&#224;&#231; &#241; &#242;&#224;&#234;&#232;&#236; &#239;&#229;&#240;&#232;&#238;&#228;&#238;&#236;: &#185;"||CAST(:id AS VARCHAR(18))||", &#234;&#235;&#232;&#229;&#237;&#242;: "||:client_shortname;
  END
 /*&#207;&#238;&#228;&#241;&#247;&#229;&#242; &#247;&#232;&#241;&#235;&#224; &#236;&#229;&#241;&#255;&#246;&#229; &#226; &#239;&#229;&#240;&#232;&#238;&#228;&#229;*/
 EXECUTE PROCEDURE sp_monthsbetween(NEW.period_beg, NEW.period_end) RETURNING_VALUES :MB;
 NEW.monthsbetween = :MB;
 /*&#211;&#228;&#224;&#235;&#232;&#242;&#252; &#226;&#241;&#229; &#208;&#197;&#199;&#197;&#208;&#194;&#219; &#228;&#235;&#255; &#228;&#224;&#237;&#237;&#238;&#233; &#239;&#235;&#238;&#241;&#234;&#238;&#241;&#242;&#232;, &#229;&#241;&#235;&#232; &#232;&#245; &#239;&#229;&#240;&#232;&#238;&#228; &#239;&#229;&#240;&#229;&#241;&#229;&#234;&#224;&#229;&#242;&#241;&#255; &#241; &#237;&#224;&#248;&#232;&#236;*/
 if (new.doc_status=1) then
 delete from doc
 where num_id=NEW.NUM_ID and doc_status=2 and ((period_beg <= NEW.period_end)AND
             (period_end >= NEW.period_beg));
END


 
Виталий Панасенко(дом)   (2009-04-17 18:17) [9]

видимо, здесь
if (new.doc_status=1) then
delete from doc
where num_id=NEW.NUM_ID and doc_status=2 and ((period_beg <= NEW.period_end)AND
            (period_end >= NEW.period_beg));


 
Виталий Панасенко(дом)   (2009-04-17 18:19) [10]

да, именно там.. коментирую кусок, работает.. спасибо за подсказку


 
Виталий Панасенко(дом)   (2009-04-17 18:23) [11]

все, спасибо.. решилось, как НЕ говорил Холмс, "элементарно"...:-)

if (inserting) then
if (new.doc_status=1) then
delete from doc
where num_id=NEW.NUM_ID and doc_status=2 and ((period_beg <= NEW.period_end)AND
           (period_end >= NEW.period_beg));

можно ветку закрывать



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.084 c
2-1268949255
allrussia
2010-03-19 00:54
2010.08.27
Технология работы процедуры


15-1264023028
Юрий
2010-01-21 00:30
2010.08.27
С днем рождения ! 21 января 2010 четверг


2-1271760916
Irisss
2010-04-20 14:55
2010.08.27
Панель иконок


15-1271414136
ocean
2010-04-16 14:35
2010.08.27
Блокировать сайты в ISA


2-1267297747
Первокурсница
2010-02-27 22:09
2010.08.27
Две задачи для первого курса,Delphi





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский