Combinando 2 bloqueos if y creando una sola consulta

Aug 20 2020

¿Existe alguna posibilidad de fusionar el bloque if y crear un solo bloque desde abajo? Ambos están conectados lógicamente.

Si es p_update_mode es COMPLETO, entonces tengo que agregar todos los datos de la tabla pasados ​​para P_entity_type. si es incremental, he puesto la condición de unión para agregar el complemento seleccionado. Además, si p_entity_type es nulo, entonces tenemos que agregar datos tanto para el elemento como para las tablas de organización.

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;

Respuestas

2 KevinMcCabe Aug 21 2020 at 04:58

(NOTA: este código no está probado y es posible que no tenga una coma aquí o un paréntesis allá ...)

Esos dos bloques parecen solo diferir en la columna de acción y una combinación, por lo que podría eliminar las 2 patas IF y mover la verificación de p_update_mode a una declaración CASE como esta:

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;

La consulta en su bloque FULL dice que no deberíamos unirnos a B en este modo. Por lo tanto, la cláusula LEFT JOIN solo devuelve filas cuando está en modo INCREMENTAL, pero no debería producir filas para el modo FULL.

Esto debe ser una combinación IZQUIERDA o es posible que no obtengamos ninguna fila de su vista de datos que no corresponda a las entidades en B para el modo COMPLETO. En otras palabras, si esto siguiera siendo un JOIN regular, su consulta general obtendría cero filas en modo FULL debido a la cláusula AND en la combinación.

Por último, el filtro AND en la cláusula WHERE en la parte inferior se vuelve necesario ahora que hay un LEFT JOIN. Sin esto, cuando se ejecuta en modo INCREMENTAL, obtendría CADA fila en su data_view INDEPENDIENTEMENTE de que haya una fila de entidad correspondiente en B o no. Aunque se está uniendo en entity_id, la unión izquierda traerá una fila para cada fila en T incluso sin una fila coincidente en B, porque eso es para lo que se diseñaron las LEFT JOIN.

Dicho todo esto, tendrás que decidir si vale la pena combinar estos dos bloques. Solo porque PUEDES, no significa que DEBES. Su rendimiento puede ser mejor si lo deja como lo tiene: ejecute algunas pruebas. Solo usted conoce el volumen de datos y la frecuencia de procesamiento. También debe considerar el mantenimiento de su código, ya que el próximo chico / chica tendrá que averiguar qué está pasando aquí.