Ir al contenido principal

Las 20 preguntas y respuestas más frecuentes en entrevistas sobre PL/SQL en 2026

Prepárate para las entrevistas sobre PL/SQL con temas clave como funciones, desencadenadores, SQL dinámico, gestión de errores, mejores prácticas y preguntas basadas en situaciones reales.
Actualizado 22 dic 2025  · 10 min leer

PL/SQL, que es la extensión del lenguaje procedimental SQL de Oracle, es algo que debes conocer si vas a trabajar con bases de datos Oracle. Esto es válido para puestos importantes como administrador de bases de datos, programadores y analistas de datos, que necesitan manejar una lógica empresarial compleja dentro de la base de datos.

Creo que los entrevistadores evalúan a los candidatos en tres aspectos clave:

  • Comprensión conceptual: Principios básicos, tipos de datos, estructuras de control y gestión de excepciones.
  • Habilidad práctica para programar: Escribir procedimientos almacenados, funciones, desencadenadores y paquetes eficientes.
  • Consideraciones sobre el rendimiento: Optimización del código PL/SQL para mejorar el tiempo de ejecución, minimizar el consumo de recursos y evitar errores como el cambio excesivo de contexto entre SQL y PL/SQL.

Para ayudar, te proporciono una guía sobre preguntas de entrevista sobre PL/SQL. Comenzaré con los conceptos fundamentales y avanzaré hacia temas más avanzados, como el procesamiento masivo, el SQL dinámico y el ajuste del rendimiento.

Si deseas comprender los conceptos fundamentales de la base de datos Oracle, te recomiendo que realices nuestro curso Introducción a Oracle SQL, que es un recurso muy importante para aprender a interactuar con la base de datos Oracle y cómo la base de datos utiliza PL/SQL para procesar consultas.

Preguntas de entrevista para principiantes en PL/SQL

En la fase inicial de la entrevista, el entrevistador puede hacerte preguntas básicas para evaluar tus conocimientos sobre conceptos básicos de bases de datos y PL/SQL. Intenta estudiar estas preguntas y respuestas para prepararte para la fase inicial de la entrevista.

1. ¿Qué es PL/SQL?

PL/SQL es la extensión procedimental de Oracle para SQL. A diferencia de SQL, que es declarativo y se centra en la recuperación y manipulación de datos, PL/SQL permite a los programadores implementar lógica procedimental, lo que lo convierte en una potente herramienta para escribir reglas de negocio complejas dentro de la base de datos. Admite variables, bucles, condicionales, gestión de excepciones y programación modular a través de procedimientos, funciones y paquetes.

2. ¿Cuál es la estructura básica de un bloque PL/SQL?

Un bloque PL/SQL es la unidad fundamental de ejecución en PL/SQL y consta de cuatro secciones principales:

  • DECLARE (Opcional): Se utiliza para definir variables, constantes, cursores y tipos definidos por el usuario.

  • BEGIN: La sección ejecutable donde se escriben las consultas SQL y las sentencias procedimentales.

  • EXCEPTION (Opcional): Gestiona los errores de tiempo de ejecución y las excepciones para garantizar una recuperación elegante de los errores.

  • END;: Marca el final del bloque.

3. ¿Cuáles son los tipos de datos PL/SQL esenciales?

PL/SQL admite varios tipos de datos, clasificados de la siguiente manera:

  • Tipos escalares: Tipos de valor único como NUMBER, VARCHAR2, DATE, BOOLEAN.

  • Tipos compuestos: Colecciones como RECORD (estructuras personalizadas) y TABLE/VARRAY (arreglos).

  • Tipos de referencia: Punteros a objetos de base de datos, como REF CURSOR para el procesamiento dinámico de consultas.

4. ¿Cuáles son las estructuras de control básicas en PL/SQL?

PL/SQL incluye varias estructuras de control que ayudan a gestionar el flujo de un programa:

  • Bucles: Entre ellos se incluyen LOOP, FOR LOOP y WHILE LOOP, que permiten la ejecución repetitiva de instrucciones.

  • Sentencias condicionales: Entre ellas se incluyen las instrucciones « IF » y « CASE », que ejecutan diferentes bloques de código en función de las condiciones. La función DECODE() es otro buen ejemplo de condicional que vale la pena estudiar. 

Preguntas de entrevista sobre PL/SQL de nivel intermedio

Una vez cubiertas las preguntas básicas, pasemos ahora a algunas preguntas de nivel intermedio sobre estructuras de datos para entrevistas. Después de evaluar tus conocimientos básicos, los entrevistadores van a evaluar ahora tu competencia técnica en la implementación y el uso de conceptos PL/SQL.

5. ¿Cuál es la diferencia entre los procedimientos almacenados y las funciones?

Los procedimientos almacenados y las funciones son bloques de código PL/SQL reutilizables, pero tienen fines bastante diferentes.

Los procedimientos almacenados se utilizan para realizar operaciones que no devuelven un valor, como insertar, actualizar o eliminar datos. Se utilizan para tareas que modifican datos o realizan operaciones complejas sin devolver un resultado.

Por ejemplo, el procedimiento siguiente actualiza el campo « salary » (Salario) del empleado con el valor « employee_id » (Salario) proporcionado, añadiendo el valor « p_increment » (Salario) especificado, de modo que el salario se actualiza dinámicamente en función de los parámetros introducidos.

