powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Нужна помощь начинающему
17 сообщений из 17, страница 1 из 1
Нужна помощь начинающему
    #39117113
Edward_K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
имеются 2 таблицы person и person_arhiv в обоих есть поле лицевой счет lschet char(20) необходимо найти ближайший свободный номер лицевого счета которого нет ни в одной таблице
делал хранимую процедуру так - но слишком медленно обрабатывает

Код: 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.
begin
  for SELECT max(person.lschet) FROM person
  into :max_person
  do nothing=0;

  for SELECT max(person_arhiv.lschet) FROM person_arhiv
  into :max_arhiv
  do nothing=0;

  if (max_arhiv<=max_person) then
   max_person_id=max_person;
  else max_person_id=max_arhiv;

  i=1;
  while (i<=:max_person_id) do
   begin
    lschet1=-1;
    lschet2=-1;
    for select person.lschet
    from person
    where (person.lschet) = :i
    into :lschet1
    do nothing=0;
    if (lschet1=-1) then
     begin
      for select person_arhiv.lschet
      from person_arhiv
      where (person_arhiv.lschet) = :i
      into :lschet2
      do nothing=0;
     end
    if ((:lschet1 =-1)and(:lschet2=-1)) then
     begin
      lschet_new:=:i; 
      exit;
    end
    i=:i+1;
   end
end


Модератор: Пользуйтесь тегом SRC
...
Рейтинг: 0 / 0
Нужна помощь начинающему
    #39117116
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hello, Edward K!
You wrote on 1 декабря 2015 г. 11:28:55:

Edward K> необходимо найти ближайший свободный номер лицевого счета которого нет ни в одной таблице
нельзя найти то чего нет.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Нужна помощь начинающему
    #39117119
Edward_K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
так в цикле и гоняю проверку на наличие
...
Рейтинг: 0 / 0
Нужна помощь начинающему
    #39117124
Edward_K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
при 8000 записях в одной и 8000 в другой, неиндексированные чтения достигают 30 000 000 в каждой таблице
...
Рейтинг: 0 / 0
Нужна помощь начинающему
    #39117143
DBConstructor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Edward_K, представьте, что параллельно выполняющиеся транзакции из разных подключений (обычный multiuser) находят один и тот же свободный номер лицевого счета. Что произойдет?
Как вариант - хранить все номера лицевых счетов в мастер-таблице с пометкой ('B'/'F' - занят/свободен). Если в таблице нет лицевых счетов с меткой 'F', то номер определяется через обычный генератор.
...
Рейтинг: 0 / 0
Нужна помощь начинающему
    #39117144
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Edward_K,

"do nothing=0;" Это кто так тебя научил?
Пиши так:
Код: sql
1.
SELECT max(person.lschet) FROM person into :max_person;



Чтобы не было 30 млн. неиндексированных чтений, необходимо ... проиндексировать.

А по коду - это полный песец, не хватает только дополнительного использования временных таблиц и динамически собираемых текстов запросов.
...
Рейтинг: 0 / 0
Нужна помощь начинающему
    #39117150
Edward_K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
WildSery, прога старая поля текстовые с индексами вобще бред получаеться, firebird еще 1.5
...
Рейтинг: 0 / 0
Нужна помощь начинающему
    #39117154
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Edward_K,

процедуру выкинуть на хрен ибо бред.
...
Рейтинг: 0 / 0
Нужна помощь начинающему
    #39117156
Edward_K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
WildSery, без do nothing=0; хранимая процедура в IBExpert не компилиться
...
Рейтинг: 0 / 0
Нужна помощь начинающему
    #39117159
Edward_K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис, процедуру выкинуть не могу так как она вызываеться из основной программы(ни кто ее переписывать не будет) и выдает только одно значение lschet_new
...
Рейтинг: 0 / 0
Нужна помощь начинающему
    #39117177
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Edward_K,

в первую очередь я бы вырвал руки проектировщику сией БД который разделил архивные и рабочие персоны по разным таблицам.

ближайший обычно ищется как-то так

Код: sql
1.
2.
3.
select max(person.lschet)
from person
where person.lschet < max_person_id



без всяких циклов. Соответственно на lschet лучше иметь DESC индекс
...
Рейтинг: 0 / 0
Нужна помощь начинающему
    #39117205
Edward_K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис, ага, я бы вырвал тоже, менял lschet с чара на интеджер затем индексировал обработка сокращаеться с 2 минут до 2 милисекунд, но прога матюкаеться что не текстовое поле написано было еще лет 15 назад все....
...
Рейтинг: 0 / 0
Нужна помощь начинающему
    #39117214
Edward_K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис,

Код: plsql
1.
2.
3.
select max(person.lschet)
from person
where person.lschet < max_person_id



так тоже не есть гуд, остануться болтаться свободные номера в середине таблицы, так как лицевой назначался не автоматом к как то от балды - банк назначал раньше
...
Рейтинг: 0 / 0
Нужна помощь начинающему
    #39117222
Edward_K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис, щас юзер сам присваивает лицевые - вот и надо выцеплять свободные
...
Рейтинг: 0 / 0
Нужна помощь начинающему
    #39117247
DBConstructor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Edward_Kно прога матюкаеться что не текстовое поле написано было еще лет 15 назад все....
Похоже, это очередной случай с решением через updatable view.
...
Рейтинг: 0 / 0
Нужна помощь начинающему
    #39117257
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Edward_K,

после причёсывания должно быть что-то такое


Код: 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.
BEGIN
  SELECT MAX(PERSON.LSCHET)
  FROM PERSON
  INTO :MAX_PERSON;

  SELECT MAX(PERSON_ARHIV.LSCHET)
  FROM PERSON_ARHIV
  INTO :MAX_ARHIV;


  IF (MAX_ARHIV <= MAX_PERSON) THEN
    MAX_PERSON_ID = MAX_PERSON;
  ELSE
    MAX_PERSON_ID = MAX_ARHIV;

  I = 1;
  WHILE (I <= :MAX_PERSON_ID) DO
  BEGIN
    IF (NOT EXISTS(
          SELECT * FROM PERSON WHERE PERSON.LSCHET = CAST(:I AS CHAR(15))
          UNION ALL
          SELECT * FROM PERSON_ARHIV WHERE PERSON_ARHIV.LSCHET = CAST(:I AS CHAR(15))
        )) THEN
    BEGIN
      LSCHET_NEW := :I;
      EXIT;
    END
    I = :I + 1;
  END
END



вместо CAST(:I AS CHAR(15)) приведи к тому типу который у тебя задан для LSCHET может индекс начнёт подхватываться
...
Рейтинг: 0 / 0
Нужна помощь начинающему
    #39117378
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Edward_Kостануться болтаться свободные номера в середине таблицы
И чо?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Нужна помощь начинающему
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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