sql - 结合 2 if 块并创建单个查询
问题描述
是否有可能合并 if 块并从下面创建单个块。两者在逻辑上是相连的。
如果它是 p_update_mode 是 FUll ,那么我必须添加为 P_entity_type 传递的表的所有数据。如果它是增量的,那么我已经将连接条件添加到添加选定的添加。此外,如果 p_entity_type 为空,那么我们必须为 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 个 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 连接,否则我们可能无法从您的 data_view 中获得任何与 B 中的实体不对应的完整模式的行。换句话说,如果这仍然是一个常规的 JOIN,由于连接中的 AND 子句,您的整个查询将在 FULL 模式下获得零行。
最后,由于存在 LEFT JOIN,因此底部 WHERE 子句中的 AND 过滤器变得很有必要。如果没有这个,当在 INCREMENTAL 模式下运行时,无论 B 中是否存在相应的实体行,您都会在 data_view 中获得每一行。即使您在 entity_id 上加入,即使 B 中没有匹配的行,左连接也会为 T 中的每一行带回一行,因为这就是左连接的设计目的。
综上所述,您将不得不决定是否值得混合这两个块。仅仅因为你可以,并不意味着你应该。你的表现可能会更好,让它保持原来的样子——运行一些测试。只有您知道数据量和处理频率。您还需要考虑代码的维护,因为下一个家伙/gal 必须弄清楚这里发生了什么。
推荐阅读
- gtk - 需要帮助将 Make 文件转换为 Vala 的 Meson 构建文件
- azure - 使用 Azure PowerShell 进行数据库迁移
- angular - 反应式表单模式验证无法在数组上正常工作
- javascript - VisJs 动态删除节点
- angular - Angular 6 - 在父母和孩子之间共享变量
- c# - 为什么如果我在方法中输入一个负数,否则如果没有捕获它
- javascript - 使用 OR 表示法声明具有 2 种类型的属性名称对我不起作用
- php - 如何捕捉“无法满足请求。” 页面/错误的 URL
- python - Tkinter 的 Mainloop 函数不允许其他函数运行
- javascript - 在 SAPUI5 中隐藏 ADAPT UI 配置中的字段^