2 if 블록 결합 및 단일 쿼리 생성
if 블록을 병합하고 아래에서 단일 블록을 만들 가능성이 있습니까? 둘 다 논리적으로 연결되어 있습니다.
p_update_mode가 FUll이면 P_entity_type에 전달 된 테이블의 모든 데이터를 추가해야합니다. 증분이면 선택한 추가를 추가하는 조인 조건을 설정했습니다. 또한 p_entity_type이 null이면 항목 및 조직 테이블 모두에 대한 데이터를 추가해야합니다.
CREATE OR REPLACE PROCEDURE update_dynamic_entity(p_entity_type VARCHAR2 DEFAULT NULL,
p_update_mode VARCHAR2) IS
BEGIN
IF lower(p_update_mode) = 'incremental'
THEN
INSERT INTO dynamicentitygtt
(entity_type, entity_id, entity_code, synonyms, action)
WITH data_view AS
( -- ITEM table
SELECT 'ITEM' entity_type, -- This separates inserted values
item_id data_id,
item_name data_name,
item_desc data_desc,
creation_date
FROM itemde
UNION ALL
-- ORG table
SELECT 'ORG' entity_type, -- This separates inserted values
org_id,
org_name,
org_desc,
creation_date
FROM orgde
-- NEXT entity table
)
SELECT upper(t.entity_type),
t.data_id,
t.data_name,
t.data_desc,
CASE
WHEN t.creation_date > b.max_last_update_date THEN
'update'
WHEN t.creation_date < b.max_last_update_date THEN
'add'
END
FROM data_view t
JOIN batch_run_details b
ON b.entity_type = t.entity_type
WHERE upper(p_entity_type) = t.entity_type
OR p_entity_type IS NULL;
END IF;
IF UPPER(UPDATE_MODE)='FULL' then
INSERT INTO dynamicentitygtt
(entity_type, entity_id, entity_code, synonyms, action)
WITH data_view AS
(
SELECT 'ITEM' entity_type, -- This separates inserted values
item_id data_id,
item_name data_name,
item_desc data_desc,
'add' action
FROM itemde
UNION ALL
-- ORG table
SELECT 'ORG' entity_type, -- This separates inserted values
org_id,
org_name,
org_desc,
'add' action
FROM orgde
)
SELECT upper(entity_type), data_id, data_name, data_desc,action
FROM data_view
WHERE upper(p_entity_type) = entity_type
OR p_entity_type IS NULL;
END IF;
END update_dynamic_entity;
답변
(참고 :이 코드는 테스트되지 않았으며 여기에 쉼표 또는 괄호가 없을 수 있습니다 ...)
이 두 블록은 액션 열과 조인에서만 다른 것처럼 보이므로 2 개의 IF 구간을 제거하고 p_update_mode 검사를 다음과 같이 CASE 문으로 이동할 수 있습니다.
CREATE OR REPLACE PROCEDURE update_dynamic_entity(p_entity_type VARCHAR2 DEFAULT NULL,
p_update_mode VARCHAR2) IS
BEGIN
INSERT INTO dynamicentitygtt
(entity_type, entity_id, entity_code, synonyms, action)
WITH data_view AS
( -- ITEM table
SELECT 'ITEM' entity_type, -- This separates inserted values
item_id data_id,
item_name data_name,
item_desc data_desc,
creation_date
FROM itemde
UNION ALL
-- ORG table
SELECT 'ORG' entity_type, -- This separates inserted values
org_id,
org_name,
org_desc,
creation_date
FROM orgde
-- NEXT entity table
)
SELECT upper(t.entity_type),
t.data_id,
t.data_name,
t.data_desc,
CASE lower(p_update_mode)
WHEN 'incremental' THEN
CASE
WHEN t.creation_date > b.max_last_update_date THEN
'update'
WHEN t.creation_date < b.max_last_update_date THEN
'add'
END
WHEN 'full' THEN
'add'
END action
FROM data_view t
LEFT JOIN batch_run_details b
ON b.entity_type = t.entity_type
AND lower(p_update_mode )='incremental'
WHERE (upper(p_entity_type) = t.entity_type OR p_entity_type IS NULL)
AND (lower(p_update_mode) = 'full'
OR (lower(p_update_mode) = 'incremental' AND b.entity_type IS NOT NULL)
);
END update_dynamic_entity;
FULL 블록의 쿼리는이 모드에서 B에 조인하면 안된다고 말합니다. 따라서 LEFT JOIN 절은 INCREMENTAL 모드에있을 때만 행을 가져 오지만 FULL 모드에 대해서는 행을 생성하지 않아야합니다.
이것은 LEFT 조인이어야합니다. 그렇지 않으면 FULL 모드에 대해 B의 엔터티에 해당하지 않는 data_view에서 행을 가져 오지 못할 수 있습니다. 즉, 이것이 일반 JOIN으로 남아 있으면 전체 쿼리는 조인의 AND 절로 인해 FULL 모드에서 0 행을 얻습니다.
마지막으로 LEFT JOIN이 있으므로 하단 WHERE 절의 AND 필터가 필요합니다. 이것이 없으면 INCREMENTAL 모드로 실행할 때 B에 해당 엔티티 행이 있는지 여부에 관계없이 data_view의 모든 행을 얻을 수 있습니다. entity_id에 조인하더라도 왼쪽 조인은 B에 일치하는 행이 없어도 T의 각 행에 대해 행을 다시 가져올 것입니다. 이것이 LEFT JOIN이 수행하도록 설계된 것이기 때문입니다.
즉,이 두 블록을 혼합 할 가치가 있는지 결정해야합니다. 할 수 있다고해서 반드시해야한다는 의미는 아닙니다. 당신의 성능은 당신이 가지고있는 그대로 두는 것이 더 나을 수 있습니다. 데이터의 양과 처리 빈도를 아는 사람은 당신뿐입니다. 다음 사람 / 걸이 여기서 무슨 일이 벌어지고 있는지 파악해야하기 때문에 코드 유지 관리도 고려해야합니다.