Help - Oracle function w/RETURN VIEW_NAME%ROWTYPE

I have a fairly complex Oracle function with a signature like this:
FUNCTION get_some_data
in_param_one VARCHAR2
, in_param_two VARCHAR2
)RETURN VIEW_NAME%ROWTYPE
(The internal logic of the function is such that it will return at most one row.)
I have sample code from MSDN that outlines calling functions in .Net, like this:
// create the command for the function
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "GET_EMPLOYEE_EMAIL";
cmd.CommandType = CommandType.StoredProcedure;
// add the parameters, including the return parameter to retrieve
// the return value
cmd.Parameters.Add("p_employee_id", OracleType.Number).Value = 101;
cmd.Parameters.Add("p_email", OracleType.VarChar, 25).Direction =
ParameterDirection.ReturnValue;
// execute the function
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
// output the result
Console.WriteLine("Email address is: " + cmd.Parameters["p_email"].Value);
I don't see an available OracleType to fit the '...%ROWTYPE' return value.
I think the Oracle code is doing inferred 'table inlining' but it may, instead, be using an inferred refcursor (clearly I'm no DBA). Everything I've been able to find online when googling for how to handle this in .Net doesn't seem to match this situation.
How can I call this function and get the data back in C#? Please note that I don't have the authority to modify the package to make it explicitly return a refcursor.
Thank you for any light you can shed!
MarFarMa

Here's a "quick and dirty" example using the HR sample schema that I think might be enough to get you going...
Pl/SQL (used to mimic your function that returns %rowtype):
create or replace function get_country_row (p_id in varchar2) return countries%rowtype as
  cursor emp_cur is select * from countries where country_id = p_id;
  emp_rec emp_cur%rowtype;
begin
  open emp_cur;
  fetch emp_cur into emp_rec;
  close emp_cur;
  return emp_rec;
end;C# Code:
using System;
using System.Data;
using System.Text;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
namespace RowTypeTest
  /// <summary>
  /// Summary description for Class1.
  /// </summary>
  class Class1
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
      // create and open connection
      string constr = "User Id=hr; Password=hr; Data Source=oranet; Pooling=false";
      OracleConnection con = new OracleConnection(constr);
      con.Open();
      // build anonymous pl/sql block to get the data
      StringBuilder sbSQL = new StringBuilder();
      sbSQL.Append("declare ");
      sbSQL.Append("  l_country_row countries%rowtype; ");
      sbSQL.Append("begin ");
      sbSQL.Append("  l_country_row   := get_country_row(:p_id); ");
      sbSQL.Append("  :p_country_id   := l_country_row.country_id; ");
      sbSQL.Append("  :p_country_name := l_country_row.country_name; ");
      sbSQL.Append("  :p_region_id    := l_country_row.region_id; ");
      sbSQL.Append("end;");
      // input parameter for country id
      OracleParameter p_id = new OracleParameter();
      p_id.OracleDbType = OracleDbType.Varchar2;
      p_id.Size = 2;
      p_id.Value = "UK";
      p_id.Direction = ParameterDirection.Input;
      // input/output parameter for country id
      // this is redundant but we are selecting * from the table...
      OracleParameter p_country_id = new OracleParameter();
      p_country_id.OracleDbType = OracleDbType.Varchar2;
      p_country_id.Size = 2;
      p_country_id.Direction = ParameterDirection.InputOutput;
      // input/output parameter for country name
      OracleParameter p_country_name = new OracleParameter();
      p_country_name.OracleDbType = OracleDbType.Varchar2;
      p_country_name.Size = 40;
      p_country_name.Direction = ParameterDirection.InputOutput;
      // input/output parameter for region id
      OracleParameter p_region_id = new OracleParameter();
      p_region_id.OracleDbType = OracleDbType.Decimal;
      p_region_id.Direction = ParameterDirection.InputOutput;
      // create command object
      OracleCommand cmd = con.CreateCommand();
      cmd.CommandText = sbSQL.ToString();
      // add parameters to command
      cmd.Parameters.Add(p_id);
      cmd.Parameters.Add(p_country_id);
      cmd.Parameters.Add(p_country_name);
      cmd.Parameters.Add(p_region_id);
      // get the data
      cmd.ExecuteNonQuery();
      // display data retrieved
      Console.WriteLine("{0}, {1}, {2}", p_country_id.Value, p_country_name.Value, p_region_id.Value);
      // clean up objects
      p_region_id.Dispose();
      p_country_name.Dispose();
      p_country_id.Dispose();
      p_id.Dispose();
      cmd.Dispose();
      con.Dispose();
}Output:
UK, United Kingdom, 1This only works if the stored function returns a single row and obviously has no error handling, etc. but I hope it helps a bit...
- Mark

