Oracle
 sql >> Base de données >  >> RDS >> Oracle

Boucle sur les valeurs, création d'une requête dynamique et ajout au jeu de résultats

Une fonction de table en pipeline semble mieux adaptée à ce que vous voulez, surtout si vous ne faites que récupérer des données. Voir http://www.oracle-base.com/ articles/misc/pipelined-table-functions.php

Ce que vous faites est de créer un type pour votre ligne de sortie. Donc, dans votre cas, vous créeriez un objet tel que

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

Créez ensuite un type de tableau qui est un tableau composé de votre type de ligne ci-dessus

CREATE TYPE get_data_faster_data IS TABLE OF get_data_faster_row;

Créez ensuite votre fonction de table qui renvoie les données de manière pipeline. Pipeliné dans Oracle est un peu comme un rendement de rendement dans .net (je ne sais pas si vous êtes familier avec cela). Vous trouvez toutes les lignes que vous voulez et les "tuyez" une à la fois dans une boucle. Lorsque votre fonction se termine, la table renvoyée est constituée de toutes les lignes que vous avez extraites.

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;

EDIT :Suite au commentaire d'Alex ci-dessous, vous avez besoin de quelque chose comme ça. Je n'ai pas pu tester cela, mais cela devrait vous aider à démarrer :

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;

Informations supplémentaires du commentaire d'Alex ci-dessous utiles pour la réponse :