CREATE PROCEDURE update_salary(p_emp_id NUMBER, p_increment NUMBER) AS  
BEGIN  
    -- Update the salary of the employee with the given ID  
    UPDATE employees  
    SET salary = salary + p_increment  
    WHERE employee_id = p_emp_id;  
END;

Las funciones, por otro lado, devuelven un valor después de realizar operaciones. Son adecuados para cálculos o recuperación de datos que necesitan devolver un resultado.

La siguiente función simplifica la obtención del salario de un empleado, lo que permite reutilizarla en consultas SQL u otros procedimientos.

CREATE FUNCTION get_employee_salary(p_emp_id NUMBER) RETURN NUMBER AS  
    v_salary NUMBER;  
BEGIN  
    -- Retrieve the salary for the given employee ID  
    SELECT salary INTO v_salary  
    FROM employees  
    WHERE employee_id = p_emp_id;  
    
    -- Return the retrieved salary  
    RETURN v_salary;  
END;

6. ¿Qué son los paquetes PL/SQL?

Los paquetes PL/SQL son colecciones de procedimientos, funciones y variables relacionados que encapsulan código para una mejor organización y reutilización. Constan de dos partes:

  • Especificaciones del paquete: Declara elementos públicos (procedimientos, funciones, variables).
  • Cuerpo del paquete: Contiene los detalles de implementación de los procedimientos y funciones declarados en la especificación.

Por ejemplo, la consulta siguiente crea un paquete employee_pkg que define un procedimiento para aumentar el salario de un empleado y una función para recuperar el número total de empleados, cuyas implementaciones se proporcionarán en el cuerpo del paquete.

-- Create a package named 'employee_pkg'
CREATE PACKAGE employee_pkg AS  

    -- Procedure to increase an employee's salary by a percentage  
    PROCEDURE raise_salary(p_emp_id NUMBER, p_percent NUMBER);  

    -- Function to return the total number of employees  
    FUNCTION get_total_employees RETURN NUMBER;  

END employee_pkg;

7. ¿Qué son los disparadores PL/SQL?

Los desencadenadores son bloques PL/SQL que se ejecutan automáticamente en respuesta a eventos específicos de la base de datos, como inserciones, actualizaciones o eliminaciones. Los desencadenantes se utilizan para hacer cumplir las reglas de negocio. También se utilizan habitualmente para realizar auditorías. Se clasifican en:

  • Desencadenadores a nivel de fila: Ejecuta una vez por cada fila afectada.
  • Desencadenadores a nivel de instrucción: Ejecuta una vez por cada instrucción SQL, independientemente del número de filas afectadas.

La siguiente consulta crea un desencadenador AFTER UPDATE trg_salary_audit en la tabla employees que registra los cambios salariales en salary_audit table, capturando el ID del empleado, el salario antiguo y el nuevo, y la marca de tiempo de la actualización.

-- Create or replace a trigger 'trg_salary_audit'
CREATE OR REPLACE TRIGGER trg_salary_audit  
AFTER UPDATE OF salary ON employees  -- Fires after salary updates in 'employees' table
FOR EACH ROW  -- Executes for each updated row
BEGIN  
    -- Inserts old and new salary details into 'salary_audit' table
    INSERT INTO salary_audit (employee_id, old_salary, new_salary, change_date)  
    VALUES (:OLD.employee_id, :OLD.salary, :NEW.salary, SYSDATE);  
END;

Estudia nuestro tutorial sobre desencadenadores SQL para que estés preparado en caso de que se te pregunte sobre ellos en la entrevista. 

8. ¿Cuáles son los métodos de gestión de excepciones en PL/SQL?

PL/SQL proporciona mecanismos de gestión de errores para garantizar la estabilidad y evitar fallos. Los tipos de excepciones incluyen los siguientes:

  • Excepciones predefinidas: Excepciones integradas como NO_DATA_FOUND, TOO_MANY_ROWS y ZERO_DIVIDE.

  • Excepciones definidas por el usuario: Las excepciones personalizadas se declaran utilizando EXCEPTION y se generan utilizando RAISE.

Por ejemplo, el siguiente bloque PL/SQL recupera el salario de un empleado con el ID 100, genera una excepción personalizada si el salario es inferior a 1000 y gestiona los posibles errores, incluidos los registros de empleados que faltan y las excepciones inesperadas.

DECLARE  
    v_salary NUMBER;  -- Variable to store the employee's salary  
    e_low_salary EXCEPTION;  -- Custom exception for low salary  

BEGIN  
    -- Retrieve salary of employee with ID 100  
    SELECT salary INTO v_salary FROM employees WHERE employee_id = 100;  

    -- Raise exception if salary is below 1000  
    IF v_salary < 1000 THEN  
        RAISE e_low_salary;  
    END IF;  

EXCEPTION  
    WHEN NO_DATA_FOUND THEN  -- Handle case where employee ID is not found  
        DBMS_OUTPUT.PUT_LINE('Employee not found.');  
    WHEN e_low_salary THEN  -- Handle custom low salary exception  
        DBMS_OUTPUT.PUT_LINE('Salary is below the allowed threshold.');  
    WHEN OTHERS THEN  -- Handle any other unexpected errors  
        DBMS_OUTPUT.PUT_LINE('An unexpected error occurred: ' || SQLERRM);  

