Оператор SQL Merge не примет некоторые из моих идентификаторов

Привет, я создал следующую инструкцию SQL, чтобы помочь мне объединить данные из одной таблицы в другую таблицу. Следующий код работает нормально.

MERGE INTO FTOURSTATS ts
USING (SELECT * FROM guest_tour) t
ON (t.TOUR_ID = ts.TOURID AND t.START_DATETIME = (SELECT CALENDARDATE FROM FTIMEPERIOD tp WHERE ts.TIMEID = tp.TIMEID) AND ((SELECT SYSDATE FROM DUAL) - t.START_DATETIME ) < 7)
WHEN MATCHED THEN 
UPDATE SET 
ts.TOTALREVENUE = ts.TOTALREVENUE + ((SELECT COST_PER_DAY FROM TOUR WHERE TOUR_ID = t.TOUR_ID) * 0.1),
ts.TOTALTOURISTS = ts.TOTALTOURISTS + t.GROUP_SIZE

Однако, когда я ввожу следующий код

WHEN NOT MATCHED THEN 
INSERT VALUES( (SELECT TIMEID FROM FTIMEPERIOD WHERE CALENDARDATE = t.TOUR_ID),1, t.TOUR_ID,(SELECT COST_PER_DAY FROM TOUR WHERE TOUR_ID = t.TOUR_ID) * 0.1,t.group_size);

Я получаю следующую ошибку

Error at Command Line : 10 Column : 69
Error report -
SQL Error: ORA-00904: "T"."TOUR_ID": invalid identifier
00904. 00000 -  "%s: invalid identifier"
*Cause:    
*Action:

Но все идентификаторы работали в разделе выше. Возможно, это связано с проблемой масштаба? Любая помощь будет высоко оценена. Я хочу, чтобы и Matched, и NOT Matched что-то делали. Они пометили это как дубликат, когда ничего не нужно делать в сопоставлении, но это мне совсем не помогает.


person Steve Rogers    schedule 08.10.2019    source источник


Ответы (2)


Поможет ли это?

UPDATE SET 
ts.TOTALREVENUE = (select ts.TOTALREVENUE + r.COST_PER_DAY * 0.1
                   FROM TOUR r
                   WHERE r.TOUR_ID = t.TOUR_ID
                  )

Вариант функции, который я упомянул в комментарии:

create or replace function f_cpd (par_tour_id in tour.tour_id%type)
  return tour.cost_per_day%type
as
  retval tour.cost_per_day%type;
begin
  select cost_per_day * 0.1
    into retval
    from tour
    where tour_id = par_tour_id;

  return retval;
end;

values
( (SELECT TIMEID FROM FTIMEPERIOD WHERE CALENDARDATE = t.START_DATETIME),
   1, 
   t.TOUR_ID,
   f_cpd(t.tour_id),            --> use it here
   t.group_size
);
person Littlefoot    schedule 08.10.2019
comment
Набор UPDATE работает нормально, это INSERT, который дает проблемы, которые я считаю - person Steve Rogers; 08.10.2019
comment
Ах, извините; каким-то образом я страдал частичной слепотой и не видел написанного. Это должен быть оператор выбора COST_PER_DAY, который вызывает проблемы; Я согласен с вами, TOUR_ID кажется слишком глубоким. Попробуйте переписать эти операторы SELECT в функции и вызвать их, передав T.TOUR_ID в качестве параметра. Да, я знаю - переключение контекста и прочее, но... посмотрим, поможет ли это. Я отредактировал свое сообщение, добавив пример, чтобы показать, что я имел в виду. - person Littlefoot; 08.10.2019
comment
Но с разделом стоимости все в порядке, проблем нет, если я просто запускаю его до вставки, но если я запускаю вставку, возникают проблемы. - person Steve Rogers; 08.10.2019
comment
Верно; код, который я разместил, следует использовать вместо части INSERT. - person Littlefoot; 08.10.2019

Присоедините таблицу TOUR к таблице GUEST_TOUR в предложении USING (при условии, что каждая строка GUEST_TOUR относится к одной строке TOUR), а затем вы можете использовать ее в предложении UPDATE:

MERGE INTO FTOURSTATS ts
USING (
  SELECT gt.*,
         t.cost_per_day
  FROM   guest_tour gt
         LEFT OUTER JOIN tour t
         ON gt.tour_id = t.tour_id
) src
ON (   src.TOUR_ID = ts.TOURID
   AND EXISTS( SELECT 1
               FROM   FTIMEPERIOD tp
               WHERE  tp.CALENDARDATE = src.START_DATETIME
               AND    tp.TIMEID       = ts.TIMEID )
  AND SYSDATE - src.START_DATETIME < 7
)
WHEN MATCHED THEN 
UPDATE SET 
  TOTALREVENUE  = ts.TOTALREVENUE  + src.cost_per_day * 0.1,
  TOTALTOURISTS = ts.TOTALTOURISTS + src.GROUP_SIZE
person MT0    schedule 08.10.2019