powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / when sqlcode ... do Не желает компилить ХП
23 сообщений из 23, страница 1 из 1
when sqlcode ... do Не желает компилить ХП
    #32651058
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IB7.1
Требуется из даты вычесть/добавить определённое количество лет, месяцев, дней.
Сваял процедуру. Всё 'Ок'. Отрабатывает на ура как в (+) так и в (—).
Но напоролся на '29-feb-2004' минус три года.
'29-feb-2001' не существует. Следует грамотно обработать ситуёвину.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
...
RETURNS (
    OUT_DATE DATE)
AS
declare variable y0 smallint;
declare variable m0 smallint;
declare variable d0 smallint;
...
 /* было так */ 
out_date = :y0 || '-' || :m0 || '-' || :d0;

 /* пытаюсь ловить ошибку */ 
out_date = :y0 || '-' || :m0 || '-' || :d0;
when sqlcode - 413  do begin  /* conversion error from string (при появлении '29-feb-2001')*/ 
 d0 = :d0 -  1 ;
 out_date = :y0 || '-' || :m0 || '-' || :d0;
end
out_date = :out_date + :d;  /*Ругается на эту строку*/ 
 /*При компиляции получаю*/ 
Invalid token.
Dynamic SQL Error.
SQL error code = - 104 .
Token unknown - line  35 , char  2 .
out_date.
 /*Ругается на всё, что после when ... do begin ... end вообще на любую, даже suspend;*/ 

 /* Если делать так, то нормально и компилится и работает*/ 
  out_date = :y0 || '-' || :m0 || '-' || :d0;
  out_date = :out_date + :d;  /*Дублирую здесь на случай корректной работы */ 
  when sqlcode - 413  do begin  /* conversion error from string (при появлении '29-feb-2001')*/ 
   d0 = :d0 -  1 ;
   out_date = :y0 || '-' || :m0 || '-' || :d0;
   out_date = :out_date + :d;  /*И здесь на случай ошибки */ 
  end
  /*Конец процедуры */ 
Why??? Чего не так? В других процедурах, например, when sqlcode -811 do ...;
и далее куча кода и всё работает.
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651088
Фотография Dnico
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А зачем перед переменными двоеточие стоят. Они вообщето в данном случае не нужны.


Best regards,
Dnico.
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651097
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IBExpert c двоеточием рисует переменные другим цветом, меня это вполне устраивает. Но суть не в этом.
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651101
olol
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У тебя что крыша поехала ?

Ты ее в ХП обрабатывай... там ты и сделаешь с ней все что хош...

Если дата в виде чисел и ОЧЕНЬ хочется без ХП... могу дать процедурку расчета (проверено, работает) и без перехватов ошибок.
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651110
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ololУ тебя что крыша поехала ?

Ты ее в ХП обрабатывай... там ты и сделаешь с ней все что хош...

Если дата в виде чисел и ОЧЕНЬ хочется без ХП...Хочешь чтобы я что-нибудь ответил?
Я вообще-то вменяемый.
По твоему я её где обрабатываю?
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651197
olol
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe...По твоему я её где обрабатываю?

Sorry... Я имел в виду внешнюю UDF...

У меня для одной проги на IB6 дата в виде одного числа INTEGER использовалась, и вычислял я начало месяца, конец и прочее без UDF...

Для твоего случая можно сделать так:

EXECUTE PROCEDURE peEncodeDate (Y INTEGER, M INTEGER, D INTEGER)
RETURNING_VALUES :L,:n;
EXECUTE PROCEDURE peIncMonth (n INTEGER, k INTEGER)
RETURNING_VALUES :L,:n;

Должно работать и на IB и на Oracle... проблемы будут только с датой до рождества Христова... минус я в peDiv2i не учел...



CREATE PROCEDURE peDiv2i (n1 INTEGER, n2 INTEGER)
RETURNS (i INTEGER, n INTEGER)
AS DECLARE VARIABLE f DOUBLE PRECISION;
BEGIN
IF (n1 IS NULL) THEN n1 = 0;
f = n1; f = f / n2; i = 0.5;
IF (i = 0) THEN
IF (f < 0) THEN f = f - 1; ELSE f = f + 1;
ELSE IF (f < 0) THEN f = f - 0.5; ELSE f = f + 0.5;
i = f; IF (i < 0) THEN i = i + 1; ELSE i = i - 1;
n = n1 - i * n2;
END
[quot]