END;

Las mejores prácticas para el manejo de excepciones incluyen lo siguiente:

  • Anticipa siempre las posibles excepciones.
  • Utiliza mensajes de error significativos.
  • Registra las excepciones para su auditoría.
  • Mantén el código de gestión de excepciones conciso y centrado en la recuperación.

9. ¿Cómo puedes verificar si se ejecuta o no una instrucción UPDATE?

El atributo SQL %NOTFOUND se puede utilizar para determinar si la instrucción UPDATE ha modificado correctamente algún registro. Si la última instrucción SQL ejecutada no ha afectado a ninguna fila, esta variable devuelve TRUE.

Por ejemplo, la consulta siguiente actualiza el salario de los empleados del departamento 10 aumentándolo en un 10 % y, a continuación, comprueba si alguna fila se ha visto afectada por la instrucción « UPDATE » utilizando el atributo « %NOTFOUND ». Si no se ha actualizado ninguna fila, se muestra el mensaje «No se ha actualizado ninguna fila». Si se han actualizado filas, se muestra el número de filas afectadas utilizando el atributo « SQL%ROWCOUNT ».

DECLARE
    -- Declare a variable to store the number of rows updated
    rows_updated INTEGER;
BEGIN
    -- Perform an UPDATE statement on the 'employees' table
    UPDATE employees
    SET salary = salary * 1.1
    WHERE department_id = 10;

    -- Check if any rows were updated by using %NOTFOUND
    IF SQL%NOTFOUND THEN
        -- If no rows were updated, print a message
        DBMS_OUTPUT.PUT_LINE('No rows were updated.');
    ELSE
        -- If rows were updated, print how many rows were affected
        rows_updated := SQL%ROWCOUNT;  -- Store the number of rows updated
        DBMS_OUTPUT.PUT_LINE(rows_updated || ' rows were updated.');
    END IF;
END;
/

Preguntas avanzadas sobre PL/SQL para entrevistas de trabajo

Ahora veamos algunas preguntas avanzadas para entrevistas, por si acaso estás solicitando un puesto de mayor responsabilidad que requiere más experiencia.

10. ¿Cuáles son los métodos para optimizar el rendimiento en PL/SQL?

Minimizar los cambios de contexto entre SQL y PL/SQL es fundamental para optimizar el rendimiento. Cada cambio conlleva una sobrecarga, lo que puede ralentizar los tiempos de ejecución, especialmente en situaciones en las que se producen transiciones frecuentes entre ambos.

11. ¿Cómo utilizas las operaciones masivas para minimizar los cambios de contexto?

PL/SQL proporciona técnicas de procesamiento masivo para optimizar la interacción entre SQL y PL/SQL mediante la recuperación o modificación de varias filas a la vez.

Por ejemplo, el bloque PL/SQL siguiente recupera todos los empleados del departamento 10 utilizando BULK COLLECT en una colección y la recorre para imprimir el nombre de cada empleado, lo que mejora el rendimiento al minimizar los cambios de contexto entre SQL y PL/SQL.

DECLARE  
    -- Define a table-type collection based on the 'employees' table structure  
    TYPE emp_table IS TABLE OF employees%ROWTYPE;  
    v_emps emp_table;  -- Declare a variable of this type  

BEGIN  
    -- Bulk fetch employees from department 10 into the collection  
    SELECT * BULK COLLECT INTO v_emps FROM employees WHERE department_id = 10;  

    -- Loop through the collection and print employee names  
    FOR i IN 1..v_emps.COUNT LOOP  
        DBMS_OUTPUT.PUT_LINE('Employee: ' || v_emps(i).employee_name);  
    END LOOP;  

END;

Además, este bloque PL/SQL utiliza FORALL para la actualización masiva, aumentando el salario en un 10 % para los empleados con los ID 101, 102 y 103.

DECLARE  
    -- Define a table-type collection for employee IDs  
    TYPE t_emp_ids IS TABLE OF employees.employee_id%TYPE;  
    -- Initialize collection with specific employee IDs  
    v_emp_ids t_emp_ids := t_emp_ids(101, 102, 103);  

BEGIN  
    -- Bulk update salaries by 10% for specified employee IDs  
    FORALL i IN 1..v_emp_ids.COUNT  
        UPDATE employees SET salary = salary * 1.10 WHERE employee_id = v_emp_ids(i);  

END;

12. ¿Qué son el SQL dinámico y los cursores de referencia?

El SQL dinámico permite ejecutar sentencias SQL de forma dinámica en tiempo de ejecución, lo que resulta útil cuando se trabaja con nombres de tablas, columnas o estructuras de consulta variables.

El siguiente bloque PL/SQL utiliza SQL dinámico para contar el número de filas de la tabla employees e imprime el resultado. Me gusta este tipo de enfoque porque permite flexibilidad.

DECLARE  
    v_table_name VARCHAR2(50) := 'employees';  -- Store table name  
    v_count NUMBER;  -- Variable to hold row count  

BEGIN  
    -- Dynamically count rows in the specified table  
    EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || v_table_name INTO v_count;  

    -- Print the total count  
    DBMS_OUTPUT.PUT_LINE('Total Employees: ' || v_count);  

END;  

