Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.08.27;
Скачать: CL | DM;

Вниз

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

 
Виталий Панасенко   (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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.151 c
2-1269849342
senatormisha
2010-03-29 11:55
2010.08.27
Перезапуск формы


2-1266751523
Fr
2010-02-21 14:25
2010.08.27
TRichEdit, вставка текста


15-1264341586
Kolan
2010-01-24 16:59
2010.08.27
Исходники DMClient а доступны для всех желающих


2-1269966073
Dr. Genius
2010-03-30 20:21
2010.08.27
Формат даты вида "30 марта 2010 года"


10-1166276143
samael6
2006-12-16 16:35
2010.08.27
Плагины к Internet Explorer