[quot]
CREATE PROCEDURE peEncodeYear (Y INTEGER)
RETURNS (L INTEGER, n INTEGER)
AS DECLARE VARIABLE i INTEGER;
BEGIN
EXECUTE PROCEDURE peDiv2i (:Y, 1000) RETURNING_VALUES :i,:Y;
n = 365241 * i; L = 1;
IF (Y >= 100) THEN BEGIN
EXECUTE PROCEDURE peDiv2i (:Y, 100) RETURNING_VALUES :i,:Y;
n = n + 36524 * i + 1; L = 0; END
IF (Y >= 4) THEN BEGIN
EXECUTE PROCEDURE peDiv2i (:Y, 4) RETURNING_VALUES :i,:Y;
n = n + 1461 * i; IF (L = 0) THEN n = n - 1; L = 1; END
IF (Y > 0) THEN BEGIN
n = n + 365 * Y + L; L = 0; END
END



CREATE PROCEDURE peEncodeMonth (Y INTEGER, M INTEGER)
RETURNS (L INTEGER, n INTEGER)
AS BEGIN
EXECUTE PROCEDURE peEncodeYear (:Y) RETURNING_VALUES :L,:n;
IF (M > 1)
THEN BEGIN n = n + 31;
IF (M > 2)
THEN BEGIN n = n + 28 + L;
IF (M > 3)
THEN BEGIN n = n + 31;
IF (M > 4)
THEN BEGIN n = n + 30;
IF (M > 5)
THEN BEGIN n = n + 31;
IF (M > 6)
THEN BEGIN n = n + 30;
IF (M > 7)
THEN BEGIN n = n + 31;
IF (M > 8)
THEN BEGIN n = n + 31;
IF (M > 9)
THEN BEGIN n = n + 30;
IF (M > 10)
THEN BEGIN n = n + 31;
IF (M > 11)
THEN n = n + 30;
END END END END END END END END END END
END



CREATE PROCEDURE peEncodeDate (Y INTEGER, M INTEGER, D INTEGER)
RETURNS (L INTEGER, n INTEGER)
AS BEGIN
EXECUTE PROCEDURE peEncodeMonth (:Y,:M) RETURNING_VALUES :L,:n;
n = n + D - 1;
END



CREATE PROCEDURE peDecodeYear (i INTEGER)
RETURNS (L INTEGER, Y INTEGER, n INTEGER)
AS BEGIN
EXECUTE PROCEDURE peDiv2i (:i, 365241) RETURNING_VALUES :i,:n;
Y = 1000 * i; L = 1;
IF (n > 36524) THEN BEGIN n = n - 1;
EXECUTE PROCEDURE peDiv2i (:n, 36524) RETURNING_VALUES :i,:n;
Y = Y + 100 * i; L = 0; END
IF (n >= 1460 + L) THEN BEGIN IF (L = 0) THEN n = n + 1;
EXECUTE PROCEDURE peDiv2i (:n, 1461) RETURNING_VALUES :i,:n;
Y = Y + 4 * i; L = 1; END
IF (n >= 365 + L) THEN BEGIN n = n - L;
EXECUTE PROCEDURE peDiv2i (:n, 365) RETURNING_VALUES :i,:n;
Y = Y + i; L = 0; END
END



CREATE PROCEDURE peDecodeMonth (i INTEGER)
RETURNS (L INTEGER, Y INTEGER, M INTEGER, n INTEGER)
AS BEGIN
M = 1; EXECUTE PROCEDURE peDecodeYear (:i) RETURNING_VALUES :L,:Y,:n;
IF (n >= 31)
THEN BEGIN M = 2; n = n - 31;
IF (n >= 28 + L)
THEN BEGIN M = 3; n = n - 28 - L;
IF (n >= 31)
THEN BEGIN M = 4; n = n - 31;
IF (n >= 30)
THEN BEGIN M = 5; n = n - 30;
IF (n >= 31)
THEN BEGIN M = 6; n = n - 31;
IF (n >= 30)
THEN BEGIN M = 7; n = n - 30;
IF (n >= 31)
THEN BEGIN M = 8; n = n - 31;
IF (n >= 31)
THEN BEGIN M = 9; n = n - 31;
IF (n >= 30)
THEN BEGIN M = 10; n = n - 30;
IF (n >= 31)
THEN BEGIN M = 11; n = n - 31;
IF (n >= 30)
THEN BEGIN M = 12; n = n - 30;
END END END END END END END END END END END
END