Los cursores Ref son cursores dinámicos que se pueden abrir, recuperar y cerrar en tiempo de ejecución, lo que permite pasar los resultados de las consultas entre unidades de programa.

El bloque PL/SQL siguiente utiliza una consulta de selección ( REF CURSOR ) para recuperar e imprimir los nombres de los empleados del departamento 20. El cursor se abre dinámicamente, se itera mediante un bucle y se cierra después del procesamiento.

DECLARE  
    -- Define a REF CURSOR type  
    TYPE emp_ref_cursor IS REF CURSOR;  
    v_cursor emp_ref_cursor;  -- Declare a cursor variable  
    v_name employees.employee_name%TYPE;  -- Variable to store employee name  

BEGIN  
    -- Open the cursor for employees in department 20  
    OPEN v_cursor FOR SELECT employee_name FROM employees WHERE department_id = 20;  

    -- Fetch and print employee names in a loop  
    LOOP  
        FETCH v_cursor INTO v_name;  
        EXIT WHEN v_cursor%NOTFOUND;  
        DBMS_OUTPUT.PUT_LINE('Employee: ' || v_name);  
    END LOOP;  

    -- Close the cursor  
    CLOSE v_cursor;  

END;

13. ¿Cómo gestionas los errores de mutación de tablas?

Los errores de mutación de tabla se producen cuando un disparador intenta modificar la tabla en la que se activa. Un disparador compuesto permite dividir la ejecución del disparador en varias fases, como BEFORE, AFTER y FOR EACH ROW, para evitar problemas de modificación directa.

El desencadenador compuesto siguiente registra los cambios salariales en la tabla salary_audit de manera eficiente, recopilando datos antes de cada actualización de fila y realizando una inserción masiva después de la instrucción, lo que reduce los cambios de contexto y mejora el rendimiento.

CREATE OR REPLACE TRIGGER trg_salary_audit  
FOR UPDATE OF salary ON employees  -- Trigger fires on salary updates  
COMPOUND TRIGGER  

    -- Declare an associative array to store audit records  
    TYPE t_salary_audit IS TABLE OF salary_audit%ROWTYPE INDEX BY PLS_INTEGER;  
    v_audit_data t_salary_audit;  
    v_idx PLS_INTEGER := 0;  

    -- Before updating each row, store old and new salary details  
    BEFORE EACH ROW IS  
    BEGIN  
        v_idx := v_idx + 1;  
        v_audit_data(v_idx).employee_id := :OLD.employee_id;  
        v_audit_data(v_idx).old_salary := :OLD.salary;  
        v_audit_data(v_idx).new_salary := :NEW.salary;  
        v_audit_data(v_idx).change_date := SYSDATE;  
    END BEFORE EACH ROW;  

    -- After the statement, insert all audit records in bulk  
    AFTER STATEMENT IS  
    BEGIN  
        FORALL i IN 1..v_idx  
            INSERT INTO salary_audit VALUES v_audit_data(i);  
    END AFTER STATEMENT;  

END trg_salary_audit;

14. ¿Qué es la sobrecarga en PL/SQL?

La sobrecarga permite definir múltiples procedimientos o funciones con el mismo nombre pero con parámetros diferentes dentro de un paquete. Esto mejora la legibilidad y el mantenimiento del código, ya que ofrece múltiples formas de realizar operaciones similares.

En la consulta siguiente, el cuerpo del paquete implementa dos procedimientos sobrecargados denominados update_salary: Uno aumenta el salario de un empleado en una cantidad específica, mientras que el otro establece un nuevo salario con una fecha de vigencia, actualizando la tabla employees en consecuencia.

-- Create the package specification
CREATE OR REPLACE PACKAGE emp_pkg AS  
    -- Procedure to increment salary by a specified amount  
    PROCEDURE update_salary(p_emp_id NUMBER, p_increment NUMBER);

    -- Overloaded procedure to set a new salary with an effective date  
    PROCEDURE update_salary(p_emp_id NUMBER, p_new_salary NUMBER, p_effective_date DATE);
END emp_pkg;
/
-- Create the package body
CREATE OR REPLACE PACKAGE BODY emp_pkg AS  

    -- Procedure to increment salary by a specified amount  
    PROCEDURE update_salary(p_emp_id NUMBER, p_increment NUMBER) AS  
    BEGIN  
        UPDATE employees  
        SET salary = salary + p_increment  
        WHERE employee_id = p_emp_id;  
    END update_salary;  

    -- Overloaded procedure to set a new salary with an effective date  
    PROCEDURE update_salary(p_emp_id NUMBER, p_new_salary NUMBER, p_effective_date DATE) AS  
    BEGIN  
        UPDATE employees  
        SET salary = p_new_salary, last_update = p_effective_date  
        WHERE employee_id = p_emp_id;  
    END update_salary;  

END emp_pkg;
/

15. ¿Qué son las directivas del compilador y los pragmas en PL/SQL?

PL/SQL proporciona directivas del compilador (PRAGMA) para optimizar el código y gestionar las excepciones. Los pragmas comunes incluyen:

  • PRAGMA EXCEPTION_INIT: Asocia una excepción definida por el usuario con un código de error de Oracle.

  • PRAGMA SERIALLY_REUSABLE: Optimiza el uso de la memoria del paquete para mejorar la escalabilidad.

