Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Нужна помощь начинающему / 17 сообщений из 17, страница 1 из 1
01.12.2015, 11:27
    #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
01.12.2015, 11:28
    #39117116
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь начинающему
Hello, Edward K!
You wrote on 1 декабря 2015 г. 11:28:55:

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

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



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

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

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

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

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

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



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

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



так тоже не есть гуд, остануться болтаться свободные номера в середине таблицы, так как лицевой назначался не автоматом к как то от балды - банк назначал раньше
...
Рейтинг: 0 / 0
01.12.2015, 12:31
    #39117222
Edward_K
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь начинающему
Симонов Денис, щас юзер сам присваивает лицевые - вот и надо выцеплять свободные
...
Рейтинг: 0 / 0
01.12.2015, 12:50
    #39117247
DBConstructor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь начинающему
Edward_Kно прога матюкаеться что не текстовое поле написано было еще лет 15 назад все....
Похоже, это очередной случай с решением через updatable view.
...
Рейтинг: 0 / 0
01.12.2015, 12:55
    #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
01.12.2015, 14:41
    #39117378
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужна помощь начинающему
Edward_Kостануться болтаться свободные номера в середине таблицы
И чо?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Нужна помощь начинающему / 17 сообщений из 17, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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