CREATE PROCEDURE peDecodeDate (i INTEGER)
RETURNS (L INTEGER, Y INTEGER, M INTEGER, D INTEGER)
AS BEGIN
EXECUTE PROCEDURE peDecodeMonth (:i) RETURNING_VALUES :L,:Y,:M,:D; D = D + 1;
END



CREATE PROCEDURE peDaysInLMonth (L INTEGER, M INTEGER)
RETURNS (D INTEGER)
AS BEGIN
IF (M = 1) THEN D = 31;
ELSE IF (M = 2) THEN D = 28 + L;
ELSE IF (M = 3) THEN D = 31;
ELSE IF (M = 4) THEN D = 30;
ELSE IF (M = 5) THEN D = 31;
ELSE IF (M = 6) THEN D = 30;
ELSE IF (M = 7) THEN D = 31;
ELSE IF (M = 8) THEN D = 31;
ELSE IF (M = 9) THEN D = 30;
ELSE IF (M = 10) THEN D = 31;
ELSE IF (M = 11) THEN D = 30;
ELSE D = 31;
END



CREATE PROCEDURE peStartOfTheMonth (i INTEGER)
RETURNS (L INTEGER, n INTEGER)
AS DECLARE VARIABLE Y INTEGER;
DECLARE VARIABLE M INTEGER; DECLARE VARIABLE D INTEGER;
BEGIN
EXECUTE PROCEDURE peDecodeDate (:i) RETURNING_VALUES :L,:Y,:M,:D; D = 1;
EXECUTE PROCEDURE peEncodeDate(:Y,:M,:D) RETURNING_VALUES :L,:n;
END



CREATE PROCEDURE peEndOfTheMonth (i INTEGER)
RETURNS (L INTEGER, n INTEGER)
AS DECLARE VARIABLE Y INTEGER;
DECLARE VARIABLE M INTEGER; DECLARE VARIABLE D INTEGER;
BEGIN
EXECUTE PROCEDURE peDecodeDate (:i) RETURNING_VALUES :L,:Y,:M,:D;
EXECUTE PROCEDURE peDaysInLMonth (:L,:M) RETURNING_VALUES :D;
EXECUTE PROCEDURE peEncodeDate(:Y,:M,:D) RETURNING_VALUES :L,:n;
END



CREATE PROCEDURE peIncMonth (i INTEGER, k INTEGER)
RETURNS (L INTEGER, n INTEGER)
AS DECLARE VARIABLE Y INTEGER;
DECLARE VARIABLE M INTEGER; DECLARE VARIABLE D INTEGER;
BEGIN
EXECUTE PROCEDURE peDecodeDate (:i) RETURNING_VALUES :L,:Y,:M,:D;
M = M - 1 + k;
EXECUTE PROCEDURE peDiv2i (:M, 12) RETURNING_VALUES :n,:M;
M = M + 1; Y = Y + n;
EXECUTE PROCEDURE peEncodeYear (:Y) RETURNING_VALUES :L,:n;
EXECUTE PROCEDURE peDaysInLMonth (:L,:M) RETURNING_VALUES :n;
IF (D > n) THEN D = n;
EXECUTE PROCEDURE peEncodeDate(:Y,:M,:D) RETURNING_VALUES :L,:n;
END
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651223
Фотография AndriyKo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ololТы ее в ХП обрабатывай... там ты и сделаешь с ней все что хош...

Наверно, все таки UDF, а не ХП ? В таком случае присоединяюсь. Если все же нужно без UDF, тогда просьба Zmeishe выложить более подробный текст процедуры (с входными параметрами).
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651227
Фотография Dnico
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe А в FB 1.5 это все ужо есть ...
Можно взять UDF и попробовать подключить к IB 7.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
 --FBUDF_API ISC_TIMESTAMP* addDay(ISC_TIMESTAMP* v, int ndays) 
declare external function addDay
timestamp, int
returns timestamp
entry_point 'addDay' module_name 'fbudf';

 --FBUDF_API ISC_TIMESTAMP* addWeek(ISC_TIMESTAMP* v, int nweeks) 