El bloque PL/SQL siguiente gestiona la inserción de un empleado con un salario no válido mediante una excepción personalizada e_invalid_salary asignada al código de error -20001. Si se produce la excepción, se muestra un mensaje de error.

DECLARE  
    e_invalid_salary EXCEPTION;  -- Declare custom exception for invalid salary  
    PRAGMA EXCEPTION_INIT(e_invalid_salary, -20001);  -- Associate exception with error code -20001  
BEGIN  
    -- Attempt to insert an employee with invalid salary  
    INSERT INTO employees (employee_id, salary) VALUES (999, -1000);  
EXCEPTION  
    -- Handle the custom exception and print a message  
    WHEN e_invalid_salary THEN  
        DBMS_OUTPUT.PUT_LINE('Invalid salary detected!');  
END;  

16. ¿Cuáles son los diferentes métodos para rastrear y depurar código PL/SQL?

PL/SQL proporciona varios paquetes integrados para rastrear y depurar el rendimiento del código. Los métodos más comunes incluyen el uso de DBMS_TRACE para rastrear el flujo de ejecución, DBMS_APPLICATION_INFO para supervisar la actividad de la sesión y DBMS_SESSION para recopilar información de diagnóstico a nivel de sesión.

La consulta siguiente primero habilita el seguimiento SQL mediante DBMS_SESSION.set_sql_trace(TRUE) y, a continuación, establece la información de sesión específica del cliente con DBMS_APPLICATION_INFO.set_client_info() para su supervisión. Se ejecuta el bloque PL/SQL, que simula una operación de UPDATE. Por último, desactiva el seguimiento tras la ejecución utilizando DBMS_SESSION.set_sql_trace(FALSE).

-- Enable tracing for the current session using DBMS_SESSION
BEGIN
   -- Start session-level tracing
   DBMS_SESSION.set_sql_trace(TRUE);
END;
/

-- Set application information using DBMS_APPLICATION_INFO
BEGIN
   -- Set the application name and action for session monitoring
   DBMS_APPLICATION_INFO.set_client_info('Trace Debug Session');
   DBMS_APPLICATION_INFO.set_action('Debugging PL/SQL Code');
END;
/

-- Example PL/SQL block that simulates a process for debugging
DECLARE
   v_employee_id NUMBER := 100;
BEGIN
   -- Example query to fetch employee details
   FOR rec IN (SELECT first_name, last_name FROM employees WHERE employee_id = v_employee_id) LOOP
      DBMS_OUTPUT.put_line('Employee: ' || rec.first_name || ' ' || rec.last_name);
   END LOOP;
   
   -- Simulate some logic that could be traced
   IF v_employee_id = 100 THEN
      DBMS_OUTPUT.put_line('Employee ID is 100');
   END IF;
END;
/

-- Disable tracing after the session is complete
BEGIN
   -- Stop session-level tracing
   DBMS_SESSION.set_sql_trace(FALSE);
END;
/

Preguntas de entrevista sobre PL/SQL basadas en escenarios

En aplicaciones empresariales del mundo real, PL/SQL se utiliza para gestionar lógicas empresariales complejas. Los entrevistadores suelen evaluar la capacidad de los candidatos para aplicar PL/SQL en situaciones prácticas. A continuación se presentan algunos retos clave, junto con estrategias para resolverlos.

Para esta siguiente y última sección, si estás realizando una entrevista, te recomiendo que pienses en cómo responder a las preguntas siguiendo esta plantilla, pero, por supuesto, intenta reorientar tu respuesta para adaptarla a tu sector específico o para reflejar tu propia experiencia. Lo mismo ocurre si estás entrevistando a un candidato y quieres ideas sobre cómo formular una pregunta y evaluar la exhaustividad de la respuesta, en cuyo caso espero que esta sección te sirva de inspiración tanto para tus preguntas como para tus criterios de evaluación.

Aumenta la competencia SQL de tu equipo

Forma a tu equipo en SQL con DataCamp para empresas. Formación completa, proyectos prácticos y métricas de rendimiento detalladas para tu organización.

Solicita una demostración hoy mismo
business-homepage-hero.png

17. ¿Cómo diseñas los desencadenantes en entornos con mucha concurrencia?

Supongamos un escenario en el que necesitas aplicar una regla de negocio según la cual el salario de un empleado no se puede actualizar más de una vez al día. Sin embargo, la base de datos experimenta una alta concurrencia de transacciones, y un simple disparador podría provocar conflictos o problemas de rendimiento.

En lugar de utilizar un desencadenador a nivel de fila que se activa con cada actualización y puede ralentizar el rendimiento, utiliza un desencadenador a nivel de instrucción con una tabla de registro para evitar múltiples actualizaciones salariales en el mismo día.

Por ejemplo, el desencadenador siguiente evita que se actualicen varias veces el salario de un empleado en el mismo día, ya que comprueba la tabla salary_update_log antes de permitir la actualización. Si el salario ya se ha actualizado hoy, se genera un error; de lo contrario, se registra la fecha de actualización.

-- Create a table to log the last salary update for each employee
CREATE TABLE salary_update_log (
    employee_id NUMBER PRIMARY KEY,  -- Employee ID as primary key
    last_update DATE  -- Date of the last salary update
);

