powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / процедура для удаления записей из 2 таблиц
25 сообщений из 29, страница 1 из 2
процедура для удаления записей из 2 таблиц
    #40034421
bastibubu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте!
нужна помощь: есть бд на Interbase 2009. Задача: удалить старые записи из таблиц прихода(tIncome) и реализации(tOutcome). сначала надо удалить те записи из таблицы реализации, которые оприходованы до 01.01.2018 и в этот момент был польностю реализован (условия: i.indate<'01/01/2018' and i.qnt-sum(o.qnt)<0.001). А потом уже надо удалить записи из таблицы прихода.

Код: css
1.
2.
tIncome: in_id (pr_k), qnt(количество прихода), cur_qnt (количество сейчас) ...
tOutcome: out_id (pr_k), in_id (fk), qnt(количество реализации)... 



Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
create procedure sp_del_out_in (d date)
as
begin
  delete from tOutcome o
  where exists
  (
  select i.in_id
  from Tincome i, Toutcome o
  where  (i.in_id=o.in_id) and (i.indate<'01/01/2018')
  group by i.in_id
  having i.qnt-sum(o.qnt)<0.001
  )



процедура неправильно работает- польностю очишает таблицу реализации.

В delphi цикл правильно работает но ооочень медленно:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
qIn.open;                                                                    
  while not qIn.Eof do begin
    qOutDelete.Params[0].AsInteger:= qInIn_id.AsInteger;  
    qOutDelete.ExecSQL;

    qInDelete.Params[0].AsInteger:=qInIn_id.asInteger;
    qIn.ExecSQL;

    qIn.Next;
  end;
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034427
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bastibubu,

дык это. раз процедура, то почему бы не

for select i.in_id
...
do
delete from tOutcome
where i.in_id = ...

?
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034432
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А cur_qnt у тебя случайно не "нереализованный остаток"? Тогда всё сводится к простому
Код: sql
1.
2.
3.
4.
5.
for select in_id from tIncome where indate<'01/01/2018' and cur_qnt<0.001 into :id
begin
   delete from tOutcome where in_id = :id;
   delete from tIncome where in_id = :id;
end


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034443
bastibubu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

А cur_qnt у тебя случайно не "нереализованный остаток"?


Dimitry Sibiryakov , это текущий остаток(current quantity). Я не знаю остатки на 01/01/2018, в бд (tIncome) хранится только текущие остатки, поэтому чтобы получить остатки на 01/01/2018 пишу условие i.qnt-sum(o.qnt)<0.001.
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034444
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bastibubuэто текущий остаток(current quantity).

Вот и отличненько. Используй его. Иначе ненароком грохнешь приход, который на складе
залежался с 18-го года и тебе будет больно после ревизии.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034503
bastibubu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kdv, Dimitry Sibiryakov я неправильно сформулировал вопрос: надо узнать когда из конкретной партии последный товарь продали, было это до 01.01.18 или после, если до -тогда удаляю из бд и приход и расход а если после- тогда надо оставить в базе.
т.е. надо узнать был остаток в этот день или нет.
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034510
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
select max(тут дата продажи) group by <тут партия>


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034762
bastibubu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот что смог написать

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
create procedure sp_del_out_in (d date)
as
begin
for select i.in_id
from tIncome i, tOutcome o
where
 (i.qnt-(select sum(o.qnt) from tOutcome o where outdate<:d)<0.001) and
 (i.in_id=o.in_id)
into :in_id 
do 
begin
  delete from tOutcome where in_id = :in_id;
  delete from tIncome where in_id = :in_id;
end
end



но условие
Код: plsql
1.
 (i.qnt-(select sum(o.qnt) from tOutcome o where outdate<:d)<0.001)


неправильно работает. Возвращает все записи, и те которые продались после 01.01.18
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034765
bastibubu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
тело процедуры возвращает эти записи (без distinct).
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034766
bastibubu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
а с distinct-ом вот это.
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034771
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bastibubu,
Если правильно понял то
вариант 1
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
for select o.in_id,sum(o.qnt)
        from tOutcome o
        group by o.in_id
        having max(o.outdate) < :d   -- Последняя реализация была до указанной даты
     into :in_id,:o_qnt
do begin -- По партиям которые реализовывались до указанной даты
  
  i_qnt=0;
  select i.qnt
     from tInCome i
     where i.in_id=:in_id
   into :i_qnt;   -- Приход по партии

   if (i_qnt - o_qnt < 0.001) then
   begin -- Все реализовали
       delete from tInCome i
         where i.in_id=:in_id;
       delete from tOutCome o
         where o.in_id=:in_id;
   end -- Все реализовали
end -- По партиям которые реализовывались до указанной даты



вариант 2
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
for  select i.in_id,i.qnt
     from tInCome i
     where i.indate < :d
   into :in_id, :i_qnt
do begin    -- По партиям поступившим до указанной даты
   o_qnt=0;
   select sum(o.qnt)
        from tOutcome o
        where o.in_id = :i_in_id
        group by o.in_id
        having max(o.outdate) < :d  -- Последняя реализация была до указанной даты
     into :o_qnt; -- Реализация по партии 

   if (i_qnt - o_qnt < 0.001) then
   begin -- Все реализовали
       delete from tInCome i
         where i.in_id=:in_id;
       delete from tOutCome o
         where o.in_id=:in_id;
   end -- Все реализовали
end   -- По партиям поступившим до указанной даты


...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034784
sdfssf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
М.б. исправить запрос так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
create procedure sp_del_out_in (d date)
as
begin
  delete from tOutcome o
  where exists
  (
  select i.in_id
  from Tincome i
  where  (i.in_id=o.in_id) and (i.indate<'01/01/2018')
  group by i.in_id
  having i.qnt-sum(o.qnt)<0.001
  )
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034882
bastibubu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
m7m , установил допольнительное условие where recs_k<5000 и всеравно очень долго работал(15мин), потом отключил. Может быть и зацикливается. В Tincome около 500 000 рекордов, а в Noutcome около 3млн. :(
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034883
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и забей, БД нужна чтобы данные хранить, вот пусть и хранит.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034905
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bastibubu
m7m , установил допольнительное условие where recs_k<5000 и всеравно очень долго работал(15мин), потом отключил. Может быть и зацикливается. В Tincome около 500 000 рекордов, а в Noutcome около 3млн. :(


Ну кто-ж его знает что там у тебя
500 000, 3 000 000 - это не так уж и много
Для того чтобы что-то сказать нужны как минимум планы запросов

зы. Зациклиться ни первый ни второй вариант не может в принципе
ззы. Для того чтобы дождаться и проанализировать что-же делается на самом деле, достаточно во втором варианте ограничить количество рассматриваемых вариантов ну например первой сотней
Код: sql
1.
for select first 100 ....


что касается первого варианта то там хуже ибо ограничить то можно однако оно подействует только после выполнения всей группировки, ну и посколько у меня подозрение на то что эта группировка очень долго выполняется то как по мне это ограничение будет почти бесполезно
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034923
bastibubu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
m7m,
второй вариант:

Код: 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.
create procedure pr_del_recg_recs (d date)
as
declare variable in_id numeric(10,4);
declare variable out_id numeric(10,4);
declare variable o_qnt numeric(10,4);
declare variable i_qnt numeric(10,4);
for  select i.in_id,i.qnt
     from tInCome i
     where i.indate < :d rows 10    -- limit of rows
   into :in_id, :i_qnt
do begin
   o_qnt=0;
   select sum(o.qnt)
        from tOutcome o
        where o.in_id = :in_id
        group by o.in_id
        having max(o.outdate) < :d
     into :o_qnt;

   if (i_qnt - o_qnt < 0.001) then
   begin
       delete from tInCome i where i.in_id=:in_id;
       delete from tOutCome o where o.in_id=:in_id;
   end
end



в таблице Toutcome самый первый запись надо удалить. Лимит (rows 10).

если лимит rows=50 процедура работает около 5мин, а если rows=500- ооочень долго.
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034925
bastibubu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
plans
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034927
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bastibubu,

индексов совсем нет?
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40034993
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bastibubu,
Как минимум в
tInCome добавт индекс по indate
tOutcome добавь индекс по in_id

зы.
Код: sql
1.
2.
3.
4.
5.
6.
   select sum(o.qnt)
        from tOutcome o
        where o.in_id = :in_id
-- group by o.in_id   Убери эту строку она здесь не нужна
        having max(o.outdate) < :d
     into :o_qnt;



и когда в условии при проверке даты с константой лучше явно указывать что это дата
ибо при where i.indate < '01/01/2018' получишь неожиданный для себя результат
т.к. в данном случае indate преобразуется в строку и будет сравнение строк

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select i.in_id,i.qnt
     from tInCome i
     where i.indate < date '01/01/2018'

   select sum(o.qnt)
        from tOutcome o
        where o.in_id = :in_id
        having max(o.outdate) < date '01/01/2018'


ззы. И таки планы и запросы лучше текстом а не картинками
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40035069
bastibubu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kdv, m7m без индексов пришлось бы серверу работать около 30 часов. Эффект индексов удивительный- время сократилось до 2.5 минут!!!
большое вам спасибо!!!
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40035073
bastibubu
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
m7m
bastibubu,
и когда в условии при проверке даты с константой лучше явно указывать что это дата
ибо при where i.indate < '01/01/2018' получишь неожиданный для себя результат
т.к. в данном случае indate преобразуется в строку и будет сравнение строк



даже без этого всё обошлось!
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40035076
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ещё один чайник, пытающийся удалять данные из тормозящей БД вместо оптимизации запросов.
Печально я гляжу на это поколенье...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40035085
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

Вот пооптимизирует удаление, а там глядишь и до оптимизиции запросов дойдет, и будет оно летать
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40035086
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bastibubu
даже без этого всё обошлось!

Если ты про это
Код: sql
1.
2.
3.
 select i.in_id,i.qnt
     from tInCome i
     where i.indate < :d 

то тут оно и не нужно
а если про это
Код: sql
1.
2.
3.
select i.in_id,i.qnt
     from tInCome i
     where i.indate < '01/01/2018'

то сомневаюсь
...
Рейтинг: 0 / 0
процедура для удаления записей из 2 таблиц
    #40035091
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Firebird не дура, Firebird приводит строку к дате, а не наоборот.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
25 сообщений из 29, страница 1 из 2
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / процедура для удаления записей из 2 таблиц
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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