powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Почему зацикливает процедуру?
11 сообщений из 11, страница 1 из 1
Почему зацикливает процедуру?
    #38902575
crazypiggy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день. Создал процедуру
Код: sql
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.
47.
48.
49.
50.
procedure CALC_SUMM_ON_VOLUME (
    LIC_SCH type of LIC_SCH_DOMAIN,
    SPR_SUB_USLUGI_ID integer,
    START_DATE timestamp,
    STOP_DATE timestamp)
returns (
    VOLUME numeric(15,5),
    TARIF numeric(15,5),
    PROCENT numeric(15,5),
    BEGIN_DATE timestamp,
    END_DATE timestamp)
as
declare variable EXVOL integer;
declare variable VOL numeric(18,5);
declare variable TS1 timestamp;
declare variable TS2 timestamp;
declare DATAPOKAZ cursor for (
    select DPS.VOLUME, DPS.PRED_DATE, DPS.DATA
    from DATA_POKAZ_SCH DPS
    where (DPS.LIC_SCH = :LIC_SCH) and
          (DPS.SPR_SUB_USLUGI_ID = :SPR_SUB_USLUGI_ID) and
          (DPS.DATA >= :START_DATE) and
          (DPS.DATA <= :STOP_DATE));
begin
  /* Procedure Text */
  ExVol=0;
  open datapokaz;
  while (1=1) do
  begin
        tarif=0;
        fetch datapokaz into :vol, :ts1, :ts2;
        if (:vol is null) then vol=0;
        if (:ts1 is null) then ts1=:start_date;
        if (:ts2 is null) then ts2=:stop_date;
             for select tarif, procent, begin_date, end_date from calc_summ_on_sub_uslugi (:lic_sch,:spr_sub_uslugi_id,:ts1,:ts2)
             into :tarif, :procent, :begin_date, :end_date
              do begin
                  if ((cast(:ts2 as date)-cast(:ts1 as date))>0) then
                  volume=:vol*(cast(:end_date as date) - cast(:begin_date as  date)+1)/(cast(:ts2 as date) - cast(:ts1 as date)+1);
                  else
                  volume=:vol;
                  if (:tarif is null) then tarif=0;
                  if (:procent is null) then procent=0;
                  exvol=1;
                  suspend;
                  end
       if  ((row_count=0) or (:ts2<:start_date))   then leave;
  end
  close datapokaz;  
end


Её зацикливает, т.е. выдает одну и ту же строку результата множество раз. Хотя должна быть лишь одна строка. Проверяю в IBExpert в Debug procedure выдает правильно одну строку. Запускаю на выполнение опять куча строк с одним и тем же результатом.
Создал похожую процедуру
Код: sql
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.
47.
48.
procedure CALC_SUMM_ON_VOLUME (
    LIC_SCH type of LIC_SCH_DOMAIN,
    SPR_SUB_USLUGI_ID integer,
    START_DATE timestamp,
    STOP_DATE timestamp)
returns (
    VOLUME numeric(15,5),
    TARIF numeric(15,5),
    PROCENT numeric(15,5),
    BEGIN_DATE timestamp,
    END_DATE timestamp)
as
declare variable EXVOL integer;
declare variable VOL numeric(18,5);
declare variable TS1 timestamp;
declare variable TS2 timestamp;
begin
  /* Procedure Text */
  ExVol=0;

  for select dps.volume, dps.pred_date, dps.data from data_pokaz_sch dps where (dps.lic_sch=:lic_sch)
  and (dps.spr_sub_uslugi_id=:spr_sub_uslugi_id) and (dps.data>=:start_date) and (dps.data<=:stop_date)
  into :vol, :ts1, :ts2
  do begin
        tarif=0;
             for select tarif, procent, begin_date, end_date from calc_summ_on_sub_uslugi (:lic_sch,:spr_sub_uslugi_id,:ts1,:ts2)
             into :tarif, :procent, :begin_date, :end_date
              do begin
                  if ((cast(:ts2 as date)-cast(:ts1 as date))>0) then
                  volume=:vol*(cast(:end_date as date) - cast(:begin_date as  date)+1)/(cast(:ts2 as date) - cast(:ts1 as date)+1);
                  else
                  volume=:vol;
                  if (:tarif is null) then tarif=0;
                  if (:procent is null) then procent=0;
                  exvol=1;
                  suspend;
                 end 
     end
     if (:exvol=0) then
     for select tarif, procent, begin_date, end_date from calc_summ_on_sub_uslugi (:lic_sch,:spr_sub_uslugi_id,:stop_date,:stop_date)
             into :tarif, :procent, :begin_date, :end_date
             do begin
                  if (:tarif is null) then tarif=0;
                  if (:procent is null) then procent=0;
                  volume=0;
                  suspend;
                end
end


Все нормально, выдает правильно одну строку. Подскажите в чем ошибка?
...
Рейтинг: 0 / 0
Почему зацикливает процедуру?
    #38902612
Фотография descent52
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
while (1=1) do....
...
Рейтинг: 0 / 0
Почему зацикливает процедуру?
    #38902616
crazypiggy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
if ((row_count=0) or (:ts2<:start_date)) then leave;
Разве это не должно остановить цикл?
...
Рейтинг: 0 / 0
Почему зацикливает процедуру?
    #38902624
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
crazypiggy,

а разве row_count при фетче отрабатывает?
...
Рейтинг: 0 / 0
Почему зацикливает процедуру?
    #38902641
crazypiggy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот Пример
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
SET TERM !!;

CREATE OR ALTER PROCEDURE GET_RELATIONS_NAMES 
RETURNS(
  RNAME CHAR(31)
)AS
  DECLARE C CURSOR FOR (SELECT RDB$RELATION_NAME FROM RDB$RELATIONS);
BEGIN
  OPEN C;
  WHILE (1 = 1) DO
  BEGIN
    FETCH C INTO :RNAME;
    IF(ROW_COUNT = 0)THEN
      LEAVE;
    SUSPEND;
  END
  CLOSE C;
END!!

SET TERM ;!!
...
Рейтинг: 0 / 0
Почему зацикливает процедуру?
    #38902706
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
crazypiggy,

Подними проверку вверх, сразу после фетча
может и полегчает
...
Рейтинг: 0 / 0
Почему зацикливает процедуру?
    #38902713
crazypiggy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Полегчало :) Так срабатывает. А почему не работало до этого?
...
Рейтинг: 0 / 0
Почему зацикливает процедуру?
    #38902720
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
crazypiggy,

Второй SELECT.
...
Рейтинг: 0 / 0
Почему зацикливает процедуру?
    #38902735
crazypiggy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Понял. Спасибо
...
Рейтинг: 0 / 0
Почему зацикливает процедуру?
    #38902744
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
crazypiggyПолегчало :) Так срабатывает. А почему не работало до этого?

Вот здесь ROW_COUNT написано
" The ROW_COUNT context variable contains the number of rows affected by the most recent DML statement (INSERT, UPDATE, DELETE, SELECT or FETCH) in the current trigger, stored procedure or executable block. "
в вольном переводе ".....содержит количество строк, обработанных в последнем DML ...."

Но и даже если бы это было не так, то в логике
... читаем
... обрабатываем
... проверяем а прочитали-ли мы что то
как по мне явная ошибка ибо должно быть
... читаем
... проверяем а прочитали-ли мы что то
... обрабатываем


ps/ сообщение №1000 можно и сто грамм
...
Рейтинг: 0 / 0
Почему зацикливает процедуру?
    #38902870
crazypiggy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Оффтоп 1000 это уже литр
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Почему зацикливает процедуру?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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