

 Amazon Redshift dejará de admitir la creación de nuevas UDF de Python a partir del parche 198. Las UDF de Python existentes seguirán funcionando hasta el 30 de junio de 2026. Para obtener más información, consulte la [publicación del blog](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

# Errores de captura
<a name="stored-procedure-trapping-errors"></a>

En este tema se describe cómo gestiona Amazon Redshift los errores.

Cuando una consulta o un comando de un procedimiento almacenado provoca un error, las consultas posteriores no se ejecutan y la transacción se revierte. Puede administrar errores mediante un bloque EXCEPTION.

**nota**  
El comportamiento predeterminado es que un error provocará que las consultas posteriores no se ejecuten, aunque no haya condiciones adicionales que generen errores en el procedimiento almacenado.

```
[ <<label>> ]
[ DECLARE
  declarations ]
BEGIN
  statements
EXCEPTION
  WHEN OTHERS THEN
    statements
END;
```

Cuando se produce una excepción y agrega un bloque de manejo de excepciones, puede escribir instrucciones RAISE y la mayoría de las demás instrucciones PL/PgSQL. Por ejemplo, puede generar una excepción con un mensaje personalizado o insertar un registro en una tabla de registro.

Al ingresar el bloque de manejo de excepciones, la transacción actual se revierte y se crea una nueva transacción para ejecutar las instrucciones en el bloque. Si las instrucciones en el bloque se ejecutan sin errores, la transacción se confirma y se vuelve a lanzar la excepción. Por último, se cierra el procedimiento almacenado.

La única condición admitida en un bloque de excepciones es OTHERS, que se asocia a cada tipo de error excepto la cancelación de la consulta. Además, si se produce un error en un bloque de manejo de excepciones, este puede ser capturado por un bloque de manejo de excepciones externo.

Cuando se produce un error en el procedimiento NONATOMIC, el error no se vuelve a generar si se gestiona mediante un bloque de excepciones. Consulte la instrucción `RAISE` de PL/pgSQL para generar una excepción detectada por el bloque de gestión de excepciones. Esta instrucción solo es válida en bloques de gestión de excepciones. Para obtener más información consulte () [RAISE](c_PLpgSQL-statements.md#r_PLpgSQL-messages-errors).

**Controlar lo que ocurre después de un error en un procedimiento almacenado con el controlador CONTINUE**

 El controlador `CONTINUE` es un tipo de controlador de excepciones que supervisa el flujo de ejecución dentro de un procedimiento almacenado NONATOMIC. Al usarlo, puede atrapar y administrar excepciones sin finalizar el bloque de instrucciones existente. Normalmente, cuando se produce un error en un procedimiento almacenado, el flujo se interrumpe y el error se devuelve a quien llama. Sin embargo, en algunos casos prácticos, la condición de error no es lo suficientemente grave como para justificar la interrupción del flujo. Se recomienda gestionar el error de forma adecuada, utilizando la lógica de gestión de errores que elija en una transacción independiente y, a continuación, seguir ejecutando instrucciones que sigan al error. A continuación se muestra la sintaxis. 

```
[ DECLARE
  declarations ]
BEGIN
  statements
EXCEPTION
  [ CONTINUE_HANDLER | EXIT_HANDLER ] WHEN OTHERS THEN
    handler_statements
END;
```

Existen varias tablas del sistema que le ayudarán a recopilar información sobre los distintos tipos de errores. Para obtener más información, consulte [STL\_LOAD\_ERRORS](r_STL_LOAD_ERRORS.md), [STL\_ERROR](r_STL_ERROR.md) y [SYS\_STREAM\_SCAN\_ERRORS](r_SYS_STREAM_SCAN_ERRORS.md). También hay tablas adicionales del sistema que puede utilizar para solucionar errores. Encontrará más información al respecto en [Referencia de las tablas y vistas de sistema](cm_chap_system-tables.md).

## Ejemplo
<a name="stored-procedure-trapping-errors-examples"></a>

En el siguiente ejemplo se muestra cómo escribir instrucciones en el bloque de manejo de excepciones. El procedimiento almacenado utiliza el comportamiento de administración de transacciones predeterminado.

```
CREATE TABLE employee (firstname varchar, lastname varchar);
INSERT INTO employee VALUES ('Tomas','Smith');
CREATE TABLE employee_error_log (message varchar);

CREATE OR REPLACE PROCEDURE update_employee_sp() AS
$$
BEGIN
    UPDATE employee SET firstname = 'Adam' WHERE lastname = 'Smith';
    EXECUTE 'select invalid';
EXCEPTION WHEN OTHERS THEN
    RAISE INFO 'An exception occurred.';
    INSERT INTO employee_error_log VALUES ('Error message: ' || SQLERRM);
END;
$$ 
LANGUAGE plpgsql;

CALL update_employee_sp();

INFO:  An exception occurred.
ERROR:  column "invalid" does not exist
CONTEXT:  SQL statement "select invalid"
PL/pgSQL function "update_employee_sp" line 3 at execute statement
```

En este ejemplo, si llamamos a `update_employee_sp`, el mensaje informativo *Se ha producido una excepción.* se genera y el mensaje de error se inserta en la tabla de registro del registro `employee_error_log`. La excepción original se vuelve a lanzar antes de que finalice el procedimiento almacenado. En las consultas siguientes, se muestran los registros resultantes de la ejecución del ejemplo.

```
SELECT * from employee;

firstname | lastname 
-----------+----------
 Tomas     | Smith

SELECT * from employee_error_log;

          message                     
------------------------------------------------
 Error message: column "invalid" does not exist
```

Para obtener más información acerca de RAISE, incluida la ayuda sobre el formato, junto con una lista de niveles adicionales, consulte [Instrucciones de PL/pgSQL admitidas](c_PLpgSQL-statements.md).

En el siguiente ejemplo se muestra cómo escribir instrucciones en el bloque de manejo de excepciones. El procedimiento almacenado utiliza el comportamiento de administración de transacciones NONATOMIC. En este ejemplo, no se devuelve ningún error al autor de la llamada una vez finalizada la llamada al procedimiento. La instrucción UPDATE no se revierte debido al error en la instrucción siguiente. Se genera un mensaje informativo y se inserta el mensaje de error en la tabla de registro.

```
CREATE TABLE employee (firstname varchar, lastname varchar); 
INSERT INTO employee VALUES ('Tomas','Smith'); 
CREATE TABLE employee_error_log (message varchar);

-- Create the SP in NONATOMIC mode
CREATE OR REPLACE PROCEDURE update_employee_sp_2() NONATOMIC AS
$$
BEGIN
    UPDATE employee SET firstname = 'Adam' WHERE lastname = 'Smith';
    EXECUTE 'select invalid';
EXCEPTION WHEN OTHERS THEN
    RAISE INFO 'An exception occurred.';
    INSERT INTO employee_error_log VALUES ('Error message: ' || SQLERRM);
END;
$$ 
LANGUAGE plpgsql;

CALL update_employee_sp_2();
INFO:  An exception occurred.
CALL

SELECT * from employee;

 firstname | lastname 
-----------+----------
 Adam      | Smith
(1 row)

SELECT * from employee_error_log;

                    message                     
------------------------------------------------
 Error message: column "invalid" does not exist
(1 row)
```

En este ejemplo, se muestra cómo crear un procedimiento con dos bloques secundarios. Cuando se llama al procedimiento almacenado, el error del primer bloque secundario se gestiona mediante su bloque de gestión de excepciones. Una vez completado el primer bloque secundario, el procedimiento continúa con la ejecución del segundo bloque secundario. Puede ver en el resultado que no se produce ningún error cuando se completa la llamada al procedimiento. Se confirman las operaciones UPDATE e INSERT en la tabla employee. Los mensajes de error de ambos bloques de excepciones se insertan en la tabla de registro.

```
CREATE TABLE employee (firstname varchar, lastname varchar); 
INSERT INTO employee VALUES ('Tomas','Smith'); 
CREATE TABLE employee_error_log (message varchar);

CREATE OR REPLACE PROCEDURE update_employee_sp_3() NONATOMIC AS
$$
BEGIN
    BEGIN
        UPDATE employee SET firstname = 'Adam' WHERE lastname = 'Smith';
        EXECUTE 'select invalid1';
    EXCEPTION WHEN OTHERS THEN
        RAISE INFO 'An exception occurred in the first block.';
        INSERT INTO employee_error_log VALUES ('Error message: ' || SQLERRM);
    END;
    BEGIN
        INSERT INTO employee VALUES ('Edie','Robertson');
        EXECUTE 'select invalid2';
    EXCEPTION WHEN OTHERS THEN
        RAISE INFO 'An exception occurred in the second block.';
        INSERT INTO employee_error_log VALUES ('Error message: ' || SQLERRM);
    END;
END;
$$ 
LANGUAGE plpgsql;

CALL update_employee_sp_3();
INFO:  An exception occurred in the first block.
INFO:  An exception occurred in the second block.
CALL

SELECT * from employee;

 firstname | lastname  
-----------+-----------
 Adam      | Smith
 Edie      | Robertson
(2 rows)

SELECT * from employee_error_log;

                     message                     
-------------------------------------------------
 Error message: column "invalid1" does not exist
 Error message: column "invalid2" does not exist
(2 rows)
```

El siguiente ejemplo muestra cómo utilizar el controlador de excepciones CONTINUE. En este ejemplo se crean dos tablas y se utilizan en un procedimiento almacenado. El controlador CONTINUE controla el flujo de ejecución en un procedimiento almacenado con un comportamiento de administración de transacciones NONATOMIC.

```
CREATE TABLE tbl_1 (a int);
CREATE TABLE tbl_error_logging(info varchar, err_state varchar, err_msg varchar);

CREATE OR REPLACE PROCEDURE sp_exc_handling_1() NONATOMIC AS
$$
BEGIN
    INSERT INTO tbl_1 VALUES (1);
    -- Expect an error for the insert statement following, because of the invalid value
    INSERT INTO tbl_1 VALUES ("val");
    INSERT INTO tbl_1 VALUES (2);
EXCEPTION CONTINUE_HANDLER WHEN OTHERS THEN
    INSERT INTO tbl_error_logging VALUES ('Encountered error', SQLSTATE, SQLERRM);
END;
$$ LANGUAGE plpgsql;
```

LLame al procedimiento almacenado:

```
CALL sp_exc_handling_1();
```

El flujo actua de la siguiente manera:

1. Se produce un error porque se intenta insertar un tipo de datos incompatible en una columna. El control pasa al bloque EXCEPTION. Al entrar en el bloque de control de excepciones, la transacción actual se revierte y se crea una nueva transacción implícita para ejecutar las instrucciones en ella.

1. Si las instrucciones de CONTINUE\_HANDLER se ejecutan sin errores, el control pasa a la instrucción inmediatamente posterior a la instrucción que provoca la excepción. (Si una instrucción de CONTINUE\_HANDLER genera una nueva excepción, puede gestionarla con un controlador de excepciones dentro del bloque EXCEPTION).

Después de llamar al procedimiento almacenado de ejemplo, las tablas contienen los siguientes registros:
+ Si ejecuta `SELECT * FROM tbl_1;`, se devuelven dos registros que contienen los valores `1` y `2`.
+ Si ejecuta `SELECT * FROM tbl_error_logging;`, se devuelve un registro con los siguientes valores: *Encountered error*, *42703* y *column "val" does not exist in tbl\_1*.

El siguiente ejemplo de control de errores adicional utiliza un controlador EXIT y un controlador CONTINUE. Este crea dos tablas: una tabla de datos y una tabla de registro. También crea un procedimiento almacenado que demuestra el control de errores:

```
CREATE TABLE tbl_1 (a int);
CREATE TABLE tbl_error_logging(info varchar, err_state varchar, err_msg varchar);

CREATE OR REPLACE PROCEDURE sp_exc_handling_2() NONATOMIC AS
$$
BEGIN
    INSERT INTO tbl_1 VALUES (1);
    BEGIN
        INSERT INTO tbl_1 VALUES (100);
        -- Expect an error for the insert statement following, because of the invalid value
        INSERT INTO tbl_1 VALUES ("val");
        INSERT INTO tbl_1 VALUES (101);
    EXCEPTION EXIT_HANDLER WHEN OTHERS THEN
        INSERT INTO tbl_error_logging VALUES ('Encountered error', SQLSTATE, SQLERRM);
    END;
    INSERT INTO tbl_1 VALUES (2);
    -- Expect an error for the insert statement following, because of the invalid value
    INSERT INTO tbl_1 VALUES ("val");
    INSERT INTO tbl_1 VALUES (3);
EXCEPTION CONTINUE_HANDLER WHEN OTHERS THEN
    INSERT INTO tbl_error_logging VALUES ('Encountered error', SQLSTATE, SQLERRM);
END;
$$ LANGUAGE plpgsql;
```

Tras crear el procedimiento almacenado, llámelo de la siguiente manera:

```
CALL sp_exc_handling_2();
```

Cuando se produce un error en el bloque de excepciones interno, que está entre corchetes entre los conjuntos internos BEGIN y END, este lo controla el controlador EXIT. Cualquier error que se produzca en el bloque exterior lo gestiona el controlador CONTINUE. 

Después de llamar al procedimiento almacenado de ejemplo, las tablas contienen los siguientes registros:
+ Si ejecuta `SELECT * FROM tbl_1;`, se devuelven cuatro registros con los valores 1, 2, 3 y 100.
+ Si ejecuta `SELECT * FROM tbl_error_logging;`, se devuelven dos registros Estos tienen los siguientes valores: *Encountered error*, *42703* y *column "val" does not exist in tbl\_1*.

Si la tabla **tbl\_error\_logging** no existe, se genera una excepción.

El siguiente ejemplo muestra cómo utilizar el controlador de excepciones CONTINUE con el bucle FOR. En este ejemplo se crean tres tablas y se utilizan en un bucle FOR dentro de un procedimiento almacenado. El bucle FOR es una variante del conjunto de resultados, lo que significa que itera sobre los resultados de una consulta:

```
CREATE TABLE tbl_1 (a int);
INSERT INTO tbl_1 VALUES (1), (2), (3);
CREATE TABLE tbl_2 (a int);
CREATE TABLE tbl_error_logging(info varchar, err_state varchar, err_msg varchar);

CREATE OR REPLACE PROCEDURE sp_exc_handling_loop() NONATOMIC AS
$$
DECLARE
 rec RECORD;
BEGIN
    FOR rec IN SELECT a FROM tbl_1
    LOOP
        IF rec.a = 2 THEN
            -- Expect an error for the insert statement following, because of the invalid value
            INSERT INTO tbl_2 VALUES("val");
        ELSE
            INSERT INTO tbl_2 VALUES (rec.a);
        END IF;
    END LOOP;
EXCEPTION CONTINUE_HANDLER WHEN OTHERS THEN
    INSERT INTO tbl_error_logging VALUES ('Encountered error', SQLSTATE, SQLERRM);
END;
$$ LANGUAGE plpgsql;
```

LLame al procedimiento almacenado:

```
CALL sp_exc_handling_loop();
```

Después de llamar al procedimiento almacenado de ejemplo, las tablas contienen los siguientes registros:
+  Si ejecuta `SELECT * FROM tbl_2;`, se devuelven dos registros que contienen los valores 1 y 3.
+ Si ejecuta `SELECT * FROM tbl_error_logging;`, se devuelve un registro con los siguientes valores: *Encountered error*, *42703* y *column "val" does not exist in tbl\_2*.

Notas de uso sobre el controlador CONTINUE:
+ Las palabras clave CONTINUE\_HANDLER y EXIT\_HANDLER solo se pueden usar en procedimientos almacenados NONATOMIC.
+ Las palabras clave CONTINUE\_HANDLER y EXIT\_HANDLER son opcionales. EXIT\_HANDLER es la opción predeterminada.