循环价值观,创建动态查询,并添加到结果集(Looping on values, creating d

2019-09-23 01:17发布

我有以下问题。 我是一个有经验的Java程序员,但在SQL和PL / SQL是有点的n00b的。

我需要做到以下几点。

1张通行证在几个阵列和其他一些变量输入程序

2环路上在阵列(它们都具有相同数量的项目)的值,并动态创建一个SQL语句

3运行此语句,并将其添加到结果集(这是该过程的OUT参数)

我已经有动态创建一个SQL查询,运行它,并把结果加到一个结果集(这是一个REF CURSOR)的经验,但我不知道我怎么就不断循环,而且每个调用的结果添加到查询到相同的结果集。 我甚至不知道这是可能的。

这里是我到目前为止(编辑为了简单的代码)。 我知道这是错误的,因为我只是用最新的查询结果替换RESULT_SET的内容(这是在其中调用这个程序的Java被证实)。

任何和所有帮助将不胜感激。

TYPE REF_CURSOR IS REF CURSOR;  




PROCEDURE GET_DATA_FASTER(in_seq_numbers IN seq_numbers_array, in_values IN text_array, in_items IN text_array, list IN VARCHAR2, RESULT_SET OUT REF_CURSOR) AS  
  query_str VARCHAR2(4000);

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

  BEGIN

    FOR i IN 1..in_seq_numbers.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 RESULT_SET FOR query_str;

    END LOOP;

    EXCEPTION WHEN OTHERS THEN
      RAISE;

  END GET_DATA_FASTER;

Answer 1:

管道式表功能似乎你想要的东西更适合,特别是如果你正在做的是检索数据。 见http://www.oracle-base.com/articles/misc/pipelined-table-functions.php

你要做的就是为你的输出行的一个。 所以你的情况,你会创建一个对象,如

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

然后创建一个表类型,是由你的行类型以上的表

CREATE TYPE get_data_faster_data IS TABLE OF get_data_faster_row;

然后创建一个以流水线的方式返回数据的表函数。 流水线在Oracle是一个有点像.NET中的收益率回报(不知道如果你熟悉)。 你会发现所有你想要的行和“管”出来一个在一个循环的时间。 当你的函数完成所返回的表由您管道出来的所有行。

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;

编辑:继Alex的评论如下,你需要这样的事情。 我一直没能对此进行测试,但它应该让你开始:

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;

从下面有用的亚历克斯的评论的答案额外的信息:

你可以有不同来源的多重循环,只要从每个被放入同一个对象的种类的数据,你可以继续抽他们与管行语句在函数的任何位置。 来电者把它们看作一个表中的行,你管的顺序。 而不是调用过程,并得到设置为输出参数的结果,可以从表中查询作为选择序列,价值,项目(package.get_data_faster(A,B,C,d)),当然你仍然可以有一个BY子句命令,如果他们用管道输送的顺序是不是你想要的。



文章来源: Looping on values, creating dynamic query and adding to result set