powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Помогите разобраться с триггерной функцией
5 сообщений из 5, страница 1 из 1
Помогите разобраться с триггерной функцией
    #39300947
Masyny23
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!

О великий All, помоги разобраться с триггерной функцией.

Есть задача, что при вставке строк в таблицу, в другую таблицу согласно условиям должны попасть/не попасть /удалиться, записи.

Написала триггерную функцию, создала триггер.
Записи в другую таблицу добавляются, но все и еще дублируются. Как я понимаю, условия не отрабатывают, но не могу понять где. . .

В PostgreSQL совсем не сильна, не мой профиль (Мой Ms sql ). Подскажите в какую сторону нужно копать? Версия 9.2



Код: plsql
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.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
-- создание триггерной функции

CREATE FUNCTION train_discovery_f () RETURNS trigger  -- '
LANGUAGE 'plpgsql'

AS $BODY$
declare _car_id  character varying ;
_d_date  date;
_car_id_opposite  character varying;
_cars_hash  character varying;
_cars_list  character varying;
_car_id_1  character varying ;
_d_date_1  date;
_car_id_opposite_1  character varying;
_cars_hash_1  character varying;
_cars_list_1  character varying;
_rec_dt  timestamp without time zone ;
_rec_dt_1   timestamp without time zone ;
_cars_count  integer  ;




BEGIN 
-- берем последние две записи по минимальному вагону
    select distinct car_id, car_id_opposite,cars_hash,cars_list,d_date, rec_dt, cars_count
    	into _car_id ,_car_id_opposite,_cars_hash,_cars_list, _d_date, _rec_dt ,_cars_count
           from train_discovery
           where _car_id = (case when NEW.car_id_opposite < NEW.car_id then NEW.car_id_opposite else NEW.car_id end)
           and rec_dt in (select max(rec_dt) 
                          from train_discovery where car_id = case when NEW.car_id_opposite < NEW.car_id then NEW.car_id_opposite else NEW.car_id end)
           ;
   select distinct car_id, car_id_opposite,cars_hash,cars_list,d_date, rec_dt
    	into _car_id_1 ,_car_id_opposite_1,_cars_hash_1,_cars_list_1, _d_date_1, _rec_dt_1
           from train_discovery
           where _car_id = (case when NEW.car_id_opposite < NEW.car_id then NEW.car_id_opposite else NEW.car_id end)
           and rec_dt in (select max(rec_dt) 
                          from train_discovery where car_id = case when NEW.car_id_opposite < NEW.car_id then NEW.car_id_opposite else NEW.car_id end
                         and rec_dt <> _rec_dt)
           ;
-- Первая запись в этом дне, или новый головной вагон, запись добавляем
If 
(case when date_part('hour', NEW.rec_dt) between 0 and 4 then date(NEW.rec_dt- INTERVAL '1 day') else date(NEW.rec_dt) end)
<> _d_date  or _car_id is null
 
 then Insert into train_discovery values (
  NEW.rec_id ,
 		NEW.rec_dt,	
 		case when NEW.car_id_opposite < NEW.car_id then NEW.car_id_opposite else NEW.car_id end ,
        case when NEW.car_id_opposite > NEW.car_id and NEW.car_id_opposite is  null then NEW.car_id_opposite else NEW.car_id end ,
        regexp_split_to_table(NEW.cars_list, E'\\,+') ,
     	NEW.cars_list,
        NEW.cars_count,
        NEW.cars_hash,
        NEW.discovery_status,
        case when date_part('hour', NEW.rec_dt) between 0 and 4 then date(NEW.rec_dt- INTERVAL '1 day') else date(NEW.rec_dt) end );

 end if;

     -- Если даты равны, и последняя запись была кривая, а предыдущая была корректная, тогда удаляем кривую и записываем корректную
 If  (case when date_part('hour', NEW.rec_dt) between 0 and 4 then date(NEW.rec_dt- INTERVAL '1 day') else date(NEW.rec_dt) end) =  _d_date 
  and _cars_hash is null and _cars_hash_1 is not null  and _cars_hash_1 = new.cars_hash 
 