-- Create or replace a compound trigger to prevent multiple salary updates on the same day
CREATE OR REPLACE TRIGGER trg_prevent_multiple_salary_update  
FOR UPDATE OF salary ON employees  
COMPOUND TRIGGER  

    -- Declare a variable to store last salary update date per row
    TYPE emp_log_type IS TABLE OF DATE INDEX BY PLS_INTEGER;
    emp_log emp_log_type;

    BEFORE STATEMENT IS  
    BEGIN  
        -- Load existing salary update logs into memory for reference
        FOR rec IN (SELECT employee_id, last_update FROM salary_update_log) LOOP  
            emp_log(rec.employee_id) := rec.last_update;  
        END LOOP;  
    END BEFORE STATEMENT;  

    BEFORE EACH ROW IS  
    BEGIN  
        -- Check if an entry exists for this employee
        IF emp_log.EXISTS(:NEW.employee_id) THEN  
            -- Validate if salary was updated today
            IF emp_log(:NEW.employee_id) = TRUNC(SYSDATE) THEN  
                RAISE_APPLICATION_ERROR(-20010, 'Salary can only be updated once per day');  
            ELSE  
                -- Update log in memory
                emp_log(:NEW.employee_id) := TRUNC(SYSDATE);  
            END IF;  
        ELSE  
            -- Insert a new log entry into memory
            emp_log(:NEW.employee_id) := TRUNC(SYSDATE);  
        END IF;  
    END BEFORE EACH ROW;  

    AFTER STATEMENT IS  
    BEGIN  
        -- Apply changes to the log table after all row updates
        FOR i IN emp_log.FIRST .. emp_log.LAST LOOP  
            MERGE INTO salary_update_log l  
            USING (SELECT i AS employee_id, emp_log(i) AS last_update FROM DUAL) s  
            ON (l.employee_id = s.employee_id)  
            WHEN MATCHED THEN  
                UPDATE SET l.last_update = s.last_update  
            WHEN NOT MATCHED THEN  
                INSERT (employee_id, last_update) VALUES (s.employee_id, s.last_update);  
        END LOOP;  
    END AFTER STATEMENT;  

END trg_prevent_multiple_salary_update;

El ejemplo anterior reduciría el bloqueo a nivel de fila y minimizaría los conflictos de transacciones durante las actualizaciones masivas.

18. ¿Cómo divides las transacciones grandes en partes más pequeñas para garantizar la fiabilidad?

Imagina un escenario en el que un sistema bancario necesita realizar una actualización masiva para ajustar los tipos de interés de millones de cuentas de clientes. La ejecución de una única transacción de gran tamaño podría bloquear las tablas durante demasiado tiempo o provocar errores de reversión.

En este caso, utiliza el procesamiento masivo con COMMIT en lotes para procesar los datos de forma incremental y evitar conflictos.

El bloque PL/SQL siguiente implementa la solución utilizando un BULK COLLECT para obtener los ID de cuenta y, a continuación, los itera para actualizar el tipo de interés en un 5 %. Confirma los cambios cada 1000 actualizaciones para mejorar el rendimiento y reducir el uso de recursos. Una confirmación final garantiza que se guarden las actualizaciones restantes.

DECLARE  
    -- Define a collection type for account IDs  
    TYPE t_accounts IS TABLE OF NUMBER;  -- Use NUMBER instead of referencing accounts.account_id
    v_account_ids t_accounts;  -- Variable to store account IDs  
    v_batch_size CONSTANT NUMBER := 1000;  -- Batch size for commits  

BEGIN  
    -- Bulk collect all account IDs into the collection  
    SELECT account_id BULK COLLECT INTO v_account_ids FROM accounts;  

    -- Loop through each account ID to update the interest rate  
    FOR i IN 1 .. v_account_ids.COUNT LOOP  
        UPDATE accounts  
        SET interest_rate = interest_rate * 1.05  -- Increase interest rate by 5%  
        WHERE account_id = v_account_ids(i);  

        -- Commit after every 1000 updates  
        IF MOD(i, v_batch_size) = 0 THEN  
            COMMIT;  
        END IF;  
    END LOOP;  

    COMMIT; -- Final commit for any remaining updates  
END;
/

Esta solución garantizaría la fiabilidad de los sistemas financieros, como el de nóminas, al evitar fallos en las transacciones.

19. ¿Cómo organizas la lógica compleja en paquetes para facilitar el mantenimiento?

Una empresa minorista necesita implementar un sistema de procesamiento de pedidos que implique varios pasos: Comprobar la disponibilidad de inventario, reservar existencias, calcular descuentos y registrar el historial de transacciones.

En lugar de escribir procedimientos independientes separados, debes organizar esta lógica de una manera estructurada y fácil de mantener. Por lo tanto, utiliza paquetes PL/SQL para encapsular procedimientos y funciones relacionados, mejorando la reutilización y el mantenimiento del código.

La especificación del paquete que se muestra a continuación define las funciones y los procedimientos para el procesamiento de pedidos, incluyendo la comprobación del inventario, la reserva de existencias, el cálculo de descuentos y el registro del estado de las transacciones. Ofrece un enfoque modular para gestionar las tareas relacionadas con los pedidos.