Similar Messages

  • Error with function that returns a rowtype...

    i have a function that returns a rowtype. below is a simplified version:
    create or replace function "GETC"
    return mytable%rowtype
    is
    rec mytable%rowtype;
    begin
    rec.rowid := 1;
    return rec;
    end;
    eventually i'll want to call this from java. but for now i'd settle for calling it from the XE web front end (and sqlplus).
    SQLPLUS: i try to call it from sqlplus by first declaring a variable where i can store the return:
    var a mytable%rowtype;
    it instantly stops me saying that i can only declare a var of a particular type. so what do i do?
    XE interface: i tried various ways to call getc(), but they were all unsuccessful. what should i be doing?
    thanks so much for your time.
    marko

    Given a function like this:
    CREATE OR REPLACE FUNCTION get_employee
         ( p_empno emp.empno%TYPE )
         RETURN emp%ROWTYPE
    AS
         v_result emp%ROWTYPE;
    BEGIN
         SELECT * INTO v_result
         FROM   emp
         WHERE  empno = p_empno;
         RETURN v_result;
    END get_employee;You can call it within PL/SQL like this:
    DECLARE
         rec emp%ROWTYPE;
    BEGIN
         rec := get_employee(7902);
         DBMS_OUTPUT.PUT_LINE(rec.ename);
    END;However,
    1. Unless there is a column named "ROWID" in the table (unlikely since it would conflict with the actual rowid and is therefore not allowed), the type will not have an attribute named "rowid".
    2. "1" would not be a valid rowid anyway.
    3. %ROWTYPE defines a PL/SQL type, which will not be recognised in other environments such as SQL and Java.

  • JAVA Calling Oracle Function and Returning OBJECT

    HI,
    I am working as a developer in java/j2ee project.
    I am facing one issue:
    I need to call Oracle function from java code. Oracle User define function is residing in oracle package and returning Object which contains data.
    Can you please help me
    With Best Regards

    golduniya wrote:
    I need to call Oracle function from java code. Oracle User define function is residing in oracle package and returning Object which contains data.
    Can you please help meIt requires a great deal of Oracle jdbc driver specific code.
    [http://download-west.oracle.com/docs/cd/B10501_01/java.920/a96654/oraint.htm#1012664]

  • 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.

  • Calling oracle function from Access passthrough query does not return list

    Thanks to the help I received in an earlier post I've created an oracle 10g function that returns a list after executing the sql it contains. It works in oracle, using sql developer.
    I need to have the list that it returns show up in MS Access via a passthrough query. It's not working so far. The connection string etc is ok, I'm able to use passthrough queries to run sql strings successfully. But when I try to call the function via the Access passthrough query at first nothing seems to happen (ie no list appears) and if I try to run it again, there is a odbc error 'call in progress. Current operation canceled'. There are only the three records in the table. I'm missing something, can anyone spot it?
    The passthrough query looks like this
    select * from fn_testvalues from dual
    Again that runs in oracle.
    To create the testing table and 2 functions see below.
    CREATE TABLE t_values (MyValue varchar2(10));
    Table created
    INSERT INTO t_values (
    SELECT 'Merced' c1 FROM dual UNION ALL
    SELECT 'Pixie' FROM dual UNION ALL
    SELECT '452' FROM dual);
    3 rows inserted
    CREATE OR REPLACE FUNCTION fn_isnum(p_val VARCHAR2) RETURN NUMBER IS
    n_val NUMBER;
    BEGIN
    n_val := to_number(p_val);
    RETURN 1;
    EXCEPTION
    WHEN OTHERS THEN
    RETURN 0;
    END;
    Function created
    testing the table:
    SELECT val, fn_isnum(MyValue ) isnum
    FROM t_values;
    VAL ISNUM
    Merced 0
    Pixie 0
    452 1
    Now the function that is called in the passthrough query:
    create or replace function fn_testvalues
    return sys_refcursor is
    rc sys_refcursor;
    begin
    open rc for
    Select t_values.*, fn_isnum(MyValue) IsNum from t_values;
    return(rc);
    end fn_testvalues;

    lecaro wrote:
    OK. But obviously there is some oracle object that one can call via an Access pass-through query which returns rows?Just to clarify. You could fetch data in Access from an Oracle function that returns a ref cursor using VBA editor. To use a pass-through query Oracle function should be a table function or pipelined table function:
    CREATE OR REPLACE
      TYPE testvalues_obj_type
        AS OBJECT(
                  val varchar2(10),
                  isnum number
    CREATE OR REPLACE
      TYPE testvalues_tbl_type
        AS TABLE OF testvalues_obj_type
    CREATE OR REPLACE
      FUNCTION fn_testvalues
        RETURN testvalues_tbl_type
        PIPELINED
        IS
            CURSOR testvalues_cur
              IS
                SELECT  testvalues_obj_type(MyValue,fn_isnum(MyValue)) testvalues_obj
                  FROM  t_values;
        BEGIN
            FOR v_rec IN testvalues_cur LOOP
              PIPE ROW(v_rec.testvalues_obj);
            END LOOP;
            RETURN;
    END;
    /To test it in Oracle:
    SELECT  *
      FROM  TABLE(fn_testvalues)
    VAL             ISNUM
    Merced              0
    Pixie               0
    452                 1
    SQL> Now in Access pass-trough query window enter:
    SELECT  *
      FROM  TABLE(fn_testvalues);SY.

  • X-file with db function returning a rowtype to forms. Positional binding?

    How to explain this ...
    First things first:
    Forms [32 bits] Versión 11.1.2.1.0 (Producción)
    Oracle Database 11g Release 11.2.0.3.0 - 64bit Production
    Now the db testcase:
    I've got two schemas, quite similar, SCHEMA_A and SCHEMA_B
    Imagine the same table: mytable (colx varchar2, coly varchar2, colz varchar2) in both schemas,
    BUT in SCHEMA_B the order of the cols is not the same. In schema B it is
    mytable (colx, colz, coly).
    (Yeah, I know, I know, but leave it for the sake of the x-file)
    Let's suppose the table has only one row, and that I have a db function in both schemas such as this:
    function get_myrow return mytable%rowtype is
    l_row mytable%rowtype;
    begin
    select * into l_row from mytable;
    return l_row;
    end;
    Here, the forms testcase:
    I make a form, where I show the value in an item
    For example:
    :item := get_myrow().coly
    And now, the x-file:
    If I compile the form in the builder, connected as SCHEMA_A, when I run it in SCHEMA_B, the item shows colz value!!
    It is as if forms is doing some kind of positional binding in the fmx. Instead of asking for coly column to the record type variable, it shows "the second value" of the record type.
    Now, I will have to find this disordered tables and reorder them (dbms_redefinition? hints are welcome).
    Any thougts? Bug as feature?

    About the "select * is problematic" , I agree 99% of the times. But this time, as I'm storing the values in the rowtype variable, is the way to ensure that the estructure and the values fit.
    You said:
    What happens when your table changes (such as a new column) but your function hasn't been updated?  Your Function will produce an error because it can't handle the additional column.
    And it's just the opposite. My function will recompile itself, as the rowtype is perfectly capable of storing the values in the new rowtype.
    In fact, it's the MLBrown function the one that would produce an error if I change columns in the table, and that's the best case scenario, as the function could be lucky and work storing the values in the wrong places, leaving the bug hidden.
    Anyway, I understand this "select *" issue is arguable, so forget about the select * , I'll take it out of this thread with a more simple testcase:
    create table mytable (
    colx varchar2(10),
    coly varchar2(10),
    colz varchar2(10));
    Consider this "select free" version of the function:
    function get_myrow return mytable%rowtype is
      l_row mytable%rowtype;
    begin
    l_row.colx := 'a';
    l_row.coly := 'b';
    l_row.colz := 'c';
      return l_row;
    end;
    Forget also about schema_a and schema_b, I can reproduce it with just one schema!!!
    Now I build a form with just a button. When- button-pressed:
    message (get_myrow.coly);
    I compile and run it, and I get a b value. ok.
    Now I drop the table and recreate but like this:
    create table mytable (
    colx varchar2(10),
    colz varchar2(10),
    coly varchar2(10));
    Now run the form (without compiling) and see how the message shown is c !!!
    The result is different, depending on how whas the rowtype structure when I compiled the fmb.
    Are you indeed telling that is acceptable an escenary where I ask for get_myrow().coly value and I get colz value instead?
    How's that possible? Because somebody shortcutted in the fmx compiling process, and converted my call for named coly value to a call to "the second column of the record variable".
    I'm not asking for a numbered position , I'm asking for coly value, not for "the second column of the rowtype variable the day I compiled the form". Had I want a possitional binding, I'd use a frikkin varray.

  • Toplink JPA Calling Oracle Function Return sys_refcursor

    I have a function which return sys_refcursor and I am trying to call this using JPA(1.0)
    @NamedNativeQuery( name = "getEmpsByDeptId"
            , query = "{ ? = call my_pck.getEmployees(:longName)}"
            , resultClass = Employee.class
            , hints = { @QueryHint(name = "org.hibernate.callable", value = "true")
                           , @QueryHint(name = "org.hibernate.readOnly", value = "true")
    DAOImpl
    query = getEntityManager().createNamedQuery("getEmpsByDeptId");
    query.setParameter("longName", "SCOTT");
    list = (List<Employee>)query.getResultList();
    However when I execute, I am getting the following exception
    Exception [TOPLINK-6132] (Oracle TopLink Essentials - 2.1 (Build b52-fcs (09/24/2008))):
    oracle.toplink.essentials.exceptions.QueryException Exception Description:
    Query argument 2 not found in list of parameters provided during query execution.
    Query: ReadAllQuery(test.entity.Employee) at oracle.toplink.essentials.exceptions.QueryException.namedArgumentNotFoundInQueryParameters
    I have tried using
    call my_pck.getEmployees(?)}"
    and
    query.setParameter(1, "SCOTT");
    However error remains the same and how can I resolve this issue?
    I have used the same function with Hibernate using JPA2.0 and it has worked.
    Thank

    lecaro wrote:
    OK. But obviously there is some oracle object that one can call via an Access pass-through query which returns rows?Just to clarify. You could fetch data in Access from an Oracle function that returns a ref cursor using VBA editor. To use a pass-through query Oracle function should be a table function or pipelined table function:
    CREATE OR REPLACE
      TYPE testvalues_obj_type
        AS OBJECT(
                  val varchar2(10),
                  isnum number
    CREATE OR REPLACE
      TYPE testvalues_tbl_type
        AS TABLE OF testvalues_obj_type
    CREATE OR REPLACE
      FUNCTION fn_testvalues
        RETURN testvalues_tbl_type
        PIPELINED
        IS
            CURSOR testvalues_cur
              IS
                SELECT  testvalues_obj_type(MyValue,fn_isnum(MyValue)) testvalues_obj
                  FROM  t_values;
        BEGIN
            FOR v_rec IN testvalues_cur LOOP
              PIPE ROW(v_rec.testvalues_obj);
            END LOOP;
            RETURN;
    END;
    /To test it in Oracle:
    SELECT  *
      FROM  TABLE(fn_testvalues)
    VAL             ISNUM
    Merced              0
    Pixie               0
    452                 1
    SQL> Now in Access pass-trough query window enter:
    SELECT  *
      FROM  TABLE(fn_testvalues);SY.

  • Ora-06502 while calling oracle function

    I am using 9.2.0.4.0 database.
    I have vb.net application that uses oracle provider for .net to connect to database.
    I am calling Oracle function which returns varchar2 value back.
    when i execute cmd2.ExecuteNonQuery, I get ora-06502 error.
    CREATE OR REPLACE FUNCTION ZZZ_TEMP( p_val IN VARCHAR2) RETURN varchar2
    AS
    BEGIN
    RETURN 'HELLO';
    EXCEPTION WHEN OTHERS THEN
    RETURN SQLCODE||' - '||SUBSTR(SQLERRM,1,100);
    END;
    ************** vb.net code
    Dim cmd2 As New Oracle.DataAccess.Client.OracleCommand(UserSchemaName & ".ZZZ_TEMP", con)
    Dim VAL As String
    Try
    cmd2.Parameters.Add("RetVal", Oracle.DataAccess.Client.OracleDbType.Varchar2, ParameterDirection.ReturnValue)
    cmd2.Parameters.Add("p_val", Oracle.DataAccess.Client.OracleDbType.Varchar2, ParameterDirection.Input).Value = "XYZ"
    cmd2.Connection = con
    cmd2.CommandType = CommandType.StoredProcedure
    cmd2.ExecuteNonQuery()
    VAL = cmd2.Parameters("RetVal").Value
    Catch ex As Oracle.DataAccess.Client.OracleException
    MsgBox(ex.Message)
    End Try

    If I change this function to retrun number rather than Varchar2 and change my
    RetVal parameter as follow it works. I am noticing that there might be a bug when function returns varchar2
    cmd2.Parameters.Add("RetVal", Oracle.DataAccess.Client.OracleDbType.int32, ParameterDirection.ReturnValue)
    cmd2.Parameters.Add("p_Val", Oracle.DataAccess.Client.OracleDbType.int32, ParameterDirection.Input).valu ="XYZ"

  • Return type Boolean From Oracle Function

    1. How do I get a return type of Boolean from Oracle function in Java?
    2. I have a function fx overloaded in Oracle (8 variances) and I have trouble getting the right one in Java. Is 8 too high a figure or Java does not support calling overloaded functions or what?
    Thanks for any help.

    I am facing a similar situation, where I have defined an overloaded function in one package (2 variants) which both return a type BOOLAN value.
    I am having trouble to setting up an CallableStatemnt to call one of this functions from Java. Whenever I set the parameter with a BIT or NUMBER data type, I get an exception with java.lang.boolean during my
    callablestatement.setobject( indez, parameter, OracleTypes.BIT );
    or
    callablestatement.setobject( indez, parameter, OracleTypes.NUMBER );
    I have no problem calling the function from SQLPlus, but doing so from Java raises the exception. I have found no exact match in OracleTypes or java.sql.Types for a BOOLEAN data type.
    In your response do you mean to modify the Function to return a NUMBER instead of a BOOLEAN, or do you mean to set the parameter as Types.NUMBER in the calling java code?
    Thanks,
    Fedro

  • Help regarding the calling of a oracle function from the OTL.

    Hi,
    I created a Oracle function like get_employee_id() which will return the employee id if the name and department exists.
    If not exists it will insert the record and return the emp_id.
    get_employee_id(name,department)
    if name and department exists id will be returned
    else record will be inserted and emp id will be returned.
    emp_id is a sequence which will be triggered to auto increment.
    Problem is::
    Not getting a correct way to access get_employee_id() from OTL interface.
    I am trying like
    query << "BEGIN :3<int> := get_employee_id(:1<char[128]>,:2<char[1024]>); END;" ;
    otl_stream oos(1, query.str().c_str(), db());
    oos << emp_name ;
    oos << emp_dept ;
    while(true){
    oos >> emp_id ;
    if(!oos) break ;
    Please let me know what is the correct way of accessing this.Thanks for the help in advance.

    Sorry, I posted this on another forum. C++ Call Interface (OCCI)
    Thanks,
    Jagdish.

  • Can oracle  function return more than one value

    Hi All
    please answer can oracle function return more than one value
    need one schenario
    regards

    Can any function, irrespective of the language, return multiple values?
    OF COURSE NOT!!
    So why do you think Oracle will now suddenly do it differently than all other languages? Never mind that it is impossible for a function (a unit/module of code) returning a memory address, to return multiple memory addresses. The machine code that does that, has not been yet been designed/implemented.
    I am continually amazed that this question is asked. It is about something so fundamental in almost every single 3rd and 4th generation language... something that is taught right at the start... the definition of what a procedure and what a function is.
    Sorry, but I simply cannot pull punches on this subject and smooth it over. There is something fundamentally wrong with your training as a programmer if you have to ask such a question about a function.
    And whatever programming skills you build on such a foundation, will be seriously lacking.
    I kindly suggest that you get back to the very basics of programming - and review and revisit until you fully understand it. There are no shortcuts in becomming a good programmer.
    Message was edited by:
    Billy Verreynne

  • Calling an Oracle function of BOOLEAN return type

    I am facing a situation, where I have defined an overloaded function in one package (2 variants) which both return a type BOOLAN value under Oracle 9i R1.
    I am having trouble to setting up an CallableStatemnt to call one of this functions from Java. Whenever I set the parameter with a BIT or NUMBER data type, I get an exception with java.lang.boolean during my
    callablestatement.setobject( index, parameter, OracleTypes.BIT );
    or
    callablestatement.setobject( index, parameter, OracleTypes.NUMBER );
    I have no problem calling the function from SQLPlus, but doing so from Java raises the exception. I have found no exact match in OracleTypes or java.sql.Types for a BOOLEAN data type.
    In your response do you mean to modify the Function to return a NUMBER instead of a BOOLEAN, or do you mean to set the parameter as Types.NUMBER in the calling java code?
    Thanks,
    Fedro

    look at BOOLEAN type mapping using JPublisher
    http://otn.oracle.com/docs/products/oracle9i/doc_library/release2/java.920/a96658.pdf

  • Oracle Function returns a Ref Cursor to a ResultSet object - Performance

    My program calls an Oracle PL/SQL function which returns a ref cursor to a ResultSet object. I know that the function runs to completion relatively quickly when i run it in an anonymous block but when the call is made through my Java application the resultset takes about 30 mins to return. Below is a snippet of my code:
    currentConnection = ConnectionManager.getInstance().getConnection();
    reportStmt = currentConnection.prepareCall("BEGIN ? := ENVISION.PKG_WMS_TO_AP.F_REPORT_CI_SC_HOLDING(?,?); END;"); reportStmt.registerOutParameter(1, OracleTypes.CURSOR);
    reportStmt.setString(2, invoice.getCrewHQ());
    reportStmt.setDate(3, invoice.getWrCompletionDate());
    reportStmt.execute();
    reportRS = ((OracleCallableStatement) reportStmt).getCursor(1);
    Through a debugger I see that the second last statement (reportStmt.execute()) runs quickly. It is only when I step into the last statement that the debugger takes up to 30 minutes.
    Any thoughts?

    Flynn,
    The Internet is a dynamic place. After nearly two and a half years, there is a chance that a link will change. This is the new URL for the relevant Web page:
    http://asktom.oracle.com/~tkyte/ResultSets/
    Good Luck,
    Avi.

  • Why oracle function return 4000 characters ?

    Dear All
    When I write any function to get some return value in a query, its width is set to 4000. Moreover, when i write the same query to create any LOV, it gives an error that record group field cannot be greater than 2000. Where the actual width of this field is 200 characters.
    Why function always returns 4000 characters?
    Regards
    Edited by: OraLearner on Dec 1, 2010 11:47 AM

    Because the maximum of a varchar2 in SQL is 4000 and you have no dimension in your function:
    SQL> r
      1  create or replace function myfunc(inMaxVal in number) return varchar2 is
      2    vRet varchar2(32000);
      3  begin
      4    for i in 1..inMaxVal loop
      5      vRet := vRet || '1';
      6    end loop;
      7    return vRet;
      8* end;
    Function created.
    SQL> select myfunc(4001) from dual;
    select myfunc(4001) from dual
    ERROR at line 1:
    ORA-06502: PL/SQL: numeric or value error: character string buffer too small
    ORA-06512: at "SCOTT.MYFUNC", line 7
    SQL> select myfunc(4000) from dual;
    MYFUNC(4000)
    1111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111so the SQL Engine have to assume your function returns 4000 bytes. If you use this function in PL/SQL it can be up to 32767 bytes:
    SQL> r
      1  begin
      2  dbms_output.put_line(substr(myfunc(4002), 1,255));
      3* end;
    11111111111111111111111111111111111111111111111111111111
    PL/SQL procedure successfully completed.cheers

  • Oracle Function help!!!

    Hi there,
    Is there any document or example for calling oracle functions and show the result sets of this functions in Oracle BI?.......

    ONUR YILDIRIM wrote:
    I DONT want to know how can I write oracle functions...I just WANT TO KNOW how can I show result sets in OBI????? What are the steps to do this?????I don't like your answer to be honest. It seems you are not getting that what you want to do is not directly possible in OBIEE. Few people have suggested different work arounds, don't just discard them because they don't do exactly what you want. You should adapt your data (or code) for OBIEE not the other way around. The reporting tool always has the priority in a reporting application. If you make the wrong decisions you will end up with a poor reporting application.

Maybe you are looking for