declare external function addWeek
timestamp, int
returns timestamp
entry_point 'addWeek' module_name 'fbudf';

 --FBUDF_API ISC_TIMESTAMP* addMonth(ISC_TIMESTAMP* v, int nmonths) 
declare external function addMonth
timestamp, int
returns timestamp
entry_point 'addMonth' module_name 'fbudf';

 --FBUDF_API ISC_TIMESTAMP* addYear(ISC_TIMESTAMP* v, int nyears) 
declare external function addYear
timestamp, int
returns timestamp
entry_point 'addYear' module_name 'fbudf';

 --FBUDF_API ISC_TIMESTAMP* addMilliSecond(ISC_TIMESTAMP* v, int nseconds) 
declare external function addMilliSecond
timestamp, int
returns timestamp
entry_point 'addMilliSecond' module_name 'fbudf';

 --FBUDF_API ISC_TIMESTAMP* addSecond(ISC_TIMESTAMP* v, int nseconds) 
declare external function addSecond
timestamp, int
returns timestamp
entry_point 'addSecond' module_name 'fbudf';

 --FBUDF_API ISC_TIMESTAMP* addMinute(ISC_TIMESTAMP* v, int nminutes) 
declare external function addMinute
timestamp, int
returns timestamp
entry_point 'addMinute' module_name 'fbudf';

 --FBUDF_API ISC_TIMESTAMP* addHour(ISC_TIMESTAMP* v, int nhours) 
declare external function addHour
timestamp, int
returns timestamp
entry_point 'addHour' module_name 'fbudf';

Best regards,
Dnico.
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651241
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>> olol
Спасибо за набор процедур, но у меня всё в `одном флаконе` 35 строчек от первого до последнего символа (от create procedure до end).

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
CREATE PROCEDURE SSP$DATE_INC(
    ADATE DATE,
    Y SMALLINT,
    M SMALLINT,
    D SMALLINT)
RETURNS (
    OUT_DATE DATE)
AS
declare variable y0 smallint;
declare variable m0 smallint;
declare variable d0 smallint;
declare variable month_inc smallint;
begin
  y0 = extract(year from :adate) + :y;
  m0 = extract(month from :adate);
  if(:m >  0 ) then month_inc =  1 ;
  else month_inc = - 1 ;

  while(:m <>  0 ) do begin
   m0 = :m0 + :month_inc;
    if(:m0 =  13 ) then begin m0 =  1 ; y0 = :y0 +  1 ; end
    else if(:m0 =  0 ) then begin m0 =  12 ; y0 = :y0 -  1 ; end
   m = :m - :month_inc;
  end
  d0 = extract(day from :adate);

  out_date = :y0 || '-' || :m0 || '-' || :d0;
  out_date = :out_date + :d;
   /* conversion error from string */ 
  when sqlcode - 413  do begin
   d0 = :d0 -  1 ;
   out_date = cast((:y0 || '-' || :m0 || '-' || :d0) as date);
   out_date = :out_date + :d;
  end
end

Всё работает, проблему обошёл. Но ответ на вопрос так и не получил. Если кто-то не уловил суть вопроса, формулирую иначе.

Почему компилятор конкретно в этой процедуре не допускает никаких операторов после
Код: plaintext
1.
2.
3.
4.
  when sqlcode - 413  do begin
   d0 = :d0 -  1 ;
   out_date = cast((:y0 || '-' || :m0 || '-' || :d0) as date);
   out_date = :out_date + :d;
  end
???
В других-то процедурах допускает!
Чем эта процедура заколдована???
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651260
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вызываю её
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
  
   /*Три года вниз*/ 
  execute procedure ssp$date_inc(new.adate, - 3 ,  0 ,  0 )
  returning_values :tmp_date;

   /*28 месяцев вверх */ 
  execute procedure ssp$date_inc(new.adate,  0 ,  28 ,  0 )
  returning_values :tmp_date;

   /*315 дней вверх */ 
  execute procedure ssp$date_inc(new.adate,  0 ,  0 ,  315 )
  returning_values :tmp_date;

   /*28 месяцев вверх и 315 дней вниз */ 
  execute procedure ssp$date_inc(new.adate,  0 ,  28 , - 315 )
  returning_values :tmp_date;

Но вопрос в другом.
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651316
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
...
 /* было так */ 