-- Create a package specification for order processing functions and procedures
CREATE PACKAGE order_processing_pkg AS  

    -- Function to check if enough inventory is available for the product
    FUNCTION check_inventory(p_product_id NUMBER, p_quantity NUMBER) RETURN BOOLEAN;  

    -- Procedure to reserve stock for a specific order
    PROCEDURE reserve_stock(p_order_id NUMBER, p_product_id NUMBER, p_quantity NUMBER);  

    -- Function to calculate discount based on customer and total amount
    FUNCTION calculate_discount(p_customer_id NUMBER, p_total_amount NUMBER) RETURN NUMBER;  

    -- Procedure to log the status of a transaction
    PROCEDURE log_transaction(p_order_id NUMBER, p_status VARCHAR2);  

END order_processing_pkg;

A continuación, utilizamos el siguiente cuerpo del paquete para implementar las funciones y procedimientos definidos en la especificación del paquete. Se encarga de tareas clave como comprobar la disponibilidad de inventario, reservar existencias, calcular descuentos y registrar el estado de las transacciones, lo que garantiza un procesamiento fluido de los pedidos.

-- Create the package body implementing the functions and procedures for order processing
CREATE PACKAGE BODY order_processing_pkg AS  

    -- Function to check if sufficient inventory is available for the product
    FUNCTION check_inventory(p_product_id NUMBER, p_quantity NUMBER) RETURN BOOLEAN AS  
        v_available_qty NUMBER;  -- Variable to store available quantity  
    BEGIN  
        -- Retrieve the available quantity from inventory
        SELECT stock_quantity INTO v_available_qty FROM inventory WHERE product_id = p_product_id;  
        -- Return true if enough stock is available, otherwise false
        RETURN v_available_qty >= p_quantity;  
    END check_inventory;  

    -- Procedure to reserve stock for a specific order
    PROCEDURE reserve_stock(p_order_id NUMBER, p_product_id NUMBER, p_quantity NUMBER) AS  
    BEGIN  
        -- Deduct the ordered quantity from the inventory
        UPDATE inventory SET stock_quantity = stock_quantity - p_quantity WHERE product_id = p_product_id;  
    END reserve_stock;  

    -- Function to calculate a discount based on the total order amount
    FUNCTION calculate_discount(p_customer_id NUMBER, p_total_amount NUMBER) RETURN NUMBER AS  
        v_discount NUMBER := 0;  -- Initialize discount to 0  
    BEGIN  
        -- Apply 10% discount if the total amount is greater than 500
        IF p_total_amount > 500 THEN  
            v_discount := p_total_amount * 0.10;  
        END IF;  
        -- Return the calculated discount
        RETURN v_discount;  
    END calculate_discount;  

    -- Procedure to log the transaction status
    PROCEDURE log_transaction(p_order_id NUMBER, p_status VARCHAR2) AS  
    BEGIN  
        -- Insert a log entry for the order status
        INSERT INTO order_log (order_id, status, log_date) VALUES (p_order_id, p_status, SYSDATE);  
    END log_transaction;  

END order_processing_pkg;

20. ¿Cómo gestionas los bloqueos en sistemas con un elevado número de transacciones?

Supongamos un escenario en el que un sistema financiero actualiza con frecuencia varias tablas relacionadas simultáneamente. Los bloqueos se producen cuando dos transacciones esperan los recursos bloqueados de la otra, lo que provoca cuellos de botella en el rendimiento.

Para resolver este problema, bloquea siempre las filas en un orden coherente en todas las transacciones. Además, utiliza la cláusula « NOWAIT » o « SKIP LOCKED » para evitar esperas indefinidas.

Por ejemplo, el bloque PL/SQL siguiente intenta bloquear una fila específica de la tabla de cuentas para la actualización mediante la cláusula « FOR UPDATE NOWAIT », lo que provoca que la transacción falle inmediatamente si otra sesión ya ha bloqueado la fila. Después de bloquear, actualiza el estado de la transacción y confirma los cambios. Si se produce un error, captura la excepción y muestra un mensaje de error.

DECLARE  
    v_balance NUMBER(15,2);  -- Declare variable to store the account balance  
BEGIN  
    -- Lock the account row for update to prevent other sessions from modifying it  
    SELECT balance INTO v_balance FROM accounts  
    WHERE account_id = 101 FOR UPDATE NOWAIT;  

    -- Update the transaction status to 'Processed' for all transactions related to this account  
    UPDATE transactions  
    SET status = 'Processed'  
    WHERE account_id = 101 AND status = 'Pending';  -- Update only pending transactions  

    COMMIT;  -- Commit the changes  

EXCEPTION  
    -- Handle errors, such as locking issues or unexpected exceptions  
    WHEN OTHERS THEN  
        DBMS_OUTPUT.PUT_LINE('Transaction failed: ' || SQLERRM);  
        ROLLBACK;  -- Ensure rollback in case of failure  
END;
/

Del mismo modo, este bloque PL/SQL procesa las transacciones pendientes bloqueándolas para su actualización con un FOR UPDATE SKIP LOCKED, lo que te permite omitir las filas que ya están bloqueadas por otras sesiones. Actualiza el estado de cada transacción a «En proceso» y confirma los cambios al final.

DECLARE  
    -- Declare a cursor to select pending transactions and lock rows for update
    CURSOR c_pending_txns IS  
        SELECT transaction_id FROM transactions WHERE status = 'Pending' FOR UPDATE SKIP LOCKED;  -- Skip locked rows  

