Deploy resulset of PL\SQL function, that returns ANYTABLE%TYPE

How can deploy resulset of PL\SQL function, that returns ANYTABLE%TYPE in SQL?

<BLOCKQUOTE><font size="1" face="Verdana, Arial">quote:</font><HR>Originally posted by angelrip:
Hello everyone,
I've come through the following problem:
1.- I created an PL/SQL stored procedure which returns a REF CURSOR element, definition looks like this:
PACKAGE PKG_LISTADOS AS
TYPE tuplas IS REF CURSOR;
/* Procedimientos exportados por el paquete */
PROCEDURE inicializarModuloListados;
FUNCTION recaudacionUltimoMes(medioPago DEF_MEDIO_PAGO.MEDIO_PAGO%TYPE)
RETURN tuplas;
2.- Now I would like to call the stored procedure and retrieve the PL/SQL cursor as a ResultSet Java Object. The code I wrote is this:
Connection conn;
XmlDocument paramDef;
conn=poolMgr.getConnection str_poolDBConnection);
try
CallableStatement cstmt=conn.prepareCall("{?=call PKG_LISTADOS.recaudacionUltimoMes(?)}");
cstmt.registerOutParameter(1, java.sql.Types.OTHER);
cstmt.setString(2, "MONEDA");
cstmt.executeQuery();
ResultSet rs=(ResultSet)cstmt.getObject(1);
catch(SQLException sqlE)
3.- However, I can't make it OK, all the time I get the following error:
SQL Error(17004), java.sql.SQLException: Non valid column type
May anyone help me with this, thanks in advance:
Miguel-Angel<HR></BLOCKQUOTE>
Do something like the following:
cstmt = conn.prepareCall("{call customer_proc(?, ?)}");
//Set the first parameter
cstmt.setInt(1, 40);
//Register to get the Cursor parameter back from the procedure
cstmt.registerOutParameter(2, OracleTypes.CURSOR);
cstmt.execute();
ResultSet cursor = ((OracleCallableStatement)cstmt).getCursor(2);
while(cursor.next())
System.out.println("CUSTOMER NAME: " + cursor.getString(1));
System.out.println("CUSTOMER AGE: " + cursor.getInt(2));
cursor.close();
null

Similar Messages

  • EBS ISG using custom PL/SQL functions that return XMLType

    Hi,
    We have a custom PL/SQL package that we use for interfacing systems and some of the functions in this package ruturn an XMLType. We want to deploy the package functions as web services through the ISG, but it is not working as expected. When deployed through the ISG, the functions with XMLType return type produce a null response from the ISG (they work fine when called in SQL or PL/SQL; functions with non-XMLTypes work fine).
    If we change the return type to CLOB (and use getClobVal() on the XMLType) then we get a response from the ISG, but it changes all the angle-brackets in the CLOB (which is still arbitrary XML text) to &lt; &gt; ...
    What is the proper way to get the complex XMLType output through the ISG? Anyone have any more experience?
    Thanks,
    --Walt                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

    Alex,
    For the predicate groups that are indexed/stored, the exact operator types (as in equality, inequality, like etc) that are indexed are specified while assigning the default index parameters. In the following example, exf$indexoper is used to specify the list of indexed operators.
    BEGIN
      DBMS_EXPFIL.DEFAULT_INDEX_PARAMETERS('Car4Sale',
        exf$attribute_list (
           exf$attribute (attr_name => 'HorsePower(Model, Year)',
                          attr_oper => exf$indexoper('=','<','>','>=','<='),
                          attr_indexed => 'FALSE')    --- stored predicate group
    END;
    /You can find more information about exf$indexoper at
    http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28419/t_expfilobj.htm#ARPLS153
    Could you confirm that you chose to index 'is null' and 'is not null' while assigning the default index parameters ? This information is available in OPERATOR_LIST column of the USER_EXPFIL_DEF_INDEX_PARAMS view.
    Hope this helps,
    -Aravind.

  • Stored PL/SQL function that returns REF CURSOR type

    Hello everyone,
    I've come through the following problem:
    1.- I created an PL/SQL stored procedure which returns a REF CURSOR element, definition looks like this:
    PACKAGE PKG_LISTADOS AS
    TYPE tuplas IS REF CURSOR;
    /* Procedimientos exportados por el paquete */
    PROCEDURE inicializarModuloListados;
    FUNCTION recaudacionUltimoMes(medioPago DEF_MEDIO_PAGO.MEDIO_PAGO%TYPE)
    RETURN tuplas;
    2.- Now I would like to call the stored procedure and retrieve the PL/SQL cursor as a ResultSet Java Object. The code I wrote is this:
    Connection conn;
    XmlDocument paramDef;
    conn=poolMgr.getConnection str_poolDBConnection);
    try
    CallableStatement cstmt=conn.prepareCall("{?=call PKG_LISTADOS.recaudacionUltimoMes(?)}");
    cstmt.registerOutParameter(1, java.sql.Types.OTHER);
    cstmt.setString(2, "MONEDA");
    cstmt.executeQuery();
    ResultSet rs=(ResultSet)cstmt.getObject(1);
    catch(SQLException sqlE)
    3.- However, I can't make it OK, all the time I get the following error:
    SQL Error(17004), java.sql.SQLException: Non valid column type
    May anyone help me with this, thanks in advance:
    Miguel-Angel

    <BLOCKQUOTE><font size="1" face="Verdana, Arial">quote:</font><HR>Originally posted by angelrip:
    Hello everyone,
    I've come through the following problem:
    1.- I created an PL/SQL stored procedure which returns a REF CURSOR element, definition looks like this:
    PACKAGE PKG_LISTADOS AS
    TYPE tuplas IS REF CURSOR;
    /* Procedimientos exportados por el paquete */
    PROCEDURE inicializarModuloListados;
    FUNCTION recaudacionUltimoMes(medioPago DEF_MEDIO_PAGO.MEDIO_PAGO%TYPE)
    RETURN tuplas;
    2.- Now I would like to call the stored procedure and retrieve the PL/SQL cursor as a ResultSet Java Object. The code I wrote is this:
    Connection conn;
    XmlDocument paramDef;
    conn=poolMgr.getConnection str_poolDBConnection);
    try
    CallableStatement cstmt=conn.prepareCall("{?=call PKG_LISTADOS.recaudacionUltimoMes(?)}");
    cstmt.registerOutParameter(1, java.sql.Types.OTHER);
    cstmt.setString(2, "MONEDA");
    cstmt.executeQuery();
    ResultSet rs=(ResultSet)cstmt.getObject(1);
    catch(SQLException sqlE)
    3.- However, I can't make it OK, all the time I get the following error:
    SQL Error(17004), java.sql.SQLException: Non valid column type
    May anyone help me with this, thanks in advance:
    Miguel-Angel<HR></BLOCKQUOTE>
    Do something like the following:
    cstmt = conn.prepareCall("{call customer_proc(?, ?)}");
    //Set the first parameter
    cstmt.setInt(1, 40);
    //Register to get the Cursor parameter back from the procedure
    cstmt.registerOutParameter(2, OracleTypes.CURSOR);
    cstmt.execute();
    ResultSet cursor = ((OracleCallableStatement)cstmt).getCursor(2);
    while(cursor.next())
    System.out.println("CUSTOMER NAME: " + cursor.getString(1));
    System.out.println("CUSTOMER AGE: " + cursor.getInt(2));
    cursor.close();
    null

  • Subquery not allowed - PL/SQL Function Body returning bolean

    Is subquery is not allowed in PL/SQL Expresion.????
    I am using the following query in one of my derived report column but I am getting the error.
    BEGIN
    if :COL1<>'abc' and :COL2 in (select deptno from dept1) then
    return 1;
    elsif :COL1<>'abc' and :COL2 in (select deptno from dept2) then
    return 0;
    elsif :COL1<>'abc' and :COL2 in (select deptno from dept3) then
    return 1;
    else
    return 0;
    end if;
    END;
    secondly CAN I use return value such as 'ABC' or 'XYZ' other than 0,1.
    Error-
    Invalid function body condition: ORA-06550: line 4, column 8: PLS-00405: subquery not allowed in this context ORA-06550: line 2, column 3: PL/SQL: Statement ignored
    -----------------

    Hi Deepak,
    There are at least methods.
    1 - You could create a SQL function that returned 0 or 1 and use that in your statement
    2 - You could use a CASE clause in the SQL statement
    As I don't have your dept1/2/3 tables, I've tried the following on the sample EMP/DEPT tables:
    SELECT EMPNO,
    ENAME,
    SAL,
    COMM,
    DEPTNO,
    CASE WHEN DEPTNO IN (SELECT DEPTNO FROM DEPT) THEN
      CASE WHEN ENAME LIKE '%A%' THEN NVL(SAL,0) + NVL(COMM,0) ELSE 456 END
    ELSE
       CASE WHEN DEPTNO NOT IN (SELECT DEPTNO FROM DEPT) THEN
         CASE WHEN ENAME LIKE '%A%' THEN NVL(SAL,0) + NVL(COMM,0) ELSE 123 END
       ELSE
         789
       END
    END "TOTAL"
    FROM EMPThis returns the values I expect:
    EMPNO     ENAME     SAL     COMM     DEPTNO     TOTAL
    7936     ATD     3000     -      40     3000
    7958     dino4     -      -      -      789
    7839     KINGS     5000     -      40     456
    7698     BLAKES     2850     -      30     2850
    7782     CLARK     2450     -      10     2450
    7566     JONES     2975     -      30     456
    7788     SCOTT     3000     -      20     456
    7902     FORD     3000     -      40     456
    7369     SMITH     800     -      20     456
    7499     ALLEN     1600     300     30     1900Obviously, you may have to experiment with the various CASE statements, but it will work using just a sql select statement.
    Andy

  • Migrating Functions that return TABLE from SQL Server to Oracle

    I have some functions in SQL Server that return a TABLE datatype. When these functions are moved to Oracle 9i using Migration Workbench, they give compilation errors. In the migrated function it says that the DDL stmt is passed to the ddl file, but the table is not created. I checked the ddl stmt for temporary tables and it is wrong. Its a create table stmt with no size for varchars and we can't even edit these stmts in the workbench.
    Also the migrated function has the table name for return type, which doesn't works in Oracle. Oracle needs a datatype to be returned from Oracle.
    How do we return a table from a function?

    Yes.
    If you do not enclose the object names (table/view/index etc) in double-quotes, they are stored in uppercase format in the data dictionary.
    If you enclose them in quotes, they are stored in the same case ans you entered. As such, while accessing such objects, you need to tell Oracle not to convert the names to uppercase, hence the requirement to supply the names in quotes.

  • PL/SQL function body returning SQL - report error:ORA-01403: no data found

    Hi,
    I am working on Application Express 4.0.2.00.06, and 11G database.
    I have a problem with classic report area of type - PL/SQL function body returning SQL query. Query works if I define region area as - Use Generic Column Names (parse query at runtime only), and does not when I define it - Use Query-Specific Column Names and Validate Query.
    I am getting error:
    report error:ORA-01403: no data found
    This is my query that is returned from function, and displayed with htp.p, and it works ok and returns data in SQL Developer and SQL Workshop (in Apex).
    <code>
    /* select 1 from dual */ SELECT SIFPRO, NAZIV, VODITELJ, DATPZA,SUM(DECODE(TJEDAN,'2010/46',BRDJEL,null)) as "2010/46" ,SUM(DECODE(TJEDAN,'2010/49',BRDJEL,null)) as "2010/49" ,SUM(DECODE(TJEDAN,'2010/50',BRDJEL,null)) as "2010/50" ,SUM(DECODE(TJEDAN,'2010/51',BRDJEL,null)) as "2010/51" ,SUM(DECODE(TJEDAN,'2010/52',BRDJEL,null)) as "2010/52" ,SUM(DECODE(TJEDAN,'2011/01',BRDJEL,null)) as "2011/01" ,SUM(DECODE(TJEDAN,'2011/02',BRDJEL,null)) as "2011/02" ,SUM(DECODE(TJEDAN,'2011/03',BRDJEL,null)) as "2011/03" ,SUM(DECODE(TJEDAN,'2011/04',BRDJEL,null)) as "2011/04" ,SUM(DECODE(TJEDAN,'2011/05',BRDJEL,null)) as "2011/05" ,SUM(DECODE(TJEDAN,'2011/06',BRDJEL,null)) as "2011/06" ,SUM(DECODE(TJEDAN,'2011/07',BRDJEL,null)) as "2011/07" ,SUM(DECODE(TJEDAN,'2011/08',BRDJEL,null)) as "2011/08" ,SUM(DECODE(TJEDAN,'2011/09',BRDJEL,null)) as "2011/09" ,SUM(DECODE(TJEDAN,'2011/10',BRDJEL,null)) as "2011/10" FROM (SELECT * FROM PMV_PLAN_TVRTKA) GROUP BY SIFPRO, NAZIV, VODITELJ, DATPZA ORDER BY SIFPRO, NAZIV, VODITELJ, DATPZA
    </code>
    As you can see, I even tried with workaround that I found on the previous post on the forum, and that is to put /* select 1 from dual */ to start query.
    Any help would be appriciated.

    /* select 1 from dual */ SELECT SIFPRO, NAZIV, VODITELJ, DATPZA,SUM(DECODE(TJEDAN,'2010/46',BRDJEL,null)) as "2010/46" ,SUM(DECODE(TJEDAN,'2010/49',BRDJEL,null)) as "2010/49" ,SUM(DECODE(TJEDAN,'2010/50',BRDJEL,null)) as "2010/50" ,SUM(DECODE(TJEDAN,'2010/51',BRDJEL,null)) as "2010/51" ,SUM(DECODE(TJEDAN,'2010/52',BRDJEL,null)) as "2010/52" ,SUM(DECODE(TJEDAN,'2011/01',BRDJEL,null)) as "2011/01" ,SUM(DECODE(TJEDAN,'2011/02',BRDJEL,null)) as "2011/02" ,SUM(DECODE(TJEDAN,'2011/03',BRDJEL,null)) as "2011/03" ,SUM(DECODE(TJEDAN,'2011/04',BRDJEL,null)) as "2011/04" ,SUM(DECODE(TJEDAN,'2011/05',BRDJEL,null)) as "2011/05" ,SUM(DECODE(TJEDAN,'2011/06',BRDJEL,null)) as "2011/06" ,SUM(DECODE(TJEDAN,'2011/07',BRDJEL,null)) as "2011/07" ,SUM(DECODE(TJEDAN,'2011/08',BRDJEL,null)) as "2011/08" ,SUM(DECODE(TJEDAN,'2011/09',BRDJEL,null)) as "2011/09" ,SUM(DECODE(TJEDAN,'2011/10',BRDJEL,null)) as "2011/10" FROM (SELECT * FROM PMV_PLAN_TVRTKA) GROUP BY SIFPRO, NAZIV, VODITELJ, DATPZA ORDER BY SIFPRO, NAZIV, VODITELJ, DATPZA

  • PL/SQL function body returning SQL query - ORA-06502: PL/SQL: numeric or value error

    I'm attempting to dynamically generate a rather large SQL query via the "PL/SQL function body returning SQL query" report region option.  The SQL query generated will possibly be over 32K.  When I execute my page, I sometimes receive the "ORA-06502: PL/SQL: numeric or value error" which points to a larger than 32K query that was generated.  I've seen other posts in the forum related to this dynamic SQL size limitation issue, but they are older (pre-2010) and point to the 32K limit of the DNS (EXECUTE IMMEDIATE) and DBMS_SQL.  I found this post (dynamic sql enhancements in 11g) which discusses 11g no longer having the 32K size limitation for generating dynamic SQL.  Our environment is on 11gR2 and using ApEx 4.2.1.  I do not know which dynamic SQL method -- DNS or DBMS_SQL -- ApEx 4.2.1 is using.  Can someone clarify for me which dynamic SQL method ApEx uses to implement the "PL/SQL function body returning SQL query" option?
    As a test, I created a page on apex.oracle.com with a report region with the following source:
    declare
      l_stub varchar2(25) := 'select * from sys.dual ';
      l_sql  clob := l_stub || 'union all ';
      br     number(3) := 33;
    begin
      while length ( l_sql ) < 34000 loop
        l_sql := l_sql || l_stub || 'union all ';
      end loop;
      l_sql := l_sql || l_stub;
      for i in 1 .. ceil ( length ( l_sql ) / br ) loop
        dbms_output.put_line ( dbms_lob.substr ( l_sql, br, ( ( i - 1 ) * br ) + 1 ) );
      end loop;
      return l_sql;
    end;
    The dbms_output section is there to be able to run this code in SQL*Plus and confirm the size of the SQL is indeed larger than 32K.  When running this in SQL*Plus, the procedure is successful and produces a proper SQL statement which can be executed.  When I put this into the report region on apex.oracle.com, I get the ORA-06502 error.
    I can certainly implement a work-around for my issue by creating a 'Before Header' process on the page which populates an ApEx collection with the data I am returning and then the report can simply select from the collection, but according to documentation, the above 32K limitation should be resolved in 11g.  Thoughts?
    Shane.

    What setting do you use in your report properties - especially in Type and in Region Source?
    If you have Type="SQL Query", then you should have a SELECT statement in the Region Source. Something like: SELECT .... FROM ... WHERE
    According to the ERR-1101 error message, you have probably set Type to "SQL Query (PL/SQL function body returning SQL query)". In this situation APEX expects you to write a body of a PL/SQL function, that will generate the text of a SQL query that APEX should run. So it can be something like:
    declare
    mycond varchar2(4000);
    begin
    if :P1_REPORT_SEARCH is not null THEN
    mycond:='WHERE LAST_NAME like :P1_REPORT_SEARCH ||''%''';
    end if;
    return 'select EMPLOYEE_ID, FIRST_NAME, LAST_NAME from EMPLOYEES ' ||mycond;
    end;
    And for escaping - are you interested in escaping the LIKE wildcards, or the quotes?
    For escaping the wildcards in LIKE function so that when the user enters % you will find a record with % and not all functions, look into the SQL Reference:
    http://download-uk.oracle.com/docs/cd/B19306_01/server.102/b14200/conditions007.htm
    (You would than need to change the code of your function accordingly).
    If you are interested in escaping the quotes, try to avoid concatenating the values entered by the user into the SQL. If you can, use bind variables instead - as I have in my example above. If you start concatenating the values into the text of SQL, you are open to SQLInjection - user can enter anything, even things that will break your SQL. If you really need to allow users to choose the operator, I would probably give them a separate combo for operators and a textfield for values, than you could check if the operator is one of the allowed ones and create the condition accordingly - and than still use bind variable for inserting the filtering value into the query.

  • How to use a select list value in a PL/SQL function body returning SQLquery

    Hi Friends,
    I have a select list P6_TEST with values 'nav' anf 'jyo'. I am trying to create a report using "SQL Query (PL/SQL
    function body returning SQL query)". In my report query can i check if P6_TEST='nav' and do something like the
    code shown below.How can i do that.
    DECLARE
    v_sql VARCHAR2(3000);
    BEGIN
    IF :P6_TEST = 'nav' THEN
    v_sql :=
    'SELECT
    * from department';
    ........................Thanks,
    Nav

    Nav:
    What you have should work. Give it a go. Post back if you run into issues.
    Varad

  • Region source (PL/SQL function body returning SQL query)

    Hi, guys.
    Here is what i try to do:
    Create a region of type SQL Query (PL/SQL function body returning SQL query). In the source area i tried to put this:
    DECLARE
    v_new VARCHAR2(10);
    v_SQL varchar2(32000);
    BEGIN
    v_new := :P102_HDN_NEW;
    -- htp.p(v_new);
    IF v_new = 'N-Set' THEN
    v_SQL := 'select ' ||
    ELSIF v_new = 'Y-Set' THEN
    v_SQL := 'select ' ||
    END IF;
    RETURN v_SQL;
    END;
    And here is the reply from APEX:
    1 error has occurred
    Query cannot be parsed within the Builder. If you believe your query is syntactically correct, check the ''generic columns'' checkbox below the region source to proceed without parsing. The query can not be parsed, the cursor is not yet open or a function returning a SQL query returned without a value.
    Now.
    1. Variable is set with the right value.
    2. Each statement (separately) returns SQL that works with no problems
    3. Problem occures if i try to put IF statement around the SQL creation.
    4. If i select "Use Generic Column Names (parse query at runtime only)" instead of "Use Query-Specific Column Names and Validate Query" then the script returns SQL properly, however report's column names are set to Col1, Col2,Col3 ......
    Thnks in advence
    Mike

    OK. Here is enire statement:
    DECLARE
    v_new VARCHAR2(10);
    v_SQL varchar2(32000);
    BEGIN
    v_new := :P102_HDN_NEW;
    htp.p(v_new);
    IF v_new = 'N-Set' THEN
    v_SQL := 'select ' ||
    'APEX_ITEM.DISPLAY_AND_SAVE(10,c.sdescr) descr, ' ||
    'APEX_ITEM.DISPLAY_AND_SAVE(12,DECODE(ld.level,''All'', ''All Categories'',ld.level)) level, ' ||
    'apex_item.checkbox(1, ld.opt_in_auto_flag, decode(ld.opt_in_auto_flag,NULL,''disabled'',''Y'',''checked'')) auto_in, ' ||
    'apex_item.checkbox(2, ld.opt_in_manual_flag, decode(ld.opt_in_manual_flag,NULL,''disabled'',''Y'',''checked'')) manual_in, ' ||
    'apex_item.checkbox(3, ld.opt_out_auto_flag, decode(ld.opt_out_auto_flag,NULL,''disabled'',''Y'',''checked'')) auto_out, ' ||
    'apex_item.checkbox(4, ld.opt_out_manual_flag, decode(ld.opt_out_manual_flag,NULL,''disabled'',''Y'',''checked'')) manual_out, ' ||
    'DECODE(c.code, ''NMBR'', NULL,''Change to '' || DECODE(ld.level,''All'',''Categories'',''All Categories'')) link_change, ' ||
    'APEX_ITEM.DISPLAY_AND_SAVE(11,c.code) code ' ||
    'from ' ||
    'tbl1 c, ' ||
    'tbl2 ld ' ||
    'where c.code = ld.code ' ||
    'and c.type = ''TYPE1'' ' ||
    'and c.active = ''Y'' ' ||
    'order by c.sorting ';
    ELSIF v_new = 'Y-Set' THEN
    v_SQL := 'select ' ||
    'APEX_ITEM.DISPLAY_AND_SAVE(10,c.sdescr) descr, ' ||
    'APEX_ITEM.DISPLAY_AND_SAVE(12,''All Categories'') level, ' ||
    'apex_item.checkbox(1, c.option_1, decode(c.option_1,NULL,''disabled'',''Y'',''checked'')) auto_in, ' ||
    'apex_item.checkbox(2, c.option_3, decode(c.option_3,NULL,''disabled'',''Y'',''checked'')) manual_in, ' ||
    'apex_item.checkbox(3, c.option_2, decode(c.option_2,NULL,''disabled'',''Y'',''checked'')) auto_out, ' ||
    'apex_item.checkbox(4, c.option_4, decode(c.option_4,NULL,''disabled'',''Y'',''checked'')) manual_out, ' ||
    'DECODE(c.code, ''AAA'', NULL,''Options by AAA'') link_change, ' ||
    'APEX_ITEM.DISPLAY_AND_SAVE(11,c.code) code ' ||
    'from ' ||
    'tbl1 c ' ||
    'where 1 = 1 ' ||
    'and c.type = ''TYPE1'' ' ||
    'and c.active = ''Y'' ' ||
    'order by c.sorting ';
    END IF;
    RETURN v_SQL;
    END;
    If i put just this
    DECLARE
    v_new VARCHAR2(10);
    v_SQL varchar2(32000);
    BEGIN
    v_new := :P102_HDN_NEW;
    htp.p(v_new);
    v_SQL := 'select ' ||
    'APEX_ITEM.DISPLAY_AND_SAVE(10,c.sdescr) descr, ' ||
    'APEX_ITEM.DISPLAY_AND_SAVE(12,DECODE(ld.level,''All'', ''All Categories'',ld.level)) level, ' ||
    'apex_item.checkbox(1, ld.opt_in_auto_flag, decode(ld.opt_in_auto_flag,NULL,''disabled'',''Y'',''checked'')) auto_in, ' ||
    'apex_item.checkbox(2, ld.opt_in_manual_flag, decode(ld.opt_in_manual_flag,NULL,''disabled'',''Y'',''checked'')) manual_in, ' ||
    'apex_item.checkbox(3, ld.opt_out_auto_flag, decode(ld.opt_out_auto_flag,NULL,''disabled'',''Y'',''checked'')) auto_out, ' ||
    'apex_item.checkbox(4, ld.opt_out_manual_flag, decode(ld.opt_out_manual_flag,NULL,''disabled'',''Y'',''checked'')) manual_out, ' ||
    'DECODE(c.code, ''NMBR'', NULL,''Change to '' || DECODE(ld.level,''All'',''Categories'',''All Categories'')) link_change, ' ||
    'APEX_ITEM.DISPLAY_AND_SAVE(11,c.code) code ' ||
    'from ' ||
    'tbl1 c, ' ||
    'tbl2 ld ' ||
    'where c.code = ld.code ' ||
    'and c.type = ''TYPE1'' ' ||
    'and c.active = ''Y'' ' ||
    'order by c.sorting ';
    RETURN v_SQL;
    END;
    it works fune...

  • Multiple Select List looping thru PL/SQL function body returning SQL query

    Hi,
    I have a Multiple Select List. I want to loop through the values from the Select List and process them in a PL/SQL function body returning a SQL query. Currently, my code only returns the SQL SELECT results of one item in the select list. How do I change my code to make it return the results of all of the items in the select list? (I tested it and it is definitely picking up all the values in the select list).
    <b>
    DECLARE
    selected_items HTMLDB_APPLICATION_GLOBAL.VC_ARR2;
    s   VARCHAR2(20);
    q varchar2(32767);
    BEGIN
    selected_items := HTMLDB_UTIL.STRING_TO_TABLE(:P50_SELECTED_INSTRUMENTS);
    -- htp.p('COUNT: '||selected_items.count);
      FOR i in 1..selected_items.count LOOP
      s := TO_CHAR(selected_items(i));
    -- htp.p('First: '||s);
    -- htp.p('Second: '||:s);
    -- htp.p('Third: '||TO_CHAR(selected_items(i)));
      q:= 'SELECT  '||
    'SUBSTR(orig_geo_loc_sys,1,INSTR(orig_geo_loc_sys,''-'')-1) AS INSTRUMENT, '||
    'SUBSTR(orig_geo_loc_sys,INSTR(orig_geo_loc_sys,''-'')+1, LENGTH'||
    ' (orig_geo_loc_sys)) AS ORIG_LINENUM, '||
    'sum(orig_intrl) orig_intrl, '||
    'sum(orig_extrl) orig_extrl, '||
    'sum(recv_intrl) recv_intrl, '||
    'sum(recv_extrl) recv_extrl '||
    'FROM line_usage_sum_view '||
    'WHERE TO_CHAR(orig_geo_loc_sys) LIKE ''' || s ||'%'' '||
    --'WHERE TO_CHAR(orig_geo_loc_sys) LIKE ''2213003%'' '||
    'AND switch_id = ''' || :P1_SWITCH_ID || ''' ' ||
    'AND call_start_date > TO_DATE(''30-NOV-1999'') ' ||
    'AND call_clear_time > TO_DATE(''30-NOV-1999'') '||
    'AND '||
    :SORTFIELD||' BETWEEN '||
    'TO_DATE(:STARTDATE,''dd-MON-YYYY HH24:MI'') AND '||
    'TO_DATE(:STOPDATE, ''dd-MON-YYYY HH24:MI'') '||
    'GROUP BY GROUPING SETS (orig_geo_loc_sys)';
    -- htp.p('SQL query: '||q);
      RETURN q;
      END LOOP;
    END;</b>
    Thank you,
    Laura

    Laura,
    First, I would be careful of introducing SQL Injection possibilities. Any time I see
    'Select ... ' || :P123_FOO || ' ... '
    I worry about sql injection. In your case you are converting :P50_SELECTED_INSTRUMENTS into selected_items and then selected_items into s. So when I see
    'WHERE TO_CHAR(orig_geo_loc_sys) LIKE ''' || s ||'%'' '||
    I think, "I could use sql Injection and hack this."
    So, I would do some validation on :P50_SELECTED_INSTRUMENTS or some other method to avoid this.
    I'm not certain I understand your query. Do you really intend to allow the user to select the beginning of a string and then find all rows that start with that string? Or, do you just want to let them find when it matches the string. This is one way if you want to do matching:
    DECLARE
    selected_items HTMLDB_APPLICATION_GLOBAL.VC_ARR2;
    s VARCHAR2(32767);
    q varchar2(32767);
    BEGIN
    -- Change the : separate string to be comma separated with quoted strings
    s := '''' || replace(:P50_SELECTED_INSTRUMENTS, ',', ''',''')|| '''' ;
    -- htp.p('COUNT: '||selected_items.count);
    q:= 'SELECT '||
    'SUBSTR(orig_geo_loc_sys,1,INSTR(orig_geo_loc_sys,''-'')-1) AS INSTRUMENT, '||
    'SUBSTR(orig_geo_loc_sys,INSTR(orig_geo_loc_sys,''-'')+1, LENGTH'||
    ' (orig_geo_loc_sys)) AS ORIG_LINENUM, '||
    'sum(orig_intrl) orig_intrl, '||
    'sum(orig_extrl) orig_extrl, '||
    'sum(recv_intrl) recv_intrl, '||
    'sum(recv_extrl) recv_extrl '||
    'FROM line_usage_sum_view '||
    'WHERE TO_CHAR(orig_geo_loc_sys) in (' || s ||' ) '||
    --'WHERE TO_CHAR(orig_geo_loc_sys) LIKE ''2213003%'' '||
    'AND switch_id = ''' || :P1_SWITCH_ID || ''' ' ||
    'AND call_start_date > TO_DATE(''30-NOV-1999'') ' ||
    'AND call_clear_time > TO_DATE(''30-NOV-1999'') '||
    'AND '||
    :SORTFIELD||' BETWEEN '||
    'TO_DATE(:STARTDATE,''dd-MON-YYYY HH24:MI'') AND '||
    'TO_DATE(:STOPDATE, ''dd-MON-YYYY HH24:MI'') '||
    'GROUP BY GROUPING SETS (orig_geo_loc_sys)';
    -- htp.p('SQL query: '||q);
    RETURN q;
    END;
    If you want to do something more like you originally stated, try this:
    DECLARE
    selected_items HTMLDB_APPLICATION_GLOBAL.VC_ARR2;
    s VARCHAR2(20);
    q varchar2(32767);
    BEGIN
    selected_items := HTMLDB_UTIL.STRING_TO_TABLE(:P50_SELECTED_INSTRUMENTS);
    -- htp.p('COUNT: '||selected_items.count);
    q:= 'SELECT '||
    'SUBSTR(orig_geo_loc_sys,1,INSTR(orig_geo_loc_sys,''-'')-1) AS INSTRUMENT, '||
    'SUBSTR(orig_geo_loc_sys,INSTR(orig_geo_loc_sys,''-'')+1, LENGTH'||
    ' (orig_geo_loc_sys)) AS ORIG_LINENUM, '||
    'sum(orig_intrl) orig_intrl, '||
    'sum(orig_extrl) orig_extrl, '||
    'sum(recv_intrl) recv_intrl, '||
    'sum(recv_extrl) recv_extrl '||
    'FROM line_usage_sum_view '||
    'WHERE 1=1 ';
    FOR i in 1..selected_items.count LOOP
    s := TO_CHAR(selected_items(i));
    q := q || ' and TO_CHAR(orig_geo_loc_sys) LIKE '''|| s ||'%'' ' ;
    END LOOP;
    q := q || ||'%'' '||
    --'WHERE TO_CHAR(orig_geo_loc_sys) LIKE ''2213003%'' '||
    'AND switch_id = ''' || :P1_SWITCH_ID || ''' ' ||
    'AND call_start_date > TO_DATE(''30-NOV-1999'') ' ||
    'AND call_clear_time > TO_DATE(''30-NOV-1999'') '||
    'AND '||
    :SORTFIELD||' BETWEEN '||
    'TO_DATE(:STARTDATE,''dd-MON-YYYY HH24:MI'') AND '||
    'TO_DATE(:STOPDATE, ''dd-MON-YYYY HH24:MI'') '||
    'GROUP BY GROUPING SETS (orig_geo_loc_sys)';
    -- htp.p('SQL query: '||q);
    RETURN q;
    END;
    Hope this helps...
    Anton

  • SOLVED: How can I use or call a function that returns %ROWTYPE?

    Hi
    edit: you can probably skip all this guff and go straight to the bottom...In the end this is probably just a question of how to use a function that returns a %rowtype.  Thanks.
    Currently reading Feuerstein's tome, 5th ed. I've downloaded and run the file genaa.sp, which is a code generator. Specifically, you feed it a table name and it generates code (package header and package body) that will create a cache of the specified table's contents.
    So, I ran:
    HR@XE> @"C:\Documents and Settings\Jason\My Documents\Work\SQL\OPP5.WEB.CODE\OPP5.WEB.CODE\genaa.sp"
    749  /
    Procedure created.
    HR@XE> exec genaa('EMPLOYEES');which generated a nice bunch of code, viz:
    create or replace package EMPLOYEES_cache is
        function onerow ( EMPLOYEE_ID_in IN HR.EMPLOYEES.EMPLOYEE_ID%TYPE) return HR.EMPLOYEES%ROWTYPE;
        function onerow_by_EMP_EMAIL_UK (EMAIL_in IN HR.EMPLOYEES.EMAIL%TYPE) return HR.EMPLOYEES%ROWTYPE;
        procedure test;
    end EMPLOYEES_cache;
    create or replace package body EMPLOYEES_cache is
        TYPE EMPLOYEES_aat IS TABLE OF HR.EMPLOYEES%ROWTYPE INDEX BY PLS_INTEGER;
        EMP_EMP_ID_PK_aa EMPLOYEES_aat;
        TYPE EMP_EMAIL_UK_aat IS TABLE OF HR.EMPLOYEES.EMPLOYEE_ID%TYPE INDEX BY HR.EMPLOYEES.EMAIL%TYPE;
        EMP_EMAIL_UK_aa EMP_EMAIL_UK_aat;
        function onerow ( EMPLOYEE_ID_in IN HR.EMPLOYEES.EMPLOYEE_ID%TYPE)
            return HR.EMPLOYEES%ROWTYPE is
            begin
                return EMP_EMP_ID_PK_aa (EMPLOYEE_ID_in);
            end;
        function onerow_by_EMP_EMAIL_UK (EMAIL_in IN HR.EMPLOYEES.EMAIL%TYPE)
            return HR.EMPLOYEES%ROWTYPE is
            begin
                return EMP_EMP_ID_PK_aa (EMP_EMAIL_UK_aa (EMAIL_in));
            end;
        procedure load_arrays is
            begin
                FOR rec IN (SELECT * FROM HR.EMPLOYEES)
                LOOP
                    EMP_EMP_ID_PK_aa(rec.EMPLOYEE_ID) := rec;
                    EMP_EMAIL_UK_aa(rec.EMAIL) := rec.EMPLOYEE_ID;
                end loop;
            END load_arrays;
        procedure test is
            pky_rec HR.EMPLOYEES%ROWTYPE;
            EMP_EMAIL_UK_aa_rec HR.EMPLOYEES%ROWTYPE;
            begin
                for rec in (select * from HR.EMPLOYEES) loop
                    pky_rec := onerow (rec.EMPLOYEE_ID);
                    EMP_EMAIL_UK_aa_rec := onerow_by_EMP_EMAIL_UK (rec.EMAIL);
                    if rec.EMPLOYEE_ID = EMP_EMAIL_UK_aa_rec.EMPLOYEE_ID then
                        dbms_output.put_line ('EMP_EMAIL_UK  lookup OK');
                    else
                        dbms_output.put_line ('EMP_EMAIL_UK  lookup NOT OK');
                    end if;
                end loop;
            end test;
        BEGIN
            load_arrays;
        end EMPLOYEES_cache;
    /which I have run successfully:
    HR@XE> @"C:\Documents and Settings\Jason\My Documents\Work\SQL\EMPLOYEES_CACHE.sql"
    Package created.
    Package body created.I am now trying to use the functionality within the package.
    I have figured out that the section
        BEGIN
            load_arrays;
        end EMPLOYEES_cache;
    /is the initialization section, and my understanding is that this is supposed to run when any of the package variables or functions are referenced. Is that correct?
    With that in mind, I'm trying to call the onerow() function, but it's not working:
    HR@XE> select onerow(100) from dual;
    select onerow(100) from dual
    ERROR at line 1:
    ORA-00904: "ONEROW": invalid identifier
    HR@XE> select employees_cache.onerow(100) from dual;
    select employees_cache.onerow(100) from dual
    ERROR at line 1:
    ORA-06553: PLS-801: internal error [55018]
    HR@XE> select table(employees_cache.onerow(100)) from dual;
    select table(employees_cache.onerow(100)) from dual
    ERROR at line 1:
    ORA-00936: missing expressionHe provides the code genaa.sp, and a very brief description of what it does, but doesn't tell us how to run the generated code!
    Now, I have just done some googling, and it seems that what I am trying to do isn't possible. Apparently %ROWTYPE is PL/SQL, and not understood by SQL, so you can't call onerow() from sql. Correct?
    So I try wrapping the call in an exec:
    HR@XE> exec select employees_cache.onerow(100) from dual;
    BEGIN select employees_cache.onerow(100) from dual; END;
    ERROR at line 1:
    ORA-06550: line 1, column 30:
    PLS-00382: expression is of wrong type
    ORA-06550: line 1, column 7:
    PLS-00428: an INTO clause is expected in this SELECT statement
    HR@XE> exec select table(employees_cache.onerow(100)) from dual;
    BEGIN select table(employees_cache.onerow(100)) from dual; END;
    ERROR at line 1:
    ORA-06550: line 1, column 14:
    PL/SQL: ORA-00936: missing expression
    ORA-06550: line 1, column 7:
    PL/SQL: SQL Statement ignored
    HR@XE> exec employees_cache.onerow(100)
    BEGIN employees_cache.onerow(100); END;
    ERROR at line 1:
    ORA-06550: line 1, column 7:
    PLS-00221: 'ONEROW' is not a procedure or is undefined
    ORA-06550: line 1, column 7:
    PL/SQL: Statement ignoredNo joy.
    Of course, now that I'm looking at it again, it seems that the way to go is indicated by the first error:
    PLS-00428: an INTO clause is expected in this SELECT statement
    So am I supposed to create a type of EMPLOYEES%ROWTYPE in a PL/SQL procedure, and the idea of this code, is that the first call to onerow() runs the initialiation code, which populates the cache, and all subsequent calls to onerow() (whether by my session or any other) will use the cache?
    I've had a stab at this, but still, no joy:
    create or replace procedure testcache is
        emp employees%rowtype;
        begin
            select employees_cache.onerow(100) from dual into emp;
            dbms_output.put_line('Emp id: ' || emp.employee_id);
        end testcache;
    show errors
    HR@XE> @testcache.sql
    Warning: Procedure created with compilation errors.
    Errors for PROCEDURE TESTCACHE:
    LINE/COL ERROR
    4/9      PL/SQL: SQL Statement ignored
    4/54     PL/SQL: ORA-00933: SQL command not properly ended
    HR@XE>Have a feeling this should be really easy. Can anybody help?
    Many thanks in advance.
    Jason
    Edited by: 942375 on 08-Feb-2013 11:45

    >
    Ha, figured it out
    >
    Hopefully you also figured out that the example is just that: a technical example of how to use certain Oracle functionality. Unfortunately it is also an example of what you should NOT do in an actual application.
    That code isn't scaleable, uses expensive PGA memory, has no limit on the amount of memory that might be used and, contrary to your belief will result in EVERY SESSION HAVING ITS OWN CACHE of exactly the same data if the session even touches that package.
    Mr. Feuerstein is an expert in SQL and PL/SQL and his books cover virtually all of the functionality available. He also does an excellent job of providing examples to illustrate how that functionality can be combined and used. But the bulk of those examples are intended solely to illustrate the 'technical' aspects of the technology. They do not necessarily reflect best practices and they often do not address performance or other issues that need to be considered when actually using those techniques in a particular application. The examples show WHAT can be done but not necessarily WHEN or even IF a given technique should be used.
    It is up to the reader to learn the advantages and disadvantages of each technicalogical piece and determine when and how to use them.
    >
    Now, I have just done some googling, and it seems that what I am trying to do isn't possible. Apparently %ROWTYPE is PL/SQL, and not understood by SQL, so you can't call onerow() from sql. Correct?
    >
    That is correct. To be used by SQL you would need to create SQL types using the CREATE TYPE syntax. Currently that syntax does not support anything similar to %ROWTYPE.
    >
    So am I supposed to create a type of EMPLOYEES%ROWTYPE in a PL/SQL procedure, and the idea of this code, is that the first call to onerow() runs the initialiation code, which populates the cache, and all subsequent calls to onerow() (whether by my session or any other) will use the cache?
    >
    NO! That is a common misconception. Each session has its own set of package variables. Any session that touches that package will cause the entire EMPLOYEES table to be queried and stored in a new associative array specifically for that session.
    That duplicates the cache for each session using the package. So while there might be some marginal benefit for a single session to cache data like that the benefit usually disappears if multiple sessions are involved.
    The main use case that I am aware of where such caching has benefit is during ETL processing of staged data when the processing of each record is too complex to be done in SQL and the records need to be BULK loaded and the data manipulated in a loop. Then using an associative array as a lookup table to quickly get a small amount of data can be effective. And if the ETL procedure is being processed in parallel (meaning different sessions) then for a small lookup array the additional memory use is tolerable.
    Mitigating against that is the fact that:
    1. Such frequently used data that you might store in the array is likely to be cached by Oracle in the buffer cache anyway
    2. Newer versions of Oracle now have more than one cache
    3. The SQL query needed to get the data from the table will use a bind variable that eliminates repeated hard parsing.
    4. The cursor and the buffer caches ARE SHARED by multiple sessions globally.
    So the short story is that there would rarely be a use case where ARRAYs like that would be preferred over accessing the data from the table.

  • SQL Query (pl/sql function body returning Sql query)

    Hi All,
    I have created a region of "SQL Query (pl/sql function body returning Sql query)" type and it is working fine , but when I am migrating(export /import) this application from development to systest environment ,
    It gives error for this region :
    Error ERR-1101 Unable to process function body returning query.
    OK
    ORA-06550: line 1, column 52: PLS-00306: wrong number or types of arguments in call to 'FU_TRADE_REPORT_QUERY' ORA-06550: line 1, column 45: PL/SQL: Statement ignored
    Any pointer ...why this is happening.
    Thanks
    Dikshit

    If your function is a stored function that is called from within APEX (function body not coded into the app itself), have you made sure that the function has been created and compiles ok prior to installing your apex app.
    If there are some dependency issues between other PL/SQL units or database objects that are causing your function not to be compiled, you apex install will fail as you are trying to reference an uncompelled bit of pl/sql.
    Let me know how you get on
    Regards
    Duncan

  • SQL Query ( PL/SQL function body returning query ) page

    Hello Friends,
    I have a page with type SQL Query ( PL/SQL function body returning query ).
    I have written a pl/sql block that returns a sql query - select statment.
    Some times i am getting no data found error - does it got to do with the variable that stores the query .
    =======================
    ORA-06502: PL/SQL: numeric or value error: character string buffer too small
    Error ERR-1101 Unable to process function body returning query.
    OK
    =====================
    When the query is returned with records where exactly the records are stored is it in the variable declared in pl/sql block or with the Oracle Apex implicit cursor.
    Here's the pl/sql block ..
    The query is generated while the user is navigating through pages ..
    ====================
    declare
    l_return_stmt varchar2(32767);
    l_select varchar2(32000);
    l_from varchar2(32000);
    l_where varchar2(32000);
    l_order_by varchar2(32000);
    l_stmt_recordcount varchar2(32000);
    l_recordcount number ;
    begin
    l_select := 'select '||:P10_VARLIST1||:P10_VARLIST2||:P10_VARLIST3
    ||:P10_VARLIST4||:P10_VARLIST5;
    l_from := ' from '||:P10_RELATION;
    if length(:P10_WHERE) > 0 then
    l_where := ' where '||:P10_WHERE;
    else
    l_where := '';
    end if;
    if length(:P10_ORDER_BY) > 0 then
    l_order_by := ' order by '||:P10_ORDER_BY;
    else
    l_order_by := '';
    end if;
    l_return_stmt := l_select||l_from||l_where||l_order_by;
    :P10_STMT := l_return_stmt;
    return l_return_stmt;
    end;
    =============================
    Appreciate your help in this regard.
    thanks/kumar
    Edited by: kumar73 on Apr 22, 2010 6:38 AM

    It looks like the query string you are trying to pass back exceeds the 32K limit for a varchar. Where this is happening is kind of difficult to tell as it could be any number of points, and also depends on what you are passing into the process via page items.
    I would first try to establish what combination of page items causes this error to occur. Then, starting from the bottom and working your way backwards, I would start 'switching off' some of the items you use to build your query until it breaks again, thus establishing which part is leading to the error.
    Also, I'm not sure what :P10_STMT is doing (are you maybe using this for visiblity of the query created)?
    It looks like the query string you are trying to pass back exceeds the 32K limit for a varchar. Where this is happening is kind of difficult to tell as it could be any number of points, and also depends on what you are passing into the process via page items.
    I would first try to establish what combination of page items causes this error to occur. then, starting from the bottom and working your way backwards, I would start 'switching off' some of the items you use to build your query until it breaks again, thus establishing which part is leading to the error.
    Also, I'm not sure what :P10_STMT is doing (are you maybe using this for visiblity of the query created)?

  • Pl/sql function body returning SQL query - Print function

    Hello all,
    I have pl/sql function body returning SQL query for my reports for my new project that I am developing. We dont have any BI tool or anything for APEX so we use Oracle reports to get the same reports to be printed in PDF format. I had been using SQL function for Reports all these days and grabbing the data using SQL query was easy in Oracle reports. But this time we had atleast 8 fields in search criteria and hence I thouhgt PL/sql function body returning SQL query could be something easy to handle that scenario. We have 11 such reports in our project. Now when we tried to use the same PL/sql function to oracle reports , I was told by one of our Oracle reports expert, that we have to write it into functions and use it in SQL query to get the Reports in Oracle reports. Is there any Easy way to convert the same Pl/SQL function or get a PDF format of the same report in APEX without going thru the much pains of rewriting the whole SQL Query.
    thank you
    Devisri

    Hi,
    give this a go.
    I can't test it as I don't have the tables in my schema.
    create or replace package MK_TEST_PF is
    -- Author  : MK
    -- Created : 21/06/2010 16:30:19
    -- Purpose : FOR LUCY_DISCOVER
    -- Public type declarations
    /*     -- just guess the table row types.....
         -- otherwise it won't compile
         type test_rec is record
              (INV REP.inv%type
              ,cNUMBER REP.cNUMBER%type
              ,OPENDATE REP.OPENDATE%type
              ,TARGETDATE REP.ESTCOMPLETE%type
              ,DATECLOSED REP.COMPLETED%type
              ,STATUS REP.STATUS%type
              ,cCODE REP.cCODE%type
              ,line varchar2(4000)
              ,SIGc varchar2(4000)
              ,CLASS REP.CLASS%type
              ,SUMM REP.SUMM%type
              ,AREA REP.AREA%type
         type test_rec is record
              (INV varchar2(4000)
              ,cNUMBER varchar2(4000)
              ,OPENDATE varchar2(4000)
              ,TARGETDATE varchar2(4000)
              ,DATECLOSED varchar2(4000)
              ,STATUS varchar2(4000)
              ,cCODE varchar2(4000)
              ,line varchar2(4000)
              ,SIGc varchar2(4000)
              ,CLASS varchar2(4000)
              ,SUMM varchar2(4000)
              ,AREA varchar2(4000)
         type test_tab is table of test_rec;
    -- Public constant declarations
    -- Public variable declarations
    -- Public function and procedure declarations
    end MK_TEST_PF;
    create or replace package body MK_TEST_PF is
    -- Private type declarations
    -- Private constant declarations
    -- Private variable declarations
    -- Function and procedure implementations
         function get_query_f
              (p_inv VARCHAR2 := UPPER(v('P44_INV'))
              ,p_reg VARCHAR2 := UPPER(v('P44_CLASS'))
              ,p_proarea VARCHAR2 := UPPER(v('P44_PROGRAM_AREA'))
              ,p_disp VARCHAR2 := UPPER(v('P44_DISPOSITION'))
              ,p_coding VARCHAR2 := UPPER(v('P44_CODING'))
              ,p_status VARCHAR2 := UPPER(v('P44_STATUS'))
              ,p_SIG VARCHAR2 := UPPER(v('P44_SIG_c'))
              ,p_inc_sum VARCHAR2 := UPPER(v('P44_INCLUDE_SUMM_FIELD'))
              ,p_word VARCHAR2 := UPPER(v('P44_WORD_IN_SUMM'))
              ,p_timeframe VARCHAR2 := UPPER(v('P44_TIME_FRAME'))
              ,p_rec VARCHAR2 := UPPER(v('P44_RECORD_KEEPING'))
              ,p_WORD_IN_SUMM VARCHAR2 := UPPER(v('P44_WORD_IN_SUMM'))
              ,p_ON_AFTER VARCHAR2 := UPPER(v('P44_ON_AFTER'))
              ,p_ON_BEFORE VARCHAR2 := UPPER(v('P44_ON_BEFORE'))
              return varchar2
         is
              v_sql VARCHAR2(5000);
         --     v_inv VARCHAR2(100);
         --     v_reg VARCHAR2(100);
         --     v_proarea VARCHAR2(100);
         --     v_status VARCHAR2(100);
         --     v_SIG VARCHAR2(100);
         --     v_disp VARCHAR2(100);
         --     v_coding VARCHAR2(100);
         --     v_inc_sum VARCHAR2(4);
         --     v_word VARCHAR2(4000);
              v_wildcard VARCHAR2(2000);
         --     v_timeframe VARCHAR2(100);
         --     v_rec VARCHAR2(5);
              v_record VARCHAR2(5);
              v_open VARCHAR2(100);
              v_closed VARCHAR2(100);
              v_PEND VARCHAR2(100);
              v_refSIG VARCHAR2(100);
              v_refreg VARCHAR2(100);
              v_refother VARCHAR2(100);
              v_y varchar2(100);
         BEGIN
              --v_inv := UPPER(v('P44_INV')) ;
              v_record := 'R%';
              v_wildcard := '%';
              v_open := 'OPEN';
              v_closed := 'CLOSED';
              v_PEND := 'PEND';
              v_refSIG := 'REF - SIG';
              v_refreg := 'REF - CLASS';
              v_refother := 'REF - OTHER';
              v_y := 'Y';
              v_sql := 'SELECT REP.INV as INV, REP.cNUMBER as cNUMBER, REP.OPENDATE as OPENDATE,
              REP.ESTCOMPLETE as TARGETDATE, REP.COMPLETED as DATECLOSED, REP.STATUS as STATUS,
              REP.cCODE as cCODE, apex_item.checkbox(1,REP.line,null,'''||v_y||''') line , apex_item.checkbox(1,REP.SIG,null,'''||v_y||''') SIGc ,
              REP.CLASS as CLASS, REP.SUMM as SUMM, REP.AREA as AREA from REP where 1=1';
              IF p_rec is not null then
                   IF p_rec = 'E' then
                        v_sql := v_sql|| ' and upper(REP.cnumber) not like '''||v_record||'''';
                   ELSIF p_rec = 'D' then
                        v_sql := v_sql|| ' and upper(REP.cnumber) like '''||v_record||'''';
                   ELSIF p_rec = 'I' then
                        v_sql := v_sql|| ' and REP.cnumber = REP.cnumber ';
                   end if ;
              end if ;
              IF upper(p_status) not like '%NULL%' then
                   IF upper(p_status) like '%OPEN%' then
                   v_sql := v_sql||' AND upper(REP.status) like '''||v_open||'''';
                   ELSIF upper(p_status) like '%CLOSED%' then
                   v_sql := v_sql||' AND upper(REP.status) like '''||v_closed||'''';
                   ELSIF upper(v_PEND) like '%PEND%' then
                   v_sql := v_sql||' AND upper(REP.status) like '''||v_PEND||'''';
                   ELSIF upper(v_refSIG) like '%REF - SIG%' then
                   v_sql := v_sql||' AND upper(REP.status) like '''||v_refSIG||'''';
                   ELSIF upper(v_refreg) like '%REF - CLASS%' then
                   v_sql := v_sql||' AND upper(REP.status) like '''||v_refreg||'''';
                   ELSIF upper(v_refother) like '%REF - OTHER%' then
                   v_sql := v_sql||' AND upper(REP.status) like '''||v_refother||'''';
                   END IF ;
              END IF ;
              IF p_inv = 'NULL' THEN
                   v_sql := v_sql||' AND instr(upper(REP.INV),'''||p_inv||''') > 0';
              END IF ;
              IF p_reg = 'NULL' THEN
                   v_sql := v_sql||' AND instr(upper(REP.CLASS),'''||p_reg||''') > 0';
              END IF ;
              IF p_proarea = 'NULL' THEN
                   v_sql := v_sql||' AND instr(upper(REP.AREA),'''||p_proarea||''') > 0';
              END IF ;
              IF p_disp = 'NULL' THEN
                   v_sql := v_sql||' AND instr(upper(REP.disposition),'''||p_disp||''') > 0';
              END IF ;
              IF p_coding = 'NULL' THEN
                   v_sql := v_sql||' AND instr(upper(REP.ccode),'''||p_coding||''') > 0';
              END IF ;
              IF p_SIG = ' ' THEN
                   v_sql := v_sql||' AND instr(upper(REP.SIG),'''||p_SIG||''') > 0';
              END IF ;
              IF p_word is not null then
                   v_sql := v_sql|| ' and
                   instr(upper(REP.SUMM),
                   upper(nvl('''||p_WORD_IN_SUMM||''',REP.SUMM))) > 0';
              end if ;
              If p_timeframe is not null then
                   if upper(p_timeframe) = 'OPEN' then
                   v_sql := v_sql|| ' and to_date(REP.opendate) between to_date ('''||p_ON_AFTER||''') and to_date('''||p_ON_BEFORE||''')';
                   elsif upper(p_timeframe) = 'CLOSED' then
                   v_sql := v_sql|| ' and to_date(REP.completed) between to_date ('''||p_ON_AFTER||''') and to_date('''||p_ON_BEFORE||''')';
                   elsif upper(p_timeframe) = 'EST' then
                   v_sql := v_sql|| ' and to_date(REP.estcomplete) between to_date ('''||p_ON_AFTER||''') and to_date('''||p_ON_BEFORE||''')';
                   end if;
              end if;
              v_sql := v_sql ||' order by REP.INV ';
              return v_sql;
         end get_query_f;
         function test_pf
              (p_inv VARCHAR2 := UPPER(v('P44_INV'))
              ,p_reg VARCHAR2 := UPPER(v('P44_CLASS'))
              ,p_proarea VARCHAR2 := UPPER(v('P44_PROGRAM_AREA'))
              ,p_disp VARCHAR2 := UPPER(v('P44_DISPOSITION'))
              ,p_coding VARCHAR2 := UPPER(v('P44_CODING'))
              ,p_status VARCHAR2 := UPPER(v('P44_STATUS'))
              ,p_SIG VARCHAR2 := UPPER(v('P44_SIG_c'))
              ,p_inc_sum VARCHAR2 := UPPER(v('P44_INCLUDE_SUMM_FIELD'))
              ,p_word VARCHAR2 := UPPER(v('P44_WORD_IN_SUMM'))
              ,p_timeframe VARCHAR2 := UPPER(v('P44_TIME_FRAME'))
              ,p_rec VARCHAR2 := UPPER(v('P44_RECORD_KEEPING'))
              ,p_WORD_IN_SUMM VARCHAR2 := UPPER(v('P44_WORD_IN_SUMM'))
              ,p_ON_AFTER VARCHAR2 := UPPER(v('P44_ON_AFTER'))
              ,p_ON_BEFORE VARCHAR2 := UPPER(v('P44_ON_BEFORE'))
              RETURN test_tab PIPELINED
         is
              type test_c is ref cursor;
              v_row test_tab;
              v_sql varchar2(4000);
              v_cursor test_c;
         begin
              v_sql := get_query_f
                   (p_inv
                   ,p_reg
                   ,p_proarea
                   ,p_disp
                   ,p_coding
                   ,p_status
                   ,p_SIG
                   ,p_inc_sum
                   ,p_word
                   ,p_timeframe
                   ,p_rec
                   ,p_WORD_IN_SUMM
                   ,p_ON_AFTER
                   ,p_ON_BEFORE
              open v_cursor for v_sql;
              fetch v_cursor bulk collect into v_row;
              close v_cursor;
              for i in 1 .. v_row.count loop
                   pipe row (v_row(i));
              end loop;
              return;
         end test_pf;
    end MK_TEST_PF;
    /Regards
    Michael

  • Query on Reoprts-pl/sql function body returning sql query

    Hi,
    I am facing a starnge problem.. and would like to know the reason for it.
    The situation is as follows:
    I have a report (pl/sql function body returning sql query based). My query is as follows:
    declare
    l_query1 varchar2(2000);
    begin
    if (:P102_min_value is not null and :P102_max_value is null) then
    l_query1 := 'select decode(:P102_date,'1',date1) Transaction_Date, decode(:P102_first_name,'2',first_name) First_Name from (
    select * from MORTGAGE_LOAN_LEADS where APPRX_LOAN_AMOUNT >=:P102_min_value
    return (l_query1);
    end if;
    end;
    This returns the error as :
    1 error has occurred
    Function returning SQL query: Query cannot be parsed within the Builder. If you believe your query is syntactically correct, check the generic columns checkbox below the region source to proceed without parsing.
    (ORA-06550: line 7, column 20: PLS-00103: Encountered the symbol "1" when expecting one of the following: * & = - + ; < / > at in is mod remainder not rem <> or != or ~= >= <= <> and or like LIKE2_ LIKE4_ LIKEC_ between || multiset member SUBMULTISET_)
    How do i correct this? am i right in thinking that the single quotes indicating a string within a select query is creating the problem? Beacuse if i use an sql query report and use the following query, it is working fine...
    select
    decode(:P102_date,'1',date1) Transaction_Date,
    decode(:P102_first_name,'2',first_name) First_Name
    from (
    select * from MORTGAGE_LOAN_LEADS where APPRX_LOAN_AMOUNT >=:P102_min_value
    But i need to write pl/sql function, so that multiple report can be returned based on different conditions. Please guide me.
    Thanks,
    Sumana

    Does that mean that both in if and else we need to have same columns selected?
    if thats the case.. any idea how i can implement it in my code. The situation here is that the columns that need to be selected are dynamic and keep on changing...
    if i try to implement like this and run the page, it gives the following error:
    Query is:
    declare
    l_query1 varchar2(4000);
    begin
    if apex_application.get_current_flow_sgid(:APP_ID) = apex_application.get_sgid then
    if (:P102_min_value is not null and :P102_max_value is null) then
    l_query1 := 'select decode(' || :P102_date|| ',''1'',date1) Transaction_Date, decode(' || :P102_first_name || ',''2'',first_name) First_Name from (
    select * from MORTGAGE_LOAN_LEADS where APPRX_LOAN_AMOUNT >=' || :P102_min_value ||'
    elsif (:P102_min_value is null and :P102_max_value is not null) then
    l_query1 := 'select decode(' || :P102_date|| ',''1'',date1) Transaction_Date, decode(' || :P102_first_name || ',''2'',first_name) First_Name from (
    select * from MORTGAGE_LOAN_LEADS where APPRX_LOAN_AMOUNT >=' || :P102_max_value ||'
    else
    l_query1 := 'select date1,first_name from MORTGAGE_LOAN_LEADS where rownum = 1';
    end if;
    else
    l_query1 := 'select date1,first_name from MORTGAGE_LOAN_LEADS where rownum = 1';
    end if;
    return l_query1;
    --dbms_output.put_line( l_query1);
    end;
    The Error is:
    failed to parse SQL query:
    ORA-00936: missing expression
    If i try to run the same in command prompt, it always goes to the else part... (else of outer if)

Maybe you are looking for