powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как правильно произвести Insert
25 сообщений из 26, страница 1 из 2
Как правильно произвести Insert
    #39417920
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, всем.
Подскажите как правильно отработать такую задачу.

Есть такая таблица (система тарифов)

Код: 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.
CREATE TABLE TARIF (
    DATA_TR    DATE NOT NULL,
    DATA_E     DATE,
    DATA_R     DATE NOT NULL,
    MARK       SMALLINT,
    NUMB       SMALLINT,
    TARN       SMALLINT,
    COD_POSL   SMALLINT,
    COD_RIZN   SMALLINT,
    NORM_US    NUMERIC(5,2),
    NORM_USD   NUMERIC(5,2),
    CODE_NN    SMALLINT,
    CODE_NDN   SMALLINT,
    CODE_UNIT  SMALLINT,
    COST_UNIT  NUMERIC(10,5),
    COST_UN1   NUMERIC(10,5),
    COST_UN2   NUMERIC(10,5),
    NORM       NUMERIC(10,5),
    NORM_DOP   NUMERIC(10,5),
    NORM_MAX   NUMERIC(10,5),
    VOL_UN0    NUMERIC(7,2),
    VOL_UN1    NUMERIC(7,2),
    OPAL_TIP   SMALLINT,
    CODE_FROG  SMALLINT
);
CREATE INDEX TR_KEY_DATA ON TARIF (NUMB, TARN, DATA_E, COD_POSL, COD_RIZN);
CREATE INDEX TR_KEY_TAR ON TARIF (TARN, NUMB, DATA_E, COD_POSL, COD_RIZN);




Это таблица тарифов на жилищно-коммунальные услуги.
По ключевым полям: DATA_TR, DATA_E, DATA_R, NUMB, TARN может быть десятки строк.
У текущей, действующей, системы тарифов DATA_E is null.

Нужно добавить новые тарифы.
В целом задача сводится к тому что нужно сделать копию ВСЕХ строчек действующей системы тарифов (DATA_E is null) с установкой новой DATA_TR (указывается пользователем) и DATA_R равную СЕГОДНЯ. У "старой" системы тарифов нужно установить DATA_E=(текущая дата-1).

Порядок моих действий:
1. У действующей системы нужно установить DATA_E=текущая дата-1, предварительно сохранив в переменные DATA_TR, DATA_R, NUMB, TARN.
2. Теперь делаю insert record ... from select ... where (data_tr=:data_tr)and(data_r=:data_r)and(numb=:numb)and(tarn=:tarn). Делаю это без выборки поля DATA_E, чтобы ему прописался NULL
3. После добавления мне нужно изменить DATA_TR и DATA_R.

Правильный ли порядок действий. И возможно ли объединить п.2 и п.3, например делая инсерт в хранимой процедуре с заменой необходимых дат. Или еще лучше - все пункты объединить в ХП
Такое возможно????

Я не прошу писать ХП. Если это возможно - я сам напишу и покажу ХП для получения советов.

--------------------------
Firebird 3.0.1.32609;
IBExpert 2017.2.7.1;
Windows 10 32-bit;
4Gb RAM;
SSD 512Mb + HDD 1 Tb;
Настройки по умолчанию
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39417970
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush,

Можно написать триггер на Insert. В этом триггере отработать нужные изменения.
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39417977
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,
А в тригер можно передать, в данном случае, даты которые нужно установить?
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39417993
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrushА в тригер можно передать, в данном случае, даты которые нужно установить?
Триггер при вставке и изменении строки имеет доступ к новым и старым данным.
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418011
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman,
Это хорошо, но мне нужно установить DATA_TR ту которую ввел пользователь.
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418021
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrushЭто хорошо, но мне нужно установить DATA_TR ту которую ввел пользователь.
Эта дата будет в новых данных. https://firebirdsql.org/refdocs/langrefupd21-ddl-trigger.html
см new.* и old.*
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418032
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush,