out_date = :y0 || '-' || :m0 || '-' || :d0;

 /* пытаюсь ловить ошибку */ 
out_date = :y0 || '-' || :m0 || '-' || :d0;
when sqlcode - 413  do begin  /* conversion error from string (при появлении '29-feb-2001')*/ 
 d0 = :d0 -  1 ;
 out_date = :y0 || '-' || :m0 || '-' || :d0;
end
out_date = :out_date + :d;  /*Ругается на эту строку*/ 

end относится к первому begin , а не к when
Сделай так

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
 /* пытаюсь ловить ошибку */ 
  begin
    out_date = :y0 || '-' || :m0 || '-' || :d0;
  when sqlcode - 413  do begin  /* conversion error from string (при появлении '29-feb-2001')*/ 
     d0 = :d0 -  1 ;
     out_date = :y0 || '-' || :m0 || '-' || :d0;
  end

  out_date = :out_date + :d;  /*Ругается на эту строку*/ 
end

Т.е. добавь begin перед действием, ошибку которого ты обрабатываешь (по аналогии с try )
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651320
Фотография AndriyKo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, вспомнил. Такая же ситуация была и у меня до тех пор, пока не засунул блок "When do begin end" в конец цикла. Чей это глюк (мой, IBE, FB), не знаю, проверять влом было. Но ты говоришь, что в других процедурах у тебя подобная ситуация проходит ? А примерчик можно отлицезреть ?
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651346
Фотография AndriyKo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
To HVLAD:

Не, речь идет о том, почему не компилится конструкция типа

CREATE PROCEDURE SSP$DATE_INC RETURNS (OUT_DATE DATE)
AS
begin
out_date = 0;
when sqlcode -413 do out_date = 0;
suspend;
end
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651356
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>> примерчик можно отлицезреть ?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
вот до сих  51  строка алгоритма
 52  if((:st_value is null) or (:en_value is null)) then
 53  begin  /*
54            Тут типа комментарий 
55         */ 
 56   if((:en_value is null) and (:st_value is not null)) then en_value = :st_value;
 57   else if(:en_value is null) then en_value =  0 ;
 58       select o.en_counter_value_doc
 59         from tb_oplata o
 60       where (o.face_account = :face_account)
 61          and (o.pay_month = :last_pay_month)
 62          and (o.payment_type = :payment_type)
 63          into :st_value;
 64         /* Multiple rows in singletion select */ 
 65        when sqlcode - 811  do st_value =  0 ;
 66  end
и от  67  до  267  строки (до конца процедуры)
Разница только в том, что этот when закрыт if then begin end`ом. Других объяснений не вижу.
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651359
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Смотрите внимательно синтаксис.
Допустимая конструкция блока есть begin...[when...]end , поэтому блоки типа begin ... when ... end ... end синтаксически не корректны
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651368
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndriyKoTo HVLAD:

Не, речь идет о том, почему не компилится конструкция типа

CREATE PROCEDURE SSP$DATE_INC RETURNS (OUT_DATE DATE)
AS
begin
out_date = 0;
when sqlcode -413 do out_date = 0; ( * )
suspend;
end

Вот после (*) должен быть или when или end
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651403
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну в общем вместо
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
  
  d0 = extract(day from :adate);
  out_date = :y0 || '-' || :m0 || '-' || :d0;
  out_date = :out_date + :d;
   /* conversion error from string */ 
  when sqlcode - 413  do begin
   d0 = :d0 -  1 ;
   out_date = :y0 || '-' || :m0 || '-' || :d0;
   out_date = :out_date + :d;
  end
Написал так (Втиснул ни к чему не обязывающий if) заработало
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
  if(:d0 <>  0 ) then begin
  out_date = :y0 || '-' || :m0 || '-' || :d0;
   /* conversion error from string */ 
  when sqlcode - 413  do begin
   d0 = :d0 -  1 ;
   out_date = :y0 || '-' || :m0 || '-' || :d0;
  end
  end
   out_date = :out_date + :d;
   suspend;

hvlad дело подсказал.
Но в моих help`ах синтаксис такой:
WHEN {<error> [, <error> …] | ANY}
DO <compound_statement>

Про внешний, по отношению к when, begin end - впервый раз столкнулся.
Спасибо.
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651426
olol
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не хочу быть занудой... а 31 марта 2001г - 1 месяц она тоже делает ?
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651434
olol
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автор

