Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / when sqlcode ... do Не желает компилить ХП / 23 сообщений из 23, страница 1 из 1
16.08.2004, 14:53:26
    #32651058
Zmeishe
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
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
16.08.2004, 15:04:22
    #32651088
Dnico
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
А зачем перед переменными двоеточие стоят. Они вообщето в данном случае не нужны.


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

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

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

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

Если дата в виде чисел и ОЧЕНЬ хочется без ХП...Хочешь чтобы я что-нибудь ответил?
Я вообще-то вменяемый.
По твоему я её где обрабатываю?
...
Рейтинг: 0 / 0
16.08.2004, 15:48:13
    #32651197
olol
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
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
16.08.2004, 15:55:05
    #32651223
AndriyKo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
ololТы ее в ХП обрабатывай... там ты и сделаешь с ней все что хош...

Наверно, все таки UDF, а не ХП ? В таком случае присоединяюсь. Если все же нужно без UDF, тогда просьба Zmeishe выложить более подробный текст процедуры (с входными параметрами).
...
Рейтинг: 0 / 0
16.08.2004, 15:55:50
    #32651227
Dnico
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
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
16.08.2004, 15:58:57
    #32651241
Zmeishe
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
>> 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
16.08.2004, 16:05:05
    #32651260
Zmeishe
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
вызываю её
Код: 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
16.08.2004, 16:22:29
    #32651316
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
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
16.08.2004, 16:22:54
    #32651320
AndriyKo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
Да, вспомнил. Такая же ситуация была и у меня до тех пор, пока не засунул блок "When do begin end" в конец цикла. Чей это глюк (мой, IBE, FB), не знаю, проверять влом было. Но ты говоришь, что в других процедурах у тебя подобная ситуация проходит ? А примерчик можно отлицезреть ?
...
Рейтинг: 0 / 0
16.08.2004, 16:30:00
    #32651346
AndriyKo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
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
16.08.2004, 16:32:22
    #32651356
Zmeishe
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
>> примерчик можно отлицезреть ?
Код: 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
16.08.2004, 16:33:51
    #32651359
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
Смотрите внимательно синтаксис.
Допустимая конструкция блока есть begin...[when...]end , поэтому блоки типа begin ... when ... end ... end синтаксически не корректны
...
Рейтинг: 0 / 0
16.08.2004, 16:36:40
    #32651368
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
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
16.08.2004, 16:47:37
    #32651403
Zmeishe
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
Ну в общем вместо
Код: 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
16.08.2004, 16:52:04
    #32651426
olol
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
Не хочу быть занудой... а 31 марта 2001г - 1 месяц она тоже делает ?
...
Рейтинг: 0 / 0
16.08.2004, 16:55:57
    #32651434
olol
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
автор

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

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

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

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

when - это часть блока, рассматривая его отдельно от блока, ты и получил свою ошибку.
Может быть в доке это чётко не написано (лень сейчас искать ;)
...
Рейтинг: 0 / 0
17.08.2004, 07:59:55
    #32651975
Zmeishe
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
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
17.08.2004, 09:04:13
    #32652024
olol
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
автор

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

Выдает:

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

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

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

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

Лично мне не подуше обработка с перехватом ошибок когда можно обойтись и без них (хотя так конечно намного проще)
...
Рейтинг: 0 / 0
17.08.2004, 09:22:05
    #32652058
Zmeishe
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
when sqlcode ... do Не желает компилить ХП
>> 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
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / when sqlcode ... do Не желает компилить ХП / 23 сообщений из 23, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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