В одной тр-ции:
Код: sql
1.
2.
3.
4.
5.
6.
7.
update tarif set data_e = current_date - 1
 where data_e is null;

insert into tarif (data_tr, data_r, data_e, остальные_поля)
select current_date, :data_user, null, остальные_поля
  from tarif 
 where data_e = current_date - 1
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418036
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman,
Если делать инсерт уже с нужными датами, то и тригер мне писать не нужно.

Суть вопроса была в чем.
По отдельности я могу выполнить все пункты поочереди.
Возможно ли их объединить, например в ХП?
Пробую писать ХП - не получается.
Делаю так:


Код: 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.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
create or alter procedure TARIF_ADD (
    I_DATA_TR date,
    I_DATA_R date,
    I_DATA_E date,
    I_NUMB integer,
    I_TARN integer)
as
declare variable IN_DATA_TR date;
declare variable IN_DATA_E date;
declare variable IN_DATA_R date;
declare variable IN_NUMB smallint;
declare variable IN_TARN smallint;
declare variable DATA_TR date;
declare variable DATA_E date;
declare variable DATA_R date;
declare variable MARK smallint;
declare variable NUMB smallint;
declare variable TARN smallint;
declare variable COD_POSL smallint;
declare variable COD_RIZN smallint;
declare variable NORM_US numeric(5,2);
declare variable NORM_USD numeric(5,2);
declare variable CODE_NN smallint;
declare variable CODE_NDN smallint;
declare variable CODE_UNIT smallint;
declare variable COST_UNIT numeric(10,5);
declare variable COST_UN1 numeric(10,5);
declare variable COST_UN2 numeric(10,5);
declare variable NORM numeric(10,5);
declare variable NORM_DOP numeric(10,5);
declare variable NORM_MAX numeric(10,5);
declare variable VOL_UN0 numeric(7,2);
declare variable VOL_UN1 numeric(7,2);
declare variable OPAL_TIP smallint;
declare variable CODE_FROG smallint;
begin
  /* Procedure Text */
  in_data_e=i_data_e;
  in_data_r=i_data_r;
  in_data_tr=i_data_tr;
  in_tarn=i_tarn;
  in_numb=i_numb;
  for select DATA_TR, data_e,   MARK, NUMB, TARN, COD_POSL, COD_RIZN,
             NORM_US, NORM_USD, CODE_NN, CODE_NDN, CODE_UNIT, COST_UNIT,
             COST_UN1, COST_UN2, NORM, NORM_DOP, NORM_MAX, VOL_UN0, VOL_UN1,
             OPAL_TIP, CODE_FROG
             from TARIF
             where (data_e is null)
      into :DATA_TR,  :Data_e,   :DATA_R,   :MARK,      :NUMB,
           :TARN,     :COD_POSL, :COD_RIZN,  :NORM_US,   :NORM_USD,
           :CODE_NN,  :CODE_NDN, :CODE_UNIT, :COST_UNIT, :COST_UN1,
           :COST_UN2, :NORM,     :NORM_DOP,  :NORM_MAX,  :VOL_UN0,
           :VOL_UN1,  :OPAL_TIP, :CODE_FROG
      do
        begin
          --data_e=in_data_e;
          update tarif set data_e=in_data_e
              where (data_tr=data_tr)and(data_r=data_r)and(numb=numb)
                    and(tarn=tarn);
          insert into TARIF (DATA_TR,  DATA_R,    MARK,      NUMB,     TARN,
                             COD_POSL, COD_RIZN,  NORM_US,   NORM_USD, CODE_NN,
                             CODE_NDN, CODE_UNIT, COST_UNIT, COST_UN1, COST_UN2,
                             NORM,     NORM_DOP,  NORM_MAX,  VOL_UN0,  VOL_UN1,
                             OPAL_TIP, CODE_FROG)
              values (In_DATA_TR, in_data_r,  MARK,      In_NUMB,   in_TARN,
                      COD_POSL,  COD_RIZN,  NORM_US,   NORM_USD, CODE_NN,
                      CODE_NDN,  CODE_UNIT, COST_UNIT, COST_UN1, COST_UN2,
                      NORM,      NORM_DOP,  NORM_MAX,  VOL_UN0,  VOL_UN1,
                      OPAL_TIP,  CODE_FROG);
        end
