es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

PL/SQL: Creación y uso de una tabla temporal en un script.

En una base de datos Oracle 19c, necesito muestrear a los clientes manteniendo una distribución uniforme para modelar el movimiento de los clientes. A propósito, hay múltiples filas con los mismos clientes, pero cambiando las direcciones para modelar el movimiento. Por lo tanto, para el muestreo, necesito agrupar primero.

Lo que tengo es que para la claúsula SAMPLE, la fuente debe ser materializada. Así que en el script PL/SQL genero una tabla temporal que quiero usar después con SAMPLE. Pero incluso un simple SELECT INTO después no funciona.

set SERVEROUT on;
DECLARE
    v_cust_name VARCHAR2(100);
    cmd_creation VARCHAR2(500) := 'CREATE PRIVATE TEMPORARY TABLE ORA$PTT_temp_cust AS(
        SELECT cust_id, MIN(name) as name
        FROM customers
        GROUP BY cust_id)';
BEGIN

    EXECUTE IMMEDIATE cmd_creation;
    dbms_output.put_line('temp created');

    SELECT name 
    INTO v_cust_name
    FROM (SELECT * 
        FROM ORA$PTT_temp_cust SAMPLE(5))
    WHERE ROWNUM =1;

    EXECUTE IMMEDIATE 'DROP TABLE ORA$PTT_temp_cust';
    dbms_output.put_line('temp dropped');
END;

Lo que obtengo es lo siguiente:

ORA-06550: línea 15, columna 18:
PL/SQL: ORA-00942: la tabla o vista no existe

La tabla se crea. Hasta ahí llegué cuando solo ejecuté el comando para la creación y nada más. Luego puedo acceder a la tabla en un script deseado desde otro punto. ¿Tiene esto que ver con la compilación? ¿Hay alguna forma diferente de resolver esto?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema está en el ámbito de la tabla temporal. La tabla temporal creada con el comando CREATE PRIVATE TEMPORARY TABLE solo es visible dentro del bloque PL/SQL donde se crea. Por lo tanto, cuando intentas seleccionar de ella fuera de ese bloque, no se puede encontrar y obtienes el error de “tabla o vista no existe”.

    Una forma de resolver esto sería modificar tu bloque PL/SQL para incluir la sentencia SELECT INTO dentro del mismo bloque donde se crea la tabla temporal. Por ejemplo:

    set SERVEROUT on;
    DECLARE
        v_cust_name VARCHAR2(100);
        cmd_creation VARCHAR2(500):='CREATE PRIVATE TEMPORARY TABLE ORA$PTT_temp_cust AS(
            SELECT cust_id, MIN(name) as name
            FROM customers
            GROUP BY cust_id)';
    BEGIN
    
        EXECUTE IMMEDIATE cmd_creation;
        dbms_output.put_line('temp created');
    
        -- seleccionar de la tabla temporal dentro del mismo bloque
        SELECT name 
        INTO v_cust_name
        FROM ORA$PTT_temp_cust SAMPLE(5)
        WHERE ROWNUM =1;
    
        EXECUTE IMMEDIATE 'DROP TABLE ORA$PTT_temp_cust';
        dbms_output.put_line('temp dropped');
    END;
    

    Con esta modificación, la sentencia SELECT INTO se ejecuta dentro del mismo ámbito donde se creó la tabla temporal, por lo que debería poder encontrar la tabla y recuperar los datos deseados.

Comments are closed.