BEGIN  
    -- Loop through the pending transactions
    FOR txn IN c_pending_txns LOOP  
        -- Update the status of each transaction to 'Processing'
        UPDATE transactions SET status = 'Processing' WHERE transaction_id = txn.transaction_id;  
    END LOOP;  
    COMMIT;  -- Commit the changes to finalize the transaction updates  
END;

Conclusión y recursos adicionales

Para los puestos centrados en Oracle, los empleadores buscan candidatos que puedan escribir código PL/SQL correcto, manejar retos de la vida real y optimizar el rendimiento de las bases de datos. Recomiendo consultar la documentación oficial de Oracle sobre Referencia del lenguaje PL/SQL para obtener una guía detallada y las mejores prácticas sobre PL/SQL. Oracle Live SQL (Interactive PL/SQL Playground) proporciona acceso a la plataforma basada en la nube de Oracle para ejecutar consultas PL/SQL en línea. También te animo a que te unas a la comunidad Oracle para interactuar con expertos y programadores de Oracle, y al foro Stack Overflow para encontrar soluciones a preguntas relacionadas con PL/SQL.

Sin embargo, nada supera a un plan de aprendizaje estructurado. Por esta razón, recomiendo encarecidamente realizar nuestro curso Introducción a Oracle SQL, que, en mi opinión, es realmente la mejor manera de convertirse en un experto. Además, si deseas ampliar tus conocimientos sobre el trabajo con bases de datos, también te recomiendo que realices nuestro curso de Diseño de bases de datos, en el que aprenderás a crear y gestionar bases de datos y a seleccionar el DBMS más adecuado a tus necesidades. Por último, prueba nuestro programa de ingeniero de datos asociado en SQL para aprender los fundamentos de la ingeniería de datos y el almacenamiento de datos. 

Por último, pero no menos importante, si estás entrevistando a candidatos y también quieres mejorar las habilidades de otros, ponte en contacto con nuestro equipo de DataCamp for Business. DataCamp puede mejorar las habilidades de equipos enteros con proyectos prácticos y itinerarios de aprendizaje personalizados. Esta es una excelente manera para que los empleadores cubran las carencias de habilidades y aumenten la confianza y la credibilidad de tu equipo, así que ponte en contacto con nuestro equipo hoy mismo.


Allan Ouko's photo
Author
Allan Ouko
LinkedIn
Creo artículos que simplifican la ciencia de los datos y la analítica, haciéndolos fáciles de entender y accesibles.

Preguntas frecuentes sobre PL SQL

¿Qué es PL/SQL y en qué se diferencia de SQL?

PL/SQL es un lenguaje procedimental desarrollado por Oracle que permite estructuras de control y gestión de errores, mientras que SQL es declarativo y se encarga de la recuperación y manipulación de datos.

¿Qué es un paquete PL/SQL?

Conjunto de procedimientos, funciones, variables y cursores relacionados para la programación modular y la reutilización.

¿En qué se diferencia un procedimiento de una función?

Los procedimientos realizan una acción que no devuelve un valor, mientras que las funciones devuelven un valor que se puede utilizar en consultas.

¿Qué son los desencadenadores en PL/SQL?

Acciones automatizadas ejecutadas antes o después de las operaciones INSERT, UPDATE, DELETE.

¿Qué es el procesamiento masivo en PL/SQL?

El procesamiento masivo (BULK COLLECT, FORALL) mejora el rendimiento al reducir los cambios de contexto entre los motores PL/SQL y SQL al manejar grandes conjuntos de datos.

Temas

Aprende SQL con DataCamp

Curso

Manipulación de datos en SQL

4 h
305.4K
Domina las consultas SQL para responder a preguntas de ciencia de datos y prepara conjuntos de datos para analizarlos en PostgreSQL.
Ver detallesRight Arrow
Iniciar curso
Ver másRight Arrow
Relacionado

blog

Las 36 preguntas y respuestas más importantes sobre Python para entrevistas de trabajo en 2026

Preguntas esenciales sobre Python para entrevistas de trabajo con ejemplos para personas en busca de empleo, estudiantes de último año y profesionales de datos.
Abid Ali Awan's photo

Abid Ali Awan

15 min

blog

20 preguntas principales de la entrevista sobre SQL Joins

Prepara tu entrevista SQL con esta lista de las preguntas más comunes sobre SQL Joins
Javier Canales Luna's photo

Javier Canales Luna

15 min

Machine Learning Interview Questions

blog

Las 30 preguntas más frecuentes en entrevistas sobre machine learning para 2026

Prepárate para tu entrevista con esta guía completa sobre preguntas relacionadas con machine learning, que abarca desde conceptos básicos y algoritmos hasta temas avanzados y específicos de cada puesto.
Abid Ali Awan's photo

Abid Ali Awan

15 min

blog

Las 20 preguntas más frecuentes en una entrevista sobre NumPy: De Básico a Avanzado

Prepárate para tu próxima entrevista de ciencia de datos con preguntas esenciales sobre NumPy, desde las más básicas hasta las más avanzadas. ¡Perfecto para afinar tus habilidades y aumentar la confianza!
Tim Lu's photo

Tim Lu

9 min

Ver másVer más