end




Ругается что "неизвестная колонка in_data_e".
Что делаю неправильно? Если вообще подобное можно уместить в ХП.
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418037
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrushРугается что "неизвестная колонка in_data_e".
Что делаю неправильно?Двоеточие забыл
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418092
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrushЕсли делать инсерт уже с нужными датами, то и тригер мне писать не нужно.
Нужно, просто ты не понимаешь, о чем я. :)

1. Делаешь вставку с новым тарифом.
2. Триггер перед вставкой закрывает текущий тариф.
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418148
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сделал через ХП

Код: 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.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
create or alter procedure TARIF_ADD (
    I_DATA_TR date,
    I_DATA_R date,
    I_DATA_E date,
    I_NUMB integer,
    I_TARN integer)
AS
declare variable DATA_TR date;
--declare variable DATA_E date;
declare variable DATA_R date;
declare variable MARK smallint;
declare variable NUMB smallint;
declare variable TARN smallint;
declare variable COD_POSL smallint;
declare variable COD_RIZN smallint;
declare variable NORM_US numeric(5,2);
declare variable NORM_USD numeric(5,2);
declare variable CODE_NN smallint;
declare variable CODE_NDN smallint;
declare variable CODE_UNIT smallint;
declare variable COST_UNIT numeric(10,5);
declare variable COST_UN1 numeric(10,5);
declare variable COST_UN2 numeric(10,5);
declare variable NORM numeric(10,5);
declare variable NORM_DOP numeric(10,5);
declare variable NORM_MAX numeric(10,5);
declare variable VOL_UN0 numeric(7,2);
declare variable VOL_UN1 numeric(7,2);
declare variable OPAL_TIP smallint;
declare variable CODE_FROG smallint;
begin
  /* Procedure Text */
  for select DATA_TR, DATA_R,   MARK, NUMB, TARN, COD_POSL, COD_RIZN,
             NORM_US, NORM_USD, CODE_NN, CODE_NDN, CODE_UNIT, COST_UNIT,
             COST_UN1, COST_UN2, NORM, NORM_DOP, NORM_MAX, VOL_UN0, VOL_UN1,
             OPAL_TIP, CODE_FROG
             from TARIF
             where (data_e is null)and(tarn=:i_tarn)and(numb=:i_numb)
      into :DATA_TR,  :DATA_R,   :MARK,      :NUMB,
           :TARN,     :COD_POSL, :COD_RIZN,  :NORM_US,   :NORM_USD,
           :CODE_NN,  :CODE_NDN, :CODE_UNIT, :COST_UNIT, :COST_UN1,
           :COST_UN2, :NORM,     :NORM_DOP,  :NORM_MAX,  :VOL_UN0,
           :VOL_UN1,  :OPAL_TIP, :CODE_FROG
      do
        begin
          update tarif set data_e=:i_data_e
              where (data_tr=:data_tr)and(data_r=:data_r)and(numb=:numb)
                    and(tarn=:tarn);
          :data_tr=i_data_tr;
          :data_r=i_data_r;
          :numb=i_numb;
          :tarn=i_tarn;
          insert into TARIF (DATA_TR,  DATA_R,    MARK,      NUMB,     TARN,
                             COD_POSL, COD_RIZN,  NORM_US,   NORM_USD, CODE_NN,
                             CODE_NDN, CODE_UNIT, COST_UNIT, COST_UN1, COST_UN2,
                             NORM,     NORM_DOP,  NORM_MAX,  VOL_UN0,  VOL_UN1,
                             OPAL_TIP, CODE_FROG)
               values(:DATA_TR,   :data_r,    :MARK,      :NUMB,     :TARN,
                      :COD_POSL,  :COD_RIZN,  :NORM_US,   :NORM_USD, :CODE_NN,
                      :CODE_NDN,  :CODE_UNIT, :COST_UNIT, :COST_UN1, :COST_UN2,
                      :NORM,      :NORM_DOP,  :NORM_MAX,  :VOL_UN0,  :VOL_UN1,
                      :OPAL_TIP,  :CODE_FROG);
        end
end




502 строчки изменяется/добавляется за 3-5 сек.
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418156
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Долго.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418157
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush502 строчки изменяется/добавляется за 3-5 сек.

это медлено
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418171
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,
т.е. 502 строчки прописать дату_е
и 502 строчки добавить за 3-5 сек. долго?
Суммарно, редактируется/добавляется, 1004 строки.

А как можно ускорить.
Тут советовали через тригер, но я увы пока не могу понять как это правильно реализовать.
Перебирать через делфи 502 строки и гнать запрос на добавление (с параметрами) и еще тригером у старой строки менять дату_е.
Мне кажется будет дольше, т.к. 502 строки в данном случае должны уйти сначала на клиента, а потом назад.

Или я совсем запутался :(
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418200
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush,

А чего непонятного. Пишешь запрос "insert into ... select ...". А в триггере пишешь свой код для update. Переменные с двоеточиями будут только с префиксом new. В принципе должно получиться компактней. На скорость, скорее всего, мало повлияет. Посмотри анализ запроса, возможно индекса какого не хватает (отдельно по селекту и отдельно по апдейту).
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418243
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush> т.е. 502 строчки прописать дату_е
> и 502 строчки добавить за 3-5 сек. долго?

Конечно. Очень долго.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418245
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Собсно, ты же сам недавно 2 ляма за 20 минут
импортил с обработкой - даже эта медленная
скорость кратно выше, чем 500 записей за 5 сек.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418280
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush....А как можно ускорить.....
прочитай внимательно что hvlad написал 20289252
(при желании можешь и в процедуру это вкатать, вместо того что ты там написал)

зы. и так, занудства ради
в структуре таблицы нет ни первичного ключа ни уникального индекса (что может быть аукнется впоследствии в самый неподходящий момент)
или ты их экономии ради не показал здесь
......
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418285
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m7m,
Их пока нет.
То что я привел - это то что существует.
Можно сделать и уникальный индекс, но он получится по полям:
DATA_TR DATE NOT NULL,
DATA_E DATE,
DATA_R DATE NOT NULL,
NUMB SMALLINT,
TARN SMALLINT,
COD_POSL SMALLINT,
COD_RIZN SMALLINT,

Не много для индекса?

А сообщение Влада только понял что он имел ввиду.
Днем голова сильно "бо-бо" наверное сразу не понял что Влад имел ввиду.
Сейчас попробую.
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418292
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush,

ну тогда не удивительно, что у тебя медленно работает
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418342
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисakrush,

ну тогда не удивительно, что у тебя медленно работает
Денис, индекса еще нет.
только те которые в первом посте.
Какой индекс посоветуете создать.
Приведенные выше поля - в совокупности дают уникальную запись
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418343
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Влад, огромное спасибо.
Благодаря подсказке время обработки тех же 502+502 строчки - 0сек.
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418354
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush> Приведенные выше поля - в совокупности дают уникальную запись

Почитай про искусственные (суррогатные) ключи.
Про это есть куча статей и обсуждений.
Большинство разработчиков при создании таблицы
указывают первое поле Id уже чисто автоматически.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418356
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush> Благодаря подсказке время обработки тех же 502+502 строчки - 0сек.

Всё равно даже с той ХП - очень медленно.
Надо смотреть почему, индексов нет или т.п.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как правильно произвести Insert
    #39418358
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустам,
какие-то индексы есть.
Приведены в первом посте.
Эти индексы в текущей, ДОС, программе работют.
насчет новых индексов и ограничений я еще не думал.
...
Рейтинг: 0 / 0
25 сообщений из 26, страница 1 из 2
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как правильно произвести Insert
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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