then
     -- Удалили пустую запись
     delete from train_discovery 
     where car_id = _car_id and car_id_opposite = _car_id_opposite and cars_hash = _cars_hash
     and cars_list = _cars_list and d_date = _d_datet and  rec_dt = _rec_dt ;
  -- Вставили корректную запись   
    Insert into train_discovery values (
  NEW.rec_id ,
 		NEW.rec_dt,	
 		case when NEW.car_id_opposite < NEW.car_id then NEW.car_id_opposite else NEW.car_id end  ,
        case when NEW.car_id_opposite > NEW.car_id and NEW.car_id_opposite is  null then NEW.car_id_opposite else NEW.car_id end  ,
        regexp_split_to_table(NEW.cars_list, E'\\,+')  ,
     	NEW.cars_list,
        NEW.cars_count,
        NEW.cars_hash,
        NEW.discovery_status,
        case when date_part('hour', NEW.rec_dt) between 0 and 4 then date(NEW.rec_dt- INTERVAL '1 day') else date(NEW.rec_dt) end ); 
 end if; 

   --   Если последний cars_hash был не пустой, а новая запись осталась пустой, добавляем запись.
        
 If ( case when date_part('hour', NEW.rec_dt) between 0 and 4 then date(NEW.rec_dt- INTERVAL '1 day') else date(NEW.rec_dt) end) =  _d_date 
  and _cars_hash is not null and new.cars_hash is null
 
then
  -- добавляем запись  
    Insert into train_discovery values (
  NEW.rec_id ,
 		NEW.rec_dt,	
 		case when NEW.car_id_opposite < NEW.car_id then NEW.car_id_opposite else NEW.car_id end ,
        case when NEW.car_id_opposite > NEW.car_id and NEW.car_id_opposite is  null then NEW.car_id_opposite else NEW.car_id end ,
        regexp_split_to_table(NEW.cars_list, E'\\,+') ,
     	NEW.cars_list,
        NEW.cars_count,
        NEW.cars_hash,
        NEW.discovery_status,
        case when date_part('hour', NEW.rec_dt) between 0 and 4 then date(NEW.rec_dt- INTERVAL '1 day') else date(NEW.rec_dt) end  ); 
 end if;         
 
        
--   Если последний cars_hash был пустой, и новый cars_hash пустой и списки вагонов разные.
If   (case when date_part('hour', NEW.rec_dt) between 0 and 4 then date(NEW.rec_dt- INTERVAL '1 day') else date(NEW.rec_dt) end) =  _d_date 
and  _cars_hash is null and new.cars_hash is null and 
      (  case when _cars_count < new.cars_count
       then  array[_cars_list] <array[_cars_list]
        when _cars_count > new.cars_count
       then  array[_cars_list] >array[_cars_list]
            else 
         array[_cars_list] = array[_cars_list]
       end ) is false
then  
  
     Insert into train_discovery values (
  NEW.rec_id ,
 		NEW.rec_dt,	
 		case when NEW.car_id_opposite < NEW.car_id then NEW.car_id_opposite else NEW.car_id end ,
        case when NEW.car_id_opposite > NEW.car_id and NEW.car_id_opposite is  null then NEW.car_id_opposite else NEW.car_id end ,
        regexp_split_to_table(NEW.cars_list, E'\\,+') ,
     	NEW.cars_list,
        NEW.cars_count,
        NEW.cars_hash,
        NEW.discovery_status,
        case when date_part('hour', NEW.rec_dt) between 0 and 4 then date(NEW.rec_dt- INTERVAL '1 day') else date(NEW.rec_dt) end ); 
 end if;         
     
 return NEW;
END; 
 -- ' 
$BODY$;

-- создание триггера
CREATE TRIGGER trigger_train_discovery
BEFORE  insert ON train_discovery_logging
FOR EACH ROW
EXECUTE PROCEDURE train_discovery_f ();
...
Рейтинг: 0 / 0
Помогите разобраться с триггерной функцией
    #39301094
p2.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Masyny23все и еще дублируютсяУникальность гарантирует только ограничение уникальности.
...
Рейтинг: 0 / 0
Помогите разобраться с триггерной функцией
    #39301127
Masyny23
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подскажите как можно посмотреть результат выполнения процедуры? Какие и как параметры сравниваются и почему добавляются строки, которые не должны добавляться и почему они дублируются?
...
Рейтинг: 0 / 0
Помогите разобраться с триггерной функцией
    #39301132
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Masyny23Подскажите как можно посмотреть результат выполнения процедуры? Какие и как параметры сравниваются и почему добавляются строки, которые не должны добавляться и почему они дублируются?

RAISE WARNING с отладочной инфой в код процедуры
дальше - по логу при запуске.

--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Помогите разобраться с триггерной функцией
    #39301238
Masyny23
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нашла ошибку, банально оказалась в "кривых руках"
Код: sql
1.
where _car_id = (case when NEW.car_id_opposite < NEW.car_id then NEW.car_id_opposite else NEW.car_id end)


в задание параметра использовала условие параметра _car_id, а надо было car_id.

Всем огромное спасибо.
Вопрос можно закрывать.
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Помогите разобраться с триггерной функцией
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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