Не поленился проверить... говорит:

Conversion error from string "2001-2-30"
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651452
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZmeisheНу в общем вместо
...
Написал так (Втиснул ни к чему не обязывающий if) заработало

А зачем if ? Чтобы написать begin ? ;)))
Попробуй без него

ZmeisheНо в моих help`ах синтаксис такой:
WHEN {<error> [, <error> …] | ANY}
DO <compound_statement>

when - это часть блока, рассматривая его отдельно от блока, ты и получил свою ошибку.
Может быть в доке это чётко не написано (лень сейчас искать ;)
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32651975
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ololНе хочу быть занудой... а 31 марта 2001г - 1 месяц она тоже делает ?
...
Conversion error from string "2001-2-30"

hvladА зачем if ? Чтобы написать begin ? ;)))
Попробуй без него
Теперь разобравшись с begin when sqlcode do begin ... end end (Даже без if`a), я немного доработал так:
Код: plaintext
1.
2.
3.
4.
5.
6.
  while(:out_date is null) do begin
  out_date = :y0 || '-' || :m0 || '-' || :d0;
   /* conversion error from string */ 
  when sqlcode - 413  do d0 = :d0 -  1 ;
  end
   out_date = :out_date + :d;
   suspend;

И полный текст процедуры такой:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
CREATE PROCEDURE SSP$DATE_INC(
    ADATE DATE,
    Y SMALLINT,
    M SMALLINT,
    D SMALLINT)
RETURNS (
    OUT_DATE DATE)
AS
declare variable y0 smallint;
declare variable m0 smallint;
declare variable d0 smallint;
declare variable month_inc smallint;
begin
  y0 = extract(year from :adate) + :y;
  m0 = extract(month from :adate);
  if(:m >  0 ) then month_inc =  1 ;
  else month_inc = - 1 ;

  while(:m <>  0 ) do begin
   m0 = :m0 + :month_inc;
    if(:m0 =  13 ) then begin m0 =  1 ; y0 = :y0 +  1 ; end
    else if(:m0 =  0 ) then begin m0 =  12 ; y0 = :y0 -  1 ; end
   m = :m - :month_inc;
  end
  d0 = extract(day from :adate);

  while(:out_date is null) do begin
  out_date = :y0 || '-' || :m0 || '-' || :d0;
   /* conversion error from string */ 
  when sqlcode - 413  do d0 = :d0 -  1 ;
  end
   out_date = :out_date + :d;
   suspend;
end
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32652024
olol
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автор

suspend; - специально поставил, чтобы делать select или как ?

Выдает:

Unknown error
Statement: select * from SSP$DATE_INC ('31.03.01', 0,-1,0)

Зато потом все таки выводит 28.02.2001

Если не секрет - то почему не юсаеш UDF ?

/*28 месяцев вверх и 315 дней вниз */
Ума не приложу - где это может пригодиться одновременное "+" и "-"

Лично мне не подуше обработка с перехватом ошибок когда можно обойтись и без них (хотя так конечно намного проще)
...
Рейтинг: 0 / 0
when sqlcode ... do Не желает компилить ХП
    #32652058
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>> Unknown error
>> Statement: select * from SSP$DATE_INC ('31.03.01', 0,-1,0)
У меня не выдаёт никаких ошибок. Ни при execute procedure ни при select * from. Проверь у себя какие-нибудь настройки системы.
>> Если не секрет - то почему не юсаеш UDF ?
UDF юзаю, когда нет возможностей SQL или на SQL алгоритм будет слишком громоздким.

>>/*28 месяцев вверх и 315 дней вниз */
>>Ума не приложу - где это может пригодиться одновременное "+" и "-"
Я тоже не знаю где это сгодится, но сначала заказчик сформулировал требования к БД такими, что была необходимость расчитывать только целые месяцы. Я их кодировал первым числом месяца '01.01.2003', '01.02.2003' и т.д.
И процедуру разработал под +/- месяцев. Потом заказчик захотел учитывать срок исковой давности 3 года. Пришлось доработать +/- годы. Теперь заказчику пришёл основательный аппетит... Да пошёл ты, сказал я, и доработал +/- всё, что хочешь, чтобы больше не возвращаться к этой ХП.
Всего 35 строчек кода — нате ешьте.
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / when sqlcode ... do Не желает компилить ХП
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]