Pipeline function syntax issues

What am I doing wrong:
I get an error on pipe row (l_var)
says "of wrong type"
This code is just like the code from here:
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:4447489221109
sqlplus >create or replace type mytesttype as object (a varchar2(1000));
2 /
function PipeTest return myTableType
pipelined
is
l_query sys_refcursor;
l_var mytesttype;
begin
open l_query for
select object_name from user_objects where rownum < 11;
loop
fetch l_query into l_var;
pipe row(l_var);
exit when l_query%notfound;
end loop;
return;
end;

Your return type is return myTableType , whereas l_var is mytesttype.

Similar Messages

  • List View Report with pipelined function in Mobile application and ORA-01007: variable not in select list

    Hi!
    I have a problem with List View Report in mobile application (theme 50 in apex) after updating to apex 4.2.2. I created Report -> List View. I used select from pipelined function in Region Source. Then when page is running and submited three times (or refreshed three times) I get an error:
    Error during rendering of region "LIST VIEW".
    ORA-01007: variable not in select list
    Technical Info (only visible for developers)
    is_internal_error: true
    apex_error_code: APEX.REGION.UNHANDLED_ERROR
    ora_sqlcode: -1007
    ora_sqlerrm: ORA-01007: variable not in select list
    component.type: APEX_APPLICATION_PAGE_REGIONS
    component.id: 21230833903737364557
    component.name: LIST VIEW
    error_backtrace:
         ORA-06512: at "APEX_040200.WWV_FLOW_DISP_PAGE_PLUGS", line 4613
         ORA-06512: at "APEX_040200.WWV_FLOW_DISP_PAGE_PLUGS", line 3220
    I get this error only when I use select from pipelined function in Region Source (for example: "select value1, value2 from table(some_pipelined_function(param1, param2)) ").
    You can check it on http://apex.oracle.com/pls/apex/f?p=50591 (login - demo, password - demo).
    In this application:
    - I created package TAB_TYPES_PKG:
    create or replace PACKAGE TAB_TYPES_PKG IS
    TYPE cur_rest_r IS RECORD (
        STR_NAME          VARCHAR2(128),
        INFO              VARCHAR2(128)
    TYPE cur_rest_t IS TABLE OF cur_rest_r;
    END TAB_TYPES_PKG;
    - I created pipelined function TEST_FUNC:
    create or replace
    FUNCTION TEST_FUNC
    RETURN TAB_TYPES_PKG.cur_rest_t  PIPELINED IS
    r_cur_rest TAB_TYPES_PKG.cur_rest_r;
    BEGIN
    r_cur_rest.STR_NAME := 'ROW 1';
    r_cur_rest.INFO := '10';
    PIPE ROW (r_cur_rest);
    r_cur_rest.STR_NAME := 'ROW 2';
    r_cur_rest.INFO := '20';
    PIPE ROW (r_cur_rest);
    r_cur_rest.STR_NAME := 'ROW 3';
    r_cur_rest.INFO := '30';
    PIPE ROW (r_cur_rest);
    r_cur_rest.STR_NAME := 'ROW 4';
    r_cur_rest.INFO := '40';
    PIPE ROW (r_cur_rest);
    r_cur_rest.STR_NAME := 'ROW 5';
    r_cur_rest.INFO := '50';
    PIPE ROW (r_cur_rest);
    RETURN;
    END TEST_FUNC;
    - I created List View Report on Page 1:
    Region Source:
    SELECT str_name,
           info
    FROM TABLE (TEST_FUNC)
    We can see error ORA-01007 after refresing (or submiting) Page 1 three times or more.
    How to fix it?

    Hi all
    I'm experiencing the same issue.  Predictably on every third refresh I receive:
    Error
    Error during rendering of region "Results".
    ORA-01007: variable not in select list
    Technical Info (only visible for developers)
    is_internal_error: true
    apex_error_code: APEX.REGION.UNHANDLED_ERROR
    ora_sqlcode: -1007
    ora_sqlerrm: ORA-01007: variable not in select list
    component.type: APEX_APPLICATION_PAGE_REGIONS
    component.id: 6910805644140264
    component.name: Results
    error_backtrace: ORA-06512: at "APEX_040200.WWV_FLOW_DISP_PAGE_PLUGS", line 4613 ORA-06512: at "APEX_040200.WWV_FLOW_DISP_PAGE_PLUGS", line 3220
    OK
    I am running Application Express 4.2.2.00.11 on GlassFish 4 using Apex Listener 2.0.3.221.10.13.
    Please note: this works perfectly using a classic report in my desktop application; however, no joy on the mobile side with a list view.  I will use a classic report in the interim.
    My region source is as follows:
    SELECT description AS "DESCRIPTION", reference AS "REFERENCE" FROM TABLE(AUTOCOMPLETE_LIST_VIEW_FNC('RESULTS'))
    The procedure:
      FUNCTION AUTOCOMPLETE_LIST_VIEW_FNC(
          p_collection_name IN VARCHAR2)
        RETURN list_row_table_type
      AS
        v_tab list_row_table_type := list_row_table_type();
      BEGIN
        DECLARE
          jsonarray json_list;
          jsonobj json;
          json_clob CLOB;
        BEGIN
          SELECT clob001
          INTO json_clob
          FROM apex_collections
          WHERE collection_name = p_collection_name;
          jsonobj              := json(json_clob);
          jsonarray            := json_ext.get_json_list(jsonobj, 'predictions');
          FOR i IN 1..jsonArray.count
          LOOP
            jsonobj := json(jsonArray.get(i));
            v_tab.extend;
            v_tab(v_tab.LAST) := list_row_type(json_ext.get_string(jsonobj, 'description'), json_ext.get_string(jsonobj, 'reference'));
          END LOOP;
          RETURN(v_tab);
        END;  
      END AUTOCOMPLETE_LIST_VIEW_FNC;
    Thanks!
    Tim

  • How do you pass parameters to a Pipelined function?

    I am using Oracle 10G and the ODP .NET 32 bit client.
    I am facing an issue trying to use variable binding with a pipeline function in Oracle. I am using ODP .NET for connecting to the database.
    If you want to be familiar with PIPELINED functions, you can read [this  blog.|http://oradim.blogspot.com/2007/10/odpnet-tip-using-pipelined-functions.html]
    I have very similar code with a difference. My function takes in two parameters that I need to pass to get the table. This is working in SQLPLUS without any issues.
    In my C# code, however things change. My function no longer returns a recordset (data reader), if I use the standard method of assigning the parameters.
    The code will work if I concat the variables in a string.
    Here is the example that doesn't work.
            static OracleDataReader fetchData(OracleConnection oc, string strPONumber)
                try
                    OracleCommand od = oc.CreateCommand();
                    od.CommandType = System.Data.CommandType.Text;
                    od.CommandText = "select * from table(pkg_fetchPOInfo.getPORowsTable(:1,:2))";
                    OracleParameter op1 = new OracleParameter();
                    op1.ParameterName = "1";
                    op1.OracleDbType = OracleDbType.Varchar2;
                    op1.Direction = System.Data.ParameterDirection.Input;
                    op1.Size = 7;
                    op1.Value = strPONumber;
                    od.Parameters.Add(op1);
                    OracleParameter op2 = new OracleParameter();
                    op2.ParameterName = "2";
                    op2.OracleDbType = OracleDbType.Varchar2;
                    op2.Direction = System.Data.ParameterDirection.Input;
                    op2.Size = 3;
                    op2.Value = "US";
                    od.Parameters.Add(op2);
                    OracleDataReader or = od.ExecuteReader();
                    return or;
                catch (Exception e)
                    Console.WriteLine("Error " + e.ToString());
                    return null;
            }Here is the example that does.
          static OracleDataReader fetchData(OracleConnection oc, string strPONumber)
                try
                    OracleCommand od = oc.CreateCommand();
                    string formSQL = "Select * from table(pkg_fetchPOInfo.getPORowsTable('"+strPONumber+"','US'))";
                    od.CommandType = System.Data.CommandType.Text;
                    od.CommandText = formSQL;
                    OracleDataReader or = od.ExecuteReader();
                    return or;
                catch (Exception e)
                    Console.WriteLine("Error " + e.ToString());
                    return null;
            }

    throw it into an anonymous block and it should work for you.
    --create or replace type varcharTableType as table   of varchar2 (4000);
    create or replace
    PACKAGE TESTP AS
      function TESTPIPE(nr in number, nr2 in number) return varchartabletype pipelined;
    END TESTP;
    CREATE OR REPLACE
    PACKAGE BODY TESTP AS
      function TESTPIPE(nr in number, nr2 in number) return varchartabletype pipelined AS
          CURSOR TESTPIPE_cur
           IS
              SELECT (level + 1) datam
                FROM dual
              connect by level < nr;
         vtt varchartabletype ;
      BEGIN
             OPEN TESTPIPE_cur;
               LOOP
                  FETCH testpipe_cur
                  BULK COLLECT INTO vtt LIMIT nr2;
                  FOR indx IN 1 .. vtt.COUNT
                  LOOP
                      Pipe Row ( vtt( indx ) )  ;
                  END LOOP;
                  EXIT WHEN testpipe_cur%NOTFOUND;
               END LOOP;
      END TESTPIPE;
    END TESTP;
           public static void pipeTest()
                String conString = GetConnectionString();
                OracleConnection _conn = new OracleConnection(conString);
                _conn.Open();
                OracleCommand oCmd = new OracleCommand();
                oCmd.CommandText = "begin open :crs for Select * from table(testp.testpipe(:nr,:nr2)); end;";
                oCmd.CommandType = CommandType.Text ;
                oCmd.Connection = _conn;
                OracleParameter crs = new OracleParameter();
                crs.OracleDbType = OracleDbType.RefCursor;
                crs.Direction = ParameterDirection.Output;
                crs.ParameterName = "crs";
                oCmd.Parameters.Add(crs);
                OracleParameter nr = new OracleParameter();
                nr.OracleDbType = OracleDbType.Int64;
                nr.Direction = ParameterDirection.Input ;
                nr.ParameterName = "nr";
                nr.Value = 25;
                oCmd.Parameters.Add(nr);
                OracleParameter nr2 = new OracleParameter();
                nr2.OracleDbType = OracleDbType.Int64;
                nr2.Direction = ParameterDirection.Input;
                nr2.ParameterName = "nr2";
                nr2.Value = 10;
                oCmd.Parameters.Add(nr2);
                using (OracleDataReader MyReader = oCmd.ExecuteReader())
                    int ColumnCount = MyReader.FieldCount;
                    // get the data and add the row
                    while (MyReader.Read())
                        String s = MyReader.GetOracleValue(0).ToString();
                        Console.WriteLine(string.Format("i={0}", s));
                Console.ReadLine();
            }

  • Turning sql  string (with dynamic columns) into a pipelined function

    Hi guys,
    I was working on an apex report the other day, and wrote the sql below (for those who don't know apex well, in an apex report you can define the columns at runtime.) When I was finished, I said to myself: "It would be great to have a pipeline function with this capability." So, the idea would be to have a sql string where the columns are created dynamically, depending on input parameters - and then be able to use this sql everywhere (oracle reports, sqlplus) through a pipelined function.
    Here's the sql (simplified, of course, the data itself is actually not important - the LOOP is the key)
    declare
    v_sql varchar2(4000);
    begin
    v_sql := 'select client, ';
    for i in (select employee from company_employees_view where condition = pi_parameter order by 1) loop
    v_sql := v_sql || sum(decode(employee,''' || i.employee || ''', total)) "' || i.employee || '"';
    end loop;
    v_sql := v_sql || ', sum(total) "Total"';
    v_sql := v_sql || ' from company_employees_view group by client';
    end;
    This sql would result in a final product like:
    select client
    , sum(decode(employee,'John',total) "John"
    , sum(decode(employee,'Paul',total) "Paul"
    , sum(decode(employee,'George',total) "George"
    (and so on... this sql could have more or less columns depending on the input parameters of the function)
    from company_employees_view
    group by client;
    I have tried feeding this sql into a ref cursor and an object, but always received an "inconsistent datatypes" message.
    The object would be something like:
    create or replace object rt_employee as (total number);
    create or replace tt_employee as table of rt_employee;
    create or replace object rt_client as (
    client varchar2(100),
    employee tt_employee);
    create or replace tt_client as table of rt_client;
    (I am not paying too much attention to syntax here.)
    By the way, no hurry whatsoever, this is just for fun, take your time. I am using database XE with apex 2.1 and sql developer 1.2.
    Thanks, Roger

    This is the only solution I've ever seen to dynamic pipelined columns...
    How to pipeline a function with a dynamic number of columns?

  • PLS-00630: pipelined functions must have a supported collection return type

    Hello, I created an TYPE of OBJECT and a PLSQL Function as shown below, but the function compilation errors with following. Not sure where is the issue?
    PLS-00630: pipelined functions must have a supported collection return typeThis is on Oracle 10g r2
    CREATE OR REPLACE TYPE cxs_plsql_profiler_object_type AS OBJECT (
       cxs_object_name      VARCHAR2 (128),
       cxs_object_type      VARCHAR2 (19),
       cxs_object_status    VARCHAR2 (7),
       cxs_read_execution   NUMBER,
       cxs_buffer_gets      NUMBER,
       cxs_disk_reads       NUMBER,
       cxs_executions       NUMBER,
       cxs_sorts            NUMBER,
       cxs_sharable_mem     NUMBER,
       cxs_address          NUMBER,
       cxs_hashvalue        NUMBER,
       cxs_osuser           VARCHAR2 (30),
       cxs_username         VARCHAR2 (30),
       cxs_module           VARCHAR2 (48),
       cxs_machine          VARCHAR2 (64),
       cxs_status           VARCHAR2 (8),
       cxs_terminal         VARCHAR2 (16),
       cxs_percentconsume   NUMBER,
       cxs_percentrepeat    NUMBER,
       cxs_plan             VARCHAR2 (120),
       target_name          VARCHAR2 (200),
       referenced_name      VARCHAR2 (200),
       referenced_type      VARCHAR2 (200),
       targetowner          VARCHAR2 (200),
       refowner             VARCHAR2 (200)
    )and here is the API
        FUNCTION CXS_GENERATE_PLSQL_PROFILER
    RETURN cxs_plsql_profiler_object_type
    PIPELINED IS
    out_rec cxs_plsql_profiler_object_type ;
    plsbatch plsql_batch;
    skount integer;
    dpendrec depend_tab;
    dkount integer;
    CURSOR objects
          IS
             SELECT object_name, object_type
               FROM dba_objects
              WHERE status = 'VALID'
                AND owner NOT IN ('SYS', 'SYSTEM')
                AND object_type IN ('PACKAGE', 'PROCEDURE', 'FUNCTION');
          CURSOR apis (p_object dba_objects.object_name%TYPE)
          IS
             SELECT DISTINCT *
                        FROM (SELECT   SUBSTR (a.sql_text, 1, 50) sql_text,
                                       TRUNC
                                          (  a.disk_reads
                                           / DECODE (a.executions,
                                                     0, 1,
                                                     a.executions
                                          ) reads_per_execution,
                                       a.buffer_gets, a.disk_reads, a.executions,
                                       a.sorts, a.sharable_mem, a.address,
                                       a.hash_value, b.osuser, b.username,
                                       b.module, b.machine, b.status, b.terminal,
                                       ROUND
                                          (cxs_db_info.kompute_percentofsql
                                                                   (a.sharable_mem),
                                           5
                                          ) percentkonsume,
                                       cxs_db_info.kount_repeat
                                                             (b.osuser,
                                                              b.terminal
                                                             ) percentr,
                                       c.operation explainplan
                                  FROM v$sqlarea a, v$session b, v$sql_plan c
                                 WHERE b.sql_hash_value = a.hash_value
                                   AND b.sql_address = a.address
                                   AND a.hash_value = c.hash_value
                                   AND a.address = c.address
                                   AND b.status = 'ACTIVE'
                                   AND UPPER (a.sql_text) LIKE
                                                            '%' || p_object || '%'
                                   AND c.ID = 0
                              ORDER BY 2 DESC)
                       WHERE ROWNUM <= 50;   --profile option
    BEGIN
    skount := 0;
    dkount := 0;
    FOR i IN objects
          LOOP
             FOR j IN apis (i.object_name)
             LOOP
                skount := skount + 1;
                plsbatch(skount).cxs_object_name  := i.object_name;
       plsbatch(skount).cxs_object_type      :=  i.object_type;
       plsbatch(skount).cxs_object_status    :=  i.object_status;
       plsbatch(skount).cxs_read_execution   := j.reads_per_execution;
       plsbatch(skount).cxs_buffer_gets      := j.buffer_gets;
       plsbatch(skount).cxs_disk_reads       := j.disk_reads;
       plsbatch(skount).cxs_executions       := j.executions;
       plsbatch(skount).cxs_sorts            := j.sorts;
       plsbatch(skount).cxs_sharable_mem     := j.sharable_mem;
       plsbatch(skount).cxs_address          := j.address;
       plsbatch(skount).cxs_hashvalue        := j.hashvalue;
       plsbatch(skount).cxs_osuser           := j.osuser;
       plsbatch(skount).cxs_username         := j.username;
       plsbatch(skount).cxs_module           := j.module;
       plsbatch(skount).cxs_machine          := j.machine;
       plsbatch(skount).cxs_status           := j.status;
       plsbatch(skount).cxs_terminal         := j.terminal;
       plsbatch(skount).cxs_percentconsume   := j.percentconsume;
       plsbatch(skount).cxs_percentrepeat    := j.percentrepeat;
       plsbatch(skount).cxs_plan             := j.explainplan;
             END LOOP;
             FOR dd IN dpend (i.object_name)
             LOOP
                dkount := dkount + 1;
                dependrec (dkount).target_name := dd.NAME;
                dependrec (dkount).refname := dd.referenced_name;
                dependrec (dkount).reftype := dd.referenced_type;
                dependrec (dkount).target_owner := dd.owner;
                dependrec (dkount).refowner := dd.referenced_owner;
             END LOOP;
          END LOOP;
    for a in 1..skount loop
       out_rec.cxs_object_type      := plsbatch(a).object_type;
       out_rec.cxs_object_status    := plsbatch(a).object_status;
       out_rec.cxs_read_execution   := plsbatch(a).reads_per_execution;
       out_rec.cxs_buffer_gets      := plsbatch(a).buffer_gets;
       out_rec.cxs_disk_reads       := plsbatch(a).disk_reads;
       out_rec.cxs_executions       := plsbatch(a).executions;
       out_rec.cxs_sorts            := plsbatch(a).sorts;
       out_rec.cxs_sharable_mem     := plsbatch(a).sharable_mem;
       out_rec.cxs_address          := plsbatch(a).address;
       out_rec.cxs_hashvalue        := plsbatch(a).hashvalue;
       out_rec.cxs_osuser           := plsbatch(a).osuser;
       out_rec.cxs_username         := plsbatch(a).username;
       out_rec.cxs_module           := plsbatch(a).module;
       out_rec.cxs_machine          := plsbatch(a).machine;
       out_rec.cxs_status           := plsbatch(a).status;
       out_rec.cxs_terminal         := plsbatch(a).terminal;
       out_rec.cxs_percentconsume   := plsbatch(a).percentconsume;
       out_rec.cxs_percentrepeat    := plsbatch(a).percentrepeat;
       out_rec.cxs_plan             := plsbatch(a).explainplan;
       PIPE ROW(out_rec);
    end loop;
    for b in 1..dkount loop
        out_rec.target_name := dd.NAME;
                out_rec.refname := dependrec (b).referenced_name;
                out_rec.reftype := dependrec (b).referenced_type;
                out_rec.target_owner := dependrec (b).owner;
                out_rec.refowner := dependrec (b).referenced_owner;
                PIPE ROW(out_rec);
    end loop;
    RETURN;
    EXCEPTION
    WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.format_error_backtrace);
    DBMS_OUTPUT.PUT_LINE(SQLCODE);
    DBMS_OUTPUT.PUT_LINE(SQLERRM);
    END; and below are tradtional table types that are used in code above.
    TYPE type_plsql_rec IS RECORD (
       cxs_object_name      VARCHAR2 (128),
       cxs_object_type      VARCHAR2 (19),
       cxs_object_status    VARCHAR2 (7),
       cxs_read_execution   NUMBER,
       cxs_buffer_gets      NUMBER,
       cxs_disk_reads       NUMBER,
       cxs_executions       NUMBER,
       cxs_sorts            NUMBER,
       cxs_sharable_mem     NUMBER,
       cxs_address          NUMBER,
       cxs_hashvalue        NUMBER,
       cxs_osuser           VARCHAR2 (30),
       cxs_username         VARCHAR2 (30),
       cxs_module           VARCHAR2 (48),
       cxs_machine          VARCHAR2 (64),
       cxs_status           VARCHAR2 (8),
       cxs_terminal         VARCHAR2 (16),
       cxs_percentconsume   NUMBER,
       cxs_percentrepeat    NUMBER,
       cxs_plan             VARCHAR2 (120)
       TYPE plsql_batch IS TABLE OF type_plsql_rec
          INDEX BY BINARY_INTEGER;
           TYPE type_depend_tab IS RECORD (
          target_name    dba_dependencies.NAME%TYPE,
          refname        dba_dependencies.referenced_name%TYPE,
          reftype        dba_dependencies.referenced_type%TYPE,
          target_owner   dba_dependencies.owner%TYPE,
          refowner       dba_dependencies.referenced_owner%TYPE
       TYPE depend_tab IS TABLE OF type_depend_tab
          INDEX BY BINARY_INTEGER;
    Thank you for your time in reading this post
    R

    Thank you Billy and Saubhik,
    I have followed your guidelines and was able to resolve this error. Now, after successfully compiling the code, I attempted to execute it in a following way.
    SELECT * FROM TABLE (cxs_generate_plsql_profiler);It gives following error: ORA-00904: "CXS_GENERATE_PLSQL_PROFILER": invalid identifier
    I also tried putting in quotes like below
    SELECT * FROM TABLE ('cxs_generate_plsql_profiler');Then, it gives following error:
    ORA-22905: cannot access rows from a non-nested table item
    Any Idea where I am doing wrong?
    Thanks,
    R

  • Pipelined function ignores DML changes on subqueries

    Hello all,
    I have a really specific issue when using a pipelined function used in a complex subquery where the function ignores the changes made on the current transaction. The problem is the hidden hint materialize sometimes used by the Oracle optimizer. I say sometimes because it depends mostly on the execution plan and the complexity of the query.
    I can repeat the problem with a dummy scenario.
    Let's say we have a dummy table with a simple record :
    CREATE TABLE DUMMY ("NAME" VARCHAR2(50 BYTE));
    INSERT INTO DUMMY VALUES('Original name');
    We then create a package which will contain our pipelined function and its record object and collection:
    CREATE OR REPLACE PACKAGE PKG_DUMMY AS
    TYPE DUMMY_RECORD IS RECORD (NAME VARCHAR2(50 BYTE));
    TYPE DUMMY_RECORDS IS TABLE OF DUMMY_RECORD;
    FUNCTION FUNC_GET_DUMMY_NAME RETURN DUMMY_RECORDS PIPELINED;
    END PKG_DUMMY;
    CREATE OR REPLACE
    PACKAGE BODY PKG_DUMMY AS
    FUNCTION FUNC_GET_DUMMY_NAME RETURN DUMMY_RECORDS PIPELINED AS
    BEGIN
    FOR CUR IN ( SELECT * FROM DUMMY )
    LOOP
    PIPE ROW (CUR);
    END LOOP;
    END FUNC_GET_DUMMY_NAME;
    END PKG_DUMMY;
    With this SQL query, we can return the value of the table by the pipelined function :
    WITH DUMMY_NAME AS
    SELECT "NAME"
    FROM TABLE(PKG_DUMMY.FUNC_GET_DUMMY_NAME())
    SELECT "NAME"
    FROM DUMMY_NAME
    Result
    Original name
    If we modify the DUMMY table with a new name without a commit, and re-execute the query, we got the same result :
    UPDATE DUMMY SET "NAME" = 'New name';
    Result
    New name
    But if we add the materialize hint in the subquery (without doing a commit or rollback), we have the original value hence my issue :
    WITH DUMMY_NAME AS
    SELECT /*+ materialize */ "NAME"
    FROM TABLE(PKG_DUMMY.FUNC_GET_DUMMY_NAME())
    SELECT "NAME"
    FROM DUMMY_NAME
    Result
    Original name
    I know I can force my subquery to use an inline hint instead of the "materialize" hint chose by the optimizer but then the query lose a lot of performance. Is there a way to force Oracle to use current DML changes with the materialize hint on a pipelined funtion in a subquery?
    This thread is also for this issue : http://stackoverflow.com/questions/1597467/is-using-a-select-inside-a-pipelined-pl-sql-table-function-allowed

    Hi Eliante, Hi Dominic,
    Very Interesting. Here what I can reproduce in Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
    sql > truncate table dummy;
    Table truncated.
    sql >INSERT INTO DUMMY VALUES('Original name');
    1 row created.Please pay attention that I didn't commit
    sql > with dummy_name as
      2  (
      3  select  "NAME"
      4  from table(pkg_dummy.func_get_dummy_name())
      5  )
      6  select "NAME"
      7  from dummy_name;
    NAME
    Original name
    sql> start c:\dispcursor
    PLAN_TABLE_OUTPUT
    SQL_ID  838mtur4m74j2, child number 0
    with dummy_name as ( select  "NAME" from table(pkg_dummy.func_get_dummy_name()) ) select "NAME"
    from dummy_name
    Plan hash value: 117055
    | Id  | Operation                         | Name                | Starts | A-Rows |   A-Time   | Buffers |
    |   1 |  COLLECTION ITERATOR PICKLER FETCH| FUNC_GET_DUMMY_NAME |      1 |      1 |00:00:00.01 |      15 |
    Note
       - rule based optimizer used (consider using cbo)
    17 rows selected.
    sql > with dummy_name as
      2  (
      3  select /*+ materialize */ "NAME"
      4  from table(pkg_dummy.func_get_dummy_name())
      5  )
      6  select "NAME"
      7  from dummy_name;
    no rows selected
    sql >start c:\dispcursor
    PLAN_TABLE_OUTPUT
    SQL_ID  9frx3wjk992rd, child number 0
    with dummy_name as ( select /*+ materialize */ "NAME" from table(pkg_dummy.func_get_dummy_name()) ) select "NAME" from dummy_name
    Plan hash value: 1359790764
    | Id  | Operation                           | Name                        | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
    |   1 |  TEMP TABLE TRANSFORMATION          |                             |      1 |        |      0 |00:00:00.01 |      20 |       |       |          |
    |   2 |   LOAD AS SELECT                    |                             |      1 |        |      0 |00:00:00.01 |      19 |  1024 |  1024 |          |
    |   3 |    COLLECTION ITERATOR PICKLER FETCH| FUNC_GET_DUMMY_NAME         |      1 |        |      0 |00:00:00.01 |      17 |       |       |          |
    |   4 |   VIEW                              |                             |      1 |   8168 |      0 |00:00:00.01 |       0 |       |       |          |
    |   5 |    TABLE ACCESS FULL                | SYS_TEMP_0FD9D780C_BD7649E3 |      1 |   8168 |      0 |00:00:00.01 |       0 |       |       |          |
    16 rows selected.I can point out that the TABLE ACCESS FULL of the global temporary SYS_TEMP_0FD9D780C_BD7649E3 table created by Oracle in response to the -materialize hint is returning *0 rows* in operation 5.
    Why?
    It seems for me that the reason for that comes from the fact that the creation of this SYS_TEMP_0FD9D780C_BD7649E3 table is done via direct path read/direct path write and as far as
    the insert of *'Original name'* has not been pushed yet into the disc then materializing the query will generate an empty temporary table (empty in this case).
    This is why if I had committed I will not have seen such a kind of discrepancy between those two queries
    What do you think?
    Mohamed Houri
    www.hourim.wordpress.com

  • Pipelined function, select from table t1 or t2 depending on user's choise

    Hi all,
    My need is to select data from table t1 or t2 depending on user's choise using pipelined function. You can find my first guess below. Maybe someone can help me to save some code, I mean getting the same result without writing "PIPE ROW" twice.
    FUNCTION fn_indicators (p_datbeg date, p_datend date, p_indicatorid number) return cl_risk_act pipelined IS
    v_obj cl_user_type;
    BEGIN
    case when p_indicatorid = 1 then
    FOR e IN (
    select trunc(sysdate-1) as adate, 0 as cid, 0 as indicatorid, '0' as code, '0' as indicatorname, 0 as value, 0 as cnt, '0' as cname from dual
    LOOP
    v_obj.adate              := e.adate;
    v_obj.cid                  := e.cid;
    v_obj.indicatorid       := e.indicatorid;
    v_obj.code               := e.code;
    v_obj.indicatorname  := e.indicatorname;
    v_obj.value              := e.value;
    v_obj.cnt                 := e.cnt;
    v_obj.cname            := e.cname;
    PIPE ROW (v_obj);
    END LOOP;
    when p_indicatorid = 2 then
    FOR e IN (
    select trunc(sysdate-2) as adate, 1 as cid, 1 as indicatorid, '1' as code, '1' as indicatorname, 1 as value, 1 as cnt, '1' as cname from dual
    LOOP
    v_obj.adate              := e.adate;
    v_obj.cid                  := e.cid;
    v_obj.indicatorid       := e.indicatorid;
    v_obj.code               := e.code;
    v_obj.indicatorname  := e.indicatorname;
    v_obj.value              := e.value;
    v_obj.cnt                 := e.cnt;
    v_obj.cname            := e.cname;
    PIPE ROW (v_obj);
    END LOOP;
    end case;
    RETURN;
    end;

    marco wrote:
    Justin,
    In my real code table real_t1 or pipelinedfn_t2 is joined to other tables, so surely real code is bigger than sample one. It is not wise to keep code twise with only one table name changed. I think about dynamic sql to choose from two tables:
    with t1 as
    (select * from real_t1
    t2 as
    (select * from pipelinedfn_t2
    t3 as (
    [dynamic selection of t1 or t2 depending on user's choise]
    select * from t3, t... where...I don't know correct syntax.
    Any ideas?
    >Justin,
    In my real code table real_t1 or pipelinedfn_t2 is joined to other tables, so surely real code is bigger than sample one. It is not wise to keep code twise with only one table name changed. I think about dynamic sql to choose from two tables:
    with t1 as
    (select * from real_t1
    t2 as
    (select * from pipelinedfn_t2
    t3 as (
    [dynamic selection of t1 or t2 depending on user's choise]
    select * from t3, t... where...I don't know correct syntax.
    Any ideas?
    Dynamic code does NOT scale.
    Making the tradeoff of smaller code size for reduced performance is not one that I would make.

  • Select remote pipelined function

    System: AIX 5.1L
    Oracle: 9.2.0.5.0 64 Bit
    If I have a package, created in schema 'exceed', on 1 instance which has a pipelined function. I then grant execute to this package for another user, called 'nav'. On another instance, that has a database link (testtrjo) to the instance with the package above using the 'nav' user account to connect, I get error: ORA-30626: function/procedure parameters of remote object types are not supported. Here is is how I am executing this table funtion across the link:
    select * from table(exceed.UP_EXCEED.UF_GetOpenEvent@testtrjo('locationsexport'));
    When I execute this function as the 'nav' user on the instance that contains the package, it works fine. Like this:
    select * from table(exceed.UP_EXCEED.UF_GetOpenEvent('locationsexport'));
    Anyone know why this is happening? In the Oracle docs it states:
    "Syntax for SQL Calling a PL/SQL Function
    Use the following syntax to reference a PL/SQL function from SQL:
    [[schema.]package.]function_name[@dblink][(param_1...param_n)]
    For example, to reference a function you created that is called My_func, in the
    My_funcs_pkg package, in the Scott schema, that takes two numeric parameters,
    you could call the following:
    SELECT Scott.My_funcs_pkg.My_func(10,20) FROM dual;"
    Any help would be appreciated.

    Thanks for the reply. I did see that before I posted and tried it also but here is what happens:
    create synonym Trjo_Exceed for UP_EXCEED@TestTrjo;
    select * from table(Trjo_Exceed.UF_GetOpenEvent('locationsexport'));
    ORA-00904: "TRJO_EXCEED"."UF_GETOPENEVENT": invalid identifier

  • Pipelined function running fast but making  the sp slow when used in it.

    i have a sp which is running slow because of (pipelined) function
    but function it self is fast.
    is there any remedy.
    select uno.a, uno.b, uno.c, uno1.c from
    abc a
    left join
    TABLE(udf_fn(a, 'h',b,c,d)) uno
                    ON a.a.a= uno.a
                   AND a.b= uno.b
                   AND a.c= uno.c
                   AND a.d= uno.d
    left join
    TABLE(udf_fn(a, 'j',b,c,d)) uno1
                    ON a.a.a= uno1.a
                   AND a.b= uno1.b
                   AND a.c= uno1.c
                   AND a.d= uno1.dyours sincerely
    Edited by: 944768 on Apr 30, 2013 11:56 PM
    Edited by: 944768 on May 1, 2013 2:01 AM

    Hi,
    Please read SQL and PL/SQL FAQ
    If you have a performance issue have a look at SQL and PL/SQL FAQ
    When you put some code or output please enclose it between two lines starting with {noformat}{noformat}
    i.e.:
    {noformat}{noformat}
    SELECT ...
    {noformat}{noformat}
    After 331 messages you should know how to post questions. Your code is unformatted and you did not provide the source of function udf_fn. How do you pretend us to answer?
    Regards.
    Al                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

  • Tabular forms based on pipelined functions - can it be done?

    Hi there,
    Pipelined functions are great, specially when you want to encapsulate the access to tables instead of just SELECTing from them (what I am doing a lot in my current project.)
    However Apex 4 does not like them, at least not for tabular forms...
    I want to handle myself the update/insert/delete process, so I don't need the MRU default functionality (all the access to the data is via APIs). But at the same time I want to just SELECT from my pipelined function and set the item types using the builder interface as with any tabular form (without having to use the apex_item API). Also I want to be able to use tabular form validation.
    To start with, you can only create a tabular form based on a table or view. To overcome this issue, I created a dummy view with the fields I wanted and created my tabular form on it. Then I changed the FROM clause to FROM TABLE(myfunction). It didn't work as it seems it tries to select the ROWID for each row... Of course my pipelined function doesn't return one but I don't need one anyway as I will be doing the data manipulation myself based on the PK.
    For this to work, I had to create a collection, populate it with the result of the pipelined function in a page process every time the page is loaded, create a view on that collection and base the tabular form on the view... A lot of work and overhead for something that should be very simple in principle.
    Then, I found out that if I remove the default MRU process that is automatically created, the tabular form validations stop working (as I posted in another thread). So I have to leave a "dummy" MRU process there with condition = never for it to work.
    The application I am working on is all based on API calls and pipelined functions so all this work has to be repeated for each tabular form that is needed.
    If it was possible to base a tabular form directly on a pipelined function it would be such an elegant solution.
    Is there a better way to implement this? Shouldn't Apex be more compatible with pipelined functions? (at least in regards to tabular forms, they work well with normal forms, reports, LOVs etc)
    Thanks
    Luis

    As I mentioned before, I don't handle inserts (well, I cheat).... On my page, there is a form to set up a request - prompts for a few things, and when submitted, calls a stored procedure:
    :P2_REQUEST_RESULT := Simon.Apex_Campus_Guest.Setup_Request(:P2_GROUP_NAME,
           :P2_COAS_ORGN, :P2_START_DATE, :P2_END_DATE, :P2_Quantity, :P2_Generic_Names);
    Which creates an APEX collection, which in turn is made visible via a pipelined function turned into a view:
    create or replace view Apex_Campus_Guest_Request_va as
    select seq_no,
            user_name,
           group_name,
            comments
      from table ( Apex_Campus_Guest.Request_Result )
    I have a second region which is tabular form on a query - conditional on select 1 from Simon.apex_campus_guest_request_va (the view defined above).
    When this submitted, I have standard MRU and MRD processes (Seq_No is the primary key). This then runs into the appropriate trigger - the update trigger is as follows:
    trigger Apex_Campus_Guest_Req_Upd
    instead of update on Apex_Campus_Guest_Request_va
    for each row
    declare
            cg_rec  campus_guest_maint.rec;
    begin
            cg_rec := Campus_Guest_Maint.Request(
                            name => :new.user_name,
                            group_name => :new.group_name,
                            comments => :new.comments);
    end;I don't know off hand why it isn't asking for a rowid - but may be that I specified a PKEY column. The insert case fails, as it tries to add a "Returning" statement in the original select. I actually find that annoying as a function is defined to allocate the PKEY from a sequence, so it doesn't need to ask for it that way.

  • Trouble using pipelined function in an select list lov query

    I'm trying to use a pipelined function in a select list lov query but i cet the error
    "LOV query is invalid, a display and a return value are needed, the column names need to be different. If your query contains an in-line query, the first FROM clause in the SQL statement must not belong to the in-line query."
    my query is as follows :
    SELECT gt.navn d, gt.GEOGRAPHY_TYPE_ID r
    FROM GEOGRAPHY_TYPE gt
    WHERE gt.kode NOT IN (1)
    and gt.kode in (select lov_value from table(RAPPORT_FILTER_PKG.GET_RAPPORT_FILTER_VALUE_PIP (
    SYS_CONTEXT ('rapport_filter_ctx','filter_id'),'GEOGRAPHY_TYPES')) )
    ORDER BY gt.navn DESC
    if i use a discrete values '80' instead of the call to
    SYS_CONTEXT ('rapport_filter_ctx','filter_id')
    i don't get eny errors, but then the LOV isn't as dynamic as i has to be
    any idears???
    Edited by: [email protected] on Dec 1, 2008 8:50 AM
    Edited by: [email protected] on Dec 1, 2008 11:17 AM

    nope that doesn't do it either
    contains a syntax errror at
    SYS_CONTEXT (('rapport_filter_ctx',:P500_RAPPORT_FILTER_ID),'GEOGRAPHY_TYPES'))
    my theory is that it's got something to do with the way APEX binds values because
    the query
    SELECT gt.navn d, gt.GEOGRAPHY_TYPE_ID r
    FROM GEOGRAPHY_TYPE gt
    WHERE gt.kode NOT IN (1)
    and gt.kode in (select r from table(RAPPORT_FILTER_PKG.GET_RAPPORT_FILTER_VALUE_PIP ('80','GEOGRAPHY_TYPES')) )
    ORDER BY gt.navn DESC
    works fine in both TOAD and in APEX but as soon as i replace th '80' with :P500_RAPPORT_FILTER_ID then, apex won't accept the code??????
    Edited by: [email protected] on Dec 3, 2008 7:54 AM

  • Use PipeLine function as datasource

    Hi all.
    Does anybody use PipeLine function as datasource for Bi EE ? Do you have any experience ?

    For more discuss :
    I was read article from Venkatakrishnan
    http://oraclebizint.wordpress.com/2007/09/21/oracle-bi-ee-101323-ref-cursors-and-pipelined-functions/
    and in that case all lok's fine and work. But in my case I was neded disable aggregate and order by functionality , becouse have some Issues. can anybody comment this situation :What's wrong in using PipeLine and BIee ?

  • Interactive Report using a View with a Pipelined Function

    Hello fellow Apex people,
    I'm Using Application Express 4.1.0.00.32
    I've got an interactive report that references a view (STOCK) and a pipelined function
    The basic query is listed below.
    SELECT S.CHANGED_TIME "Changed Time"
    , S.CHANGED_BY "Changed By"
    , S.ID "Id"
    , STKST_DESCRS.STOCK_STATUS_CODES "Stock Status Codes"
    , STKST_DESCRS.STOCK_STATUS_DESCRS "Stock Status"
    , S.ORIGINAL_CONTAINER "Original Container"
    FROM STOCK S
    , table(LWS_StkstStatus (S.ID)) STKST_DESCRS
    ORDER BY S.CO_ID,
    S.SEQUENCE_NUM;
    When the page is first run all the data is displayed correctly,
    If I define a filter, sort or a blank search the data from the pipelined function (STKST_DESCRS.) becomes null and isn't displayed.
    Does anyone know what is happening?
    Many Thanks

    I'm curious why you find this dangerous. I want a report that looks like this:
    Opportunity X:
    4 - 2-apr-2008 - Closed deal
    3 - 1-mar-2008 - Called Joe again
    2 - 12-feb-2008 - Called Joe
    1 - 14-jan-2008 - Initial call with customer.
    When you enter a new note, I want it to be numbered 5. The only problem I can imagine is someone deleting a note, which will almost never happen, and if it does, it just leaves a numbering gap. I don't see how using the function in a SELECT will accomplish this.

  • Pipelined function in reports6i....1

    Hi,
    i have a problem with using pipelined function in
    reports6i.
    can i use pipelined function in reports6i.
    The following code is used to return rows
    based on the parameter i am passing:
    my package declaration and body is as follows:
    PACKAGE P_RET_ARRAY IS
    TYPE array1 AS TABLE OF NUMBER;
    FUNCTION ret_array(str VARCHAR2)
    RETURN ARRAY1 PIPELINED;
    END;
    PACKAGE BODY P_RET_ARRAY IS
    FUNCTION ret_array(str VARCHAR2)
    RETURN ARRAY1 pipelined
    IS
    str1 VARCHAR2(100);
    num1 NUMBER(5);
    BEGIN
    str1 := str ||',';
    WHILE LENGTH(str1)>=0
    LOOP
    num1 := TO_NUMBER(SUBSTR(str1,1,INSTR(str1,',',1)-1));
    pipe (num1);
    str1 := SUBSTR(str1,INSTR(str1,',',1)+1);
    END LOOP;
    --NULL;
    RETURN ;
    END;
    END;
    I got the above piece of code from one of the oracle forums:
    now if i am trying to use this code in my reports6i it's not recognizing
    pipelined.any suggestions plz .
    it's urgent....

    Hi,
    i have a problem with using pipelined function in
    reports6i.
    can i use pipelined function in reports6i.
    The following code is used to return rows
    based on the parameter i am passing:
    my package declaration and body is as follows:
    PACKAGE P_RET_ARRAY IS
    TYPE array1 AS TABLE OF NUMBER;
    FUNCTION ret_array(str VARCHAR2)
    RETURN ARRAY1 PIPELINED;
    END;
    PACKAGE BODY P_RET_ARRAY IS
    FUNCTION ret_array(str VARCHAR2)
    RETURN ARRAY1 pipelined
    IS
    str1 VARCHAR2(100);
    num1 NUMBER(5);
    BEGIN
    str1 := str ||',';
    WHILE LENGTH(str1)>=0
    LOOP
    num1 := TO_NUMBER(SUBSTR(str1,1,INSTR(str1,',',1)-1));
    pipe (num1);
    str1 := SUBSTR(str1,INSTR(str1,',',1)+1);
    END LOOP;
    --NULL;
    RETURN ;
    END;
    END;
    I got the above piece of code from one of the oracle forums:
    now if i am trying to use this code in my reports6i it's not recognizing
    pipelined.any suggestions plz .
    it's urgent....

  • Pipelined function with lagre amount of data

    We would like to use pipelined functions as source of the select statements instead of tables. Thus we can easily switch from our tables to the structures with data from external module due to the need for integration with other systems.
    We know these functions are used in situations such as data warehousing to apply multiple transformations to data but what will be the performance in real time access.
    Does anyone have any experience using pipelined function with large amounts of data in the interface systems?

    It looks like you have already determined that the datatable object will be the best way to do this. When you are creating the object, you must enter the absolute path to your spreadsheet file. Then, you have to create some type of connection (i.e. a pushbutton or timer) that will send a true to the import data member of the datatable object. After these two things have been done, you will be able to access the data using the A3 - K133 data members.
    Regards,
    Michael Shasteen
    Applications Engineering
    National Instruments
    www.ni.com/ask
    1-866-ASK-MY-NI

Maybe you are looking for