Supongamos que tengo una tabla y un conjunto de datos como sigue:
# 1. Éxito accidental con datos de prueba incorrectos
CREATE TABLE undead_type
(
   undead_id     INTEGER PRIMARY KEY,
   undead_name   VARCHAR2 (100)
)
/
BEGIN
   INSERT INTO undead_type (undead_id, undead_name)
        VALUES (1, 'Skeleton');
   INSERT INTO undead_type (undead_id, undead_name)
        VALUES (2, 'Zombie');
   INSERT INTO undead_type (undead_id, undead_name)
        VALUES (3, 'Ghoul');
   INSERT INTO undead_type (undead_id, undead_name)
        VALUES (4, 'Wight');
   INSERT INTO undead_type (undead_id, undead_name)
        VALUES (5, 'Wraith');
   INSERT INTO undead_type (undead_id, undead_name)
        VALUES (6, 'Mohrg');
  INSERT INTO undead_type (undead_id, undead_name)
        VALUES (7, 'Ghast');
   INSERT INTO undead_type (undead_id, undead_name)
        VALUES (8, 'Mummy');
   INSERT INTO undead_type (undead_id, undead_name)
        VALUES (9, 'Lich');
   INSERT INTO undead_type (undead_id, undead_name)
        VALUES (10, 'Demilich');
   INSERT INTO undead_type (undead_id, undead_name)
        VALUES (11, 'Vampire Spawn');
   INSERT INTO undead_type (undead_id, undead_name)
        VALUES (12, 'Vampire');
   INSERT INTO undead_type (undead_id, undead_name)
        VALUES (13, 'Allip');
   COMMIT;
END;
/
Y tengo que escribir un programa que produce la siguiente salida: Undead en Orden Alfabético:
- Allip
 - Demilich
 - Ghast
 - ...
 
DECLARE
   l_count   INTEGER;
   l_name    plch_animals.animal_name%TYPE;
BEGIN
   DBMS_OUTPUT.put_line ('Animals in Alphabetical Order');
   SELECT COUNT (*) INTO l_count FROM plch_animals;
   FOR indx IN 1 .. l_count
   LOOP
      SELECT animal_name
        INTO l_name
        FROM plch_animals
       WHERE animal_id = indx;
      DBMS_OUTPUT.put_line (l_name);
   END LOOP;
END;
/
# 2. Demasiado SQL, datos insuficientes
DECLARE
   TYPE undead_ids_t IS TABLE OF undead_type.undead_id%TYPE;
   l_undead_ids   undead_ids_t;
   l_name         undead_type.undead_name%TYPE;
BEGIN
   DBMS_OUTPUT.put_line ('undead in Alphabetical Order');
   SELECT undead_id
     BULK COLLECT INTO l_undead_ids
     FROM undead_type;
   FOR indx IN 1 .. l_undead_ids.COUNT
   LOOP
      SELECT undead_name
        INTO l_name
        FROM undead_type
       WHERE undead_id = indx;
      DBMS_OUTPUT.put_line (l_name);
   END LOOP;
END;
/
# 3. Vamos a pasarlo bien con las conexiones PL/SQL con colecciones
DECLARE
   TYPE undead_ids_t IS TABLE OF undead_type.undead_id%TYPE
      INDEX BY undead_type.undead_name%TYPE;
   l_undead_ids   undead_ids_t;
   l_index        undead_type.undead_name%TYPE;
   l_name         undead_type.undead_name%TYPE;
BEGIN
   DBMS_OUTPUT.put_line ('undeads in Alphabetical Order');
   FOR rec IN (  SELECT *
                   FROM undead_type
               ORDER BY undead_name DESC)
   LOOP
      l_undead_ids (rec.undead_name) := rec.undead_id;
   END LOOP;
   l_index := l_undead_ids.FIRST;
   WHILE l_index IS NOT NULL
   LOOP
      DBMS_OUTPUT.put_line (l_index);
      l_index := l_undead_ids.NEXT (l_index);
   END LOOP;
END;
/
#4. SQL Simple
SELECT undead_name FROM undead_type ORDER BY undead_name;No es mucho más simple que eso. Y si lo necesita dentro de PL / SQL
#5. PL/SQL Simple
 BEGIN
   DBMS_OUTPUT.put_line ('undead in Alphabetical Order');
   FOR rec IN (SELECT undead_name FROM undead_type
                ORDER BY undead_name)
   LOOP
      DBMS_OUTPUT.put_line (rec.undead_name);
   END LOOP;
END;
Lecciones aprendidas
- Deje a SQL hacer el levantamiento de pesas, tanto como sea posible (no es que haya algo muy "pesado" para levantar en este ejercicio!)
 - No sobre-complicar las cosas. Asegúrese de que sus datos de prueba tengan suficiente volumen y variedad para ejercer realmente su algoritmo.
 - Si te encuentras pensando "¿tiene que ser tan complicado?", Casi con toda seguridad la respuesta es un resonante "No!" Y debe dar un paso atrás, desafiar sus suposiciones, y ver cómo se puede simplificar su código
 

No hay comentarios:
Publicar un comentario
Por favor deja tu comentario, es valioso.