首页 > 解决方案 > plsql 程序重复的代码行。试图以更好的方式制作

问题描述

我有一个场景。如果用户传递参数Entity_type,那么您只需要为该entity( table) 插入数据。如果他没有传递任何参数,那么您需要将所有必需表的数据插入到一个表中。

所以我们有一个表,如果它被传递,它将DYNAMICENTITYGTT从表中获取数据,Item如果它被传递,则从表中获取数据orgEntity_type但是如果proc中的参数为null,它将从两个表中获取数据。

它还将根据UPDATE_MODE添加或删除方式的类型存储另一列。目标表相同。源表及其列名不同但类型相同。

我已经为此编写了以下程序。

我只是要求无论如何都要使这段代码更好。我的意思是这可以用更聪明的方式写吗?因为我重复多行。我给出了 2 个实体的示例,但有 7 个,所以代码会很大。

CREATE OR REPLACE procedure UPDATE_DYNAMIC_ENTITY(ENTITY_TYPE varchar2 default null,UPDATE_MODE varchar2)
Is
x number;
BEGIN
IF UPPER(entity_type)='ITEM' then
    if upper(UPDATE_MODE)='DELETE' then
      INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select Entity_type,Item_id,item_name,item_desc,'delete' from ITEMDE;
    ELSIF lower(UPDATE_MODE)='add' then
      INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select Entity_type,Item_id,item_name,item_desc,'add' from ITEMDE;
    END IF;
ELSIF UPPER(entity_type)='ORG' then
    if upper(UPDATE_MODE)='DELETE' then
      INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select Entity_type,ORG_id,org_name,org_desc,'delete' from ORGDE;
    ELSIF lower(UPDATE_MODE)='add' then
      INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select Entity_type,ORG_id,org_name,org_desc,'add' from ORGDE;
    END IF;
ELSE
   if upper(UPDATE_MODE)='DELETE' then
      INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select Entity_type,Item_id,item_name,item_desc,'delete' from ITEMDE;
      INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select Entity_type,ORG_id,org_name,org_desc,'delete' from ORGDE;
    ELSIF lower(UPDATE_MODE)='add' then
      INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select Entity_type,Item_id,item_name,item_desc,'add' from ITEMDE;
      INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select Entity_type,ORG_id,org_name,org_desc,'add' from ORGDE;
   END IF;
   
END IF;
END UPDATE_DYNAMIC_ENTITY;

标签: sqldatabaseoracleplsqlplsqldeveloper

解决方案


基本上我看到两个插入两个变量确定其内容。您是从 select 语句中插入的,因此您可以操纵这些选择以在条件不符合预期时不返回任何值。

对于参数p_update_mode很容易,如果它包含值“删除”插入“删除”,如果它包含值“添加”插入“添加”。

对于p_entity_type我们从两个选择中插入的参数,当其值为“NULL”时,itemde如果值为“ITEM”,则仅从表中插入,orgde如果值为“ORG”,则仅从表中插入。

现在,如果在任何选择中都有一些无效值,p_entity_type则不会产生数据,因为我们只识别“NULL”、“ITEM”和“ORG”。但是对于参数p_update_mode我们直接修改值并在插入中使用它,因此最好执行一些检查输入值是否对我们有效。

CREATE OR REPLACE PROCEDURE update_dynamic_entity(p_entity_type VARCHAR2 DEFAULT NULL,
                                                  p_update_mode VARCHAR2) IS
BEGIN
  IF lower(p_update_mode) NOT IN ('add', 'delete')
  THEN
    RAISE VALUE_ERROR; -- maybe use raise_application_error for more details about problem
  END IF;
  --
  INSERT INTO dynamicentitygtt
    (entity_type, entity_id, entity_code, synonyms, action)
    SELECT upper(NVL(p_entity_type, 'ITEM')), item_id, item_name, item_desc, lower(p_update_mode)
      FROM itemde
     WHERE upper(p_entity_type) = 'ITEM'
        OR p_entity_type IS NULL;
  --
  INSERT INTO dynamicentitygtt
    (entity_type, entity_id, entity_code, synonyms, action)
    SELECT upper(NVL(p_entity_type, 'ORG')), org_id, org_name, org_desc, lower(p_update_mode)
      FROM orgde
     WHERE upper(p_entity_type) = 'ORG'
        OR p_entity_type IS NULL;
END update_dynamic_entity;

在您编写时,您有 7 个实体,因此这种方法将导致有 7 个插入,因为我相信(如果我错了,请告诉我)每个实体在不同的表中都有自己的数据集。

也有可能连接所有这些表并使其成为单个插入,如下例所示,每个新实体都意味着仅将新选择添加到WITH语句的一部分中。但我不确定在这种情况下的表现。这将取决于您的桌子有多满。

CREATE OR REPLACE PROCEDURE update_dynamic_entity(p_entity_type VARCHAR2 DEFAULT NULL,
                                                  p_update_mode VARCHAR2) IS
BEGIN
  IF lower(p_update_mode) NOT IN ('add', 'delete')
  THEN
    RAISE VALUE_ERROR; -- maybe use raise_application_error for more details about problem
  END IF;
  --
  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
        FROM itemde
      UNION ALL
      -- ORG table
      SELECT 'ORG' entity_type, -- This separates inserted values
              org_id,
              org_name,
              org_desc
        FROM orgde
      -- NEXT entity table
      )
    SELECT upper(entity_type), data_id, data_name, data_desc, lower(p_update_mode)
      FROM data_view
     WHERE upper(p_entity_type) = entity_type
        OR p_entity_type IS NULL;
END update_dynamic_entity;

即使这对您来说很混乱,您也可以创建一个VIEW您执行UNIONs 的位置并将其WITH从中删除,PROCEDURE并使用新实体将 selects 添加到VIEW而不是PROCEDURE.


推荐阅读