2 ifブロックを組み合わせて、単一のクエリを作成する
ifブロックと下から1つのブロックの両方をマージする可能性はありますか?両方とも論理的に接続されています。
p_update_modeがFUllの場合、P_entity_typeに渡されたテーブルのすべてのデータを追加する必要があります。増分の場合は、選択した追加を追加するために結合条件を設定しました。また、p_entity_typeがnullの場合は、itemテーブルとorgテーブルの両方のデータを追加する必要があります。
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つのブロックは、アクション列と結合のみが異なるように見えるため、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モードの場合は行を生成しないはずです。
これは左結合である必要があります。そうしないと、フルモードのBのエンティティに対応しない行がdata_viewから取得されない可能性があります。つまり、これが通常のJOINのままである場合、結合のAND句が原因で、クエリ全体でFULLモードで行がゼロになります。
最後に、LEFT JOINがあるため、下部のWHERE句のANDフィルターが必要になります。これがないと、INCREMENTALモードで実行すると、Bに対応するエンティティ行があるかどうかに関係なく、data_viewにすべての行が表示されます。entity_idで結合している場合でも、左結合では、Bに一致する行がなくても、Tの各行の行が戻されます。これは、LEFTJOINが行うように設計されているためです。
そうは言っても、これら2つのブロックをブレンドする価値があるかどうかを判断する必要があります。できるからといって、すべきだという意味ではありません。パフォーマンスは、そのままにしておく方が良い場合があります。いくつかのテストを実行してください。データの量と処理の頻度を知っているのはあなただけです。次の男/ギャルはここで何が起こっているのかを理解する必要があるため、コードの保守も考慮する必要があります。