sql >> Base de Datos >  >> RDS >> Oracle

Recorriendo valores, creando consultas dinámicas y agregando al conjunto de resultados

Una función de tabla canalizada parece más adecuada para lo que desea, especialmente si todo lo que está haciendo es recuperar datos. Consulte http://www.oracle-base.com/ artículos/misc/pipelined-table-functions.php

Lo que hace es crear un tipo para su fila de salida. Entonces, en su caso, crearía un objeto como

CREATE TYPE get_data_faster_row AS OBJECT(
    seq    NUMBER(15,2),
    value  VARCHAR2(10),
    item   VARCHAR2(10)
);

Luego cree un tipo de tabla que sea una tabla compuesta por su tipo de fila anterior

CREATE TYPE get_data_faster_data IS TABLE OF get_data_faster_row;

Luego cree su función de tabla que devuelva los datos de manera canalizada. Canalizado en Oracle es un poco como un retorno de rendimiento en .net (no estoy seguro si está familiarizado con eso). Encuentra todas las filas que desea y las "canaliza" una a la vez en un bucle. Cuando su función completa, la tabla que se devuelve consta de todas las filas que canalizó.

CREATE FUNCTION Get_Data_Faster(params) RETURN get_data_faster_data PIPELINED AS
BEGIN
    -- Iterate through your parameters 
        --Iterate through the results of the select using
        -- the current parameters. You'll probably need a 
        -- cursor for this
        PIPE ROW(get_data_faster_row(seq, value, item));
        LOOP;
    LOOP;
END;

EDITAR:Siguiendo el comentario de Alex a continuación, necesitas algo como esto. No he podido probar esto, pero debería ayudarlo a comenzar:

CREATE FUNCTION Get_Data_Faster(in_seq_numbers IN seq_numbers_array, in_values IN text_array, in_items IN text_array, list IN VARCHAR2) RETURN get_data_faster_data PIPELINED AS
    TYPE r_cursor IS REF CURSOR;
    query_results r_cursor;
    results_out get_data_faster_row := get_data_faster_row(NULL, NULL, NULL);

    query_str VARCHAR2(4000);

    seq_number NUMBER;
    the_value VARCHAR2(10);
    the_item VARCHAR2(10);

BEGIN
    FOR i IN 1..in_seq_number.COUNT
    LOOP
        seq_number := in_seq_numbers(i);
        the_value := trim(in_values(i));
        the_item := trim(in_items(i));

        query_str := 'SELECT distinct '||seq_number||' as seq, value, item
        FROM my_table ai';                    

        query_str := query_str || '
        WHERE ai.value = '''||the_value||''' AND ai.item = '''||the_item||'''
        AND ai.param = ''BOOK''
        AND ai.prod in (' || list || ');

        OPEN query_results FOR query_str;

        LOOP
            FETCH query_results INTO 
                results_out.seq,
                results_out.value,
                results_out.item;
            EXIT WHEN query_results%NOTFOUND;
            PIPE ROW(results_out);
        END LOOP;

    CLOSE query_results;

    END LOOP;

END;

Información adicional del comentario de Alex a continuación útil para la respuesta: