#sql #oracle #merge #nvl
#sql #Oracle #слияние #nvl
Вопрос:
У меня есть инструкция слияния ниже, и я хочу добавить в качестве условия, что если X_RECEIVED_ON_DT равно нулю, он будет использовать дату в FULFILLED_ON_DT и PO_CLOSED_DT, которые являются столбцами в TGT (целевой таблице) для заполнения столбца TGT.X_GAAP_EXCH_RATE_WID
MERGE
/* PARALLEL(8) */
INTO W_PURCH_COST_F TGT USING
(SELECT
/* PARALLEL(8) */
cost.INTEGRATION_ID,
cost.X_RECEIVED_ON_DT,
cost.LOC_CURR_CODE,
COALESCE(gaap.ROW_WID,0) X_GAAP_EXCH_RATE_WID
FROM W_Purch_Cost_F_3955 cost
JOIN W_DAY_D wday
ON TRUNC(cost.X_RECEIVED_ON_DT)=TRUNC(wday.CALENDAR_DATE)
LEFT OUTER JOIN WC_GAAP_EXCH_RATE_G gaap
ON gaap.PERIOD =wday.PER_NAME_ENT_PERIOD
AND cost.LOC_CURR_CODE =gaap.FROM_CURCY_CD
) SRC ON (TGT.INTEGRATION_ID = SRC.INTEGRATION_ID AND TGT.DATASOURCE_NUM_ID = 310)
WHEN MATCHED THEN
UPDATE SET TGT.X_GAAP_EXCH_RATE_WID = SRC.X_GAAP_EXCH_RATE_WID;
Ответ №1:
Если вы хотите ссылаться на W_PURCH_COST_F
(псевдоним TGT
) в исходном запросе, вам придется включить его в предложение SRC
‘s FROM
.
Это означает, что в этом W_PURCH_COST_F
заявлении у вас будет две MERGE
таблицы — одна в качестве цели слияния (как у вас уже есть сейчас), другая в качестве «источника», используемого для объединения с другими таблицами в SRC
. Тогда использовать NVL
, CASE
или DECODE
и делать то, что вы хотите, — простая задача.
Хотя я не совсем понимаю, как вы будете использовать оба FULFILLED_ON_DT
и PO_CLOSED_DT
, но я надеюсь, что вы знаете.
Пример, основанный на схеме Скотта (поскольку у меня нет ваших таблиц):
Это не сработает — вы не можете ссылаться TGT
в SRC
:
SQL> merge into emp e
2 using (select distinct d.deptno, d.dname, d.loc
3 from dept d
4 where d.deptno = e.deptno --> not allowed
5 ) x
6 on (e.deptno = x.deptno)
7 when matched then update set e.ename = x.loc;
where d.deptno = e.deptno
*
ERROR at line 4:
ORA-00904: "E"."DEPTNO": invalid identifier
Но, если используется в SRC
предложении FROM
, это работает:
SQL> merge into emp e
2 using (select distinct d.deptno, d.dname, d.loc
3 from dept d join emp a on a.deptno = d.deptno
4 ) x
5 on (e.deptno = x.deptno)
6 when matched then update set e.ename = x.loc;
14 rows merged.
SQL>
Варианты, которые вы, возможно, захотите рассмотреть, следующие:
-
Вложенный
NVL
:nvl(x_received_on_dt, nvl(fulfilled_on_dt, po_closed_dt))
-
coalesce
(возвращает первое ненулевое значение):coalesce(x_received_on_dt, fulfilled_on_dt, po_closed_dt, sysdate)
coalesce
для меня это лучший выбор.
Комментарии:
1. Привет @Littlefoot , извините, он будет использовать либо FULFILLED_ON_DT, либо PO_CLOSED_DT, если значение FULFILLED_ON_DT не равно null, он будет использовать это, если его значение равно null, будет использовать PO_CLOSED_DT, иначе 0
2. Хорошо, используйте вложенные NVL. Однако вы не можете использовать 0 (число) со значениями ДАТЫ из-за несовместимых типов данных. Должно быть что-то еще — значение ДАТЫ (например, SYSDATE или какая-либо недопустимая дата, например, ДАТА ‘1000-01-01’).
3. Привет @ Littlefoot, я получил ошибку с отсутствующим ключевым словом. это мой выбор NVL (СЛУЧАЙ, КОГДА стоимость. X_RECEIVED_ON_DT РАВНО НУЛЮ, ТОГДА SRC1.FULFILLED_ON_DT, ИНАЧЕ SRC1.PO_CLOSED_DT,0)
4. Я отредактировал свой ответ и добавил примеры NVL и COALESCE; взгляните.