4

I'm trying to create a function which returns an object that can be used in the FROM Clause. According to research on the oracle documentation I've found that a PIPELINED function is what I need.

I have this code:

CREATE TYPE type_struct AS OBJECT
(
    i NUMBER
);

CREATE TYPE tp_struct AS TABLE OF type_struct;

CREATE OR REPLACE FUNCTION gen_nums (na NUMBER, nb NUMBER)
RETURN tp_struct PIPELINED
IS
    rec type_struct;
    counter NUMBER;
BEGIN
    counter := na;

    WHILE (counter <= nb)
    LOOP
        SELECT counter
        INTO rec
        FROM dual;

        counter := counter + 1;

        PIPE ROW (rec);
    END LOOP;

    RETURN;
END gen_nums;
/

The intended result is a table with records from 'na' to 'nb', both inclusive.

However I get this error when compiling the function:

ORA 00932 inconsistent datatypes expected udt got number

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Nuno Valente
  • 143
  • 2
  • 12
  • Your code won't compile because the internal assignment names don't match the parameter names. If you're going to edit your code for publishing please make sure it's still correct. – APC Nov 16 '16 at 11:28
  • Thank you for noticing! Editing done! – Nuno Valente Nov 16 '16 at 11:53

2 Answers2

6

ORA 00932 inconsistent datatypes expected udt got number

You get this because your code assigns a scalar to the output type. You need to cast the variable to match the assignment target. So:

   SELECT type_struct(counter)
    INTO rec
    FROM dual;

You don't necessarily need a pipelined function. We can use table() with any function which returns a collection.

Here is a much simpler implementation, which requires only one UDT.

CREATE TYPE tp_numbers AS TABLE OF number;
/
CREATE OR REPLACE FUNCTION gen_nums (na NUMBER, nb NUMBER)
RETURN tp_numbers 
IS
    return_value tp_numbers ;
BEGIN
    SELECT (na + level) - 1 
    bulk collect    INTO return_value  
    FROM dual
    connect by level <= nb;

    RETURN return_value ;
END gen_nums;
/
APC
  • 144,005
  • 19
  • 170
  • 281
0
CREATE OR REPLACE FUNCTION gen_nums (na NUMBER, nb NUMBER)
RETURN sys.DBMS_DEBUG_VC2COLL PIPELINED --sys.DBMS_DEBUG_VC2COLL an oracle provided collection type.
IS
    counter NUMBER;
BEGIN
    counter := na;
    WHILE (counter <= nb)
    LOOP
        PIPE ROW (counter);
        counter := counter + 1;
    END LOOP;
    RETURN;
END gen_nums;
Prashant Mishra
  • 619
  • 9
  • 25