Function as column in select query

Recently I came upon a couple of applications using Oracle database 10g that use functions as a column in a select query for reporting purposes. These queries were taking about 10 minutes to return 55,000 records. How can such queries be optimized where the functions in the queries cannot be modified?
Can the performance be improved at all without a re-design of the query?
SELECT
          col1
         ,col2
         ,fn_get_val(col3)
         ,col4
         ,col5
   FROM
          table a,
          table b
   WHERE .....; The above function "fn_get_val" is defined as:
CREATE OR REPLACE fn_get_val(i_col IN VARCHAR2)  return varchar2
as
       CURSOR c ( i_var  VARCHAR2 )
          business logic here again
begin
     OPEN c( i_col );
     LOOP
         Loop through the above cursor
         EXIT;  -- exit when condition satisfied.
    END LOOP;
    CLOSE c;
end;
/Thanks in advance!

user1980 wrote:
Can the performance be improved at all without a re-design of the query?Possibly if function is deterministic.
Simplistic example:
SQL> create or replace package Global as
  2          counter integer := 0;
  3  end;
  4  /
Package created.
SQL>
SQL> --// non-deterministic
SQL> create or replace function EmpName( empID number ) return varchar2 is
  2          cursor c is
  3                  select ename from emp where empno = empID;
  4          empName         varchar2(10);
  5  begin
  6          Global.counter := Global.counter + 1;
  7          --// simulating your explicit cursor loop
  8          open c;
  9          fetch c into empName;
10          close c;
11 
12          return(
13                  InitCap(empName)
14          );
15  end;
16  /
Function created.
SQL>
SQL>
SQL> exec Global.counter := 0;
PL/SQL procedure successfully completed.
SQL> select
  2          empName( 7369 ) as NAME
  3  from       dual
  4  connect by level <= 100;
NAME
Smith
Smith
100 rows selected.
SQL> exec dbms_output.put_line( 'Counter='||Global.counter );
Counter=100
PL/SQL procedure successfully completed.
SQL>
SQL> --// deterministic
SQL> create or replace function EmpName( empID number ) return varchar2 deterministic is
  2          cursor c is
  3                  select ename from emp where empno = empID;
  4          empName         varchar2(10);
  5  begin
  6          Global.counter := Global.counter + 1;
  7          --// simulating your explicit cursor loop
  8          open c;
  9          fetch c into empName;
10          close c;
11 
12          return(
13                  InitCap(empName)
14          );
15  end;
16  /
Function created.
SQL>
SQL> exec Global.counter := 0;
PL/SQL procedure successfully completed.
SQL> select
  2          empName( 7369 ) as NAME
  3  from       dual
  4  connect by level <= 100;
NAME
Smith
Smith
100 rows selected.
SQL> exec dbms_output.put_line( 'Counter='||Global.counter );
Counter=1
PL/SQL procedure successfully completed.
SQL> So 1 execution of the function versus a 100 executions. But it is not always that straightforward and simplistic.
The ideal would be to not use a user function in the first place - but to instead apply that function's logic directly in SQL using native SQL statements.

Similar Messages

  • Facing problem with a date column in select query

    Hi,
    I am facing problem with a date column. Below is my query and its fainling with " invalid number format model" .
    Query: SELECT *
    FROM EMP
    WHERE trunc(LAST_UPDATED) >= to_date(to_char(22-05-2009,'dd-mm-yyyy'),'dd-mm-yyyy')
    LAST_UPDATED column is "DATE" data type.
    Please help me Thanks

    Radhakrishna Sarma wrote:
    SeánMacGC wrote:
    WHERE LAST_UPDATED >= to_date('22-05-2009','dd-mm-yyyy');
    You do not need the TRUNC here in any case.
    I don't think so. What if the user wants only data for 22nd May and the table has records with date later than 22nd also? In that case your query willl not work. In order for the Index to work, I think the query can be written like this I think Sean is right though. Use of TRUNC Function is quiet useless based on the condition given here, since the to_date Function used by OP will always point to midnight of the specified date, in this case 22-05-2009 00:00:00.
    Regards,
    Jo
    Edit: I think Sean proved his point... ;)

  • Can i update more then one column using select query.

    Dear All,
    Can i update more then one column of target table A from source table B. Like
    Update table A set A.A1 = (Select B.B1 from B where A.A3 = B.B3).
    Above stmt. I am updating only one column. But I want to update more then one column A.A1 and A.A2
    Plz give me the possible ways.
    Thanks,
    Vikas

    Yes you can do. Try the below Query
    Update A set (A.A1,A.A2) = (Select B.B1,B.B2 from B where A.A3 = B.B3)

  • COMBINING COMMON COLUMNS IN SELECT QUERY

    hi all,
        While make inner join between two tables how to link more than one
    common colums , which operator i want to use, shall anybody give me one ex.
    Thanks in advance.
    R.Vijai

    hi
    good
    try like this
    SELECT c~matnr                 "Material no.
              c~werks                 "Plant
              c~lvorm                 "Flag Mat.-Del. at Plant level
              c~bwtty                 "Valuation category
              c~kzkri                 "Indicator: Gritical part
              c~dispr                 "Material: MRP profile
    ADD  Mike Krepcik  TD 3363  02/01/05  D10K913640
              c~dismm                 "MRP type
    END                TD 3363  02/01/05  D10K913640
              c~plifz                 "Planned delivery time in days
              c~perkz                 "Period indicator
              c~minbe                 "Reorder point
              c~mabst                 "Maximum stock level
              c~umlmc                 "Stock in Tran. (plant to plant)
              a~mtart                 "Material type
              a~meins                 "Base unit of measure
              k~spras                 "Language key
              k~maktx                 "Material description
              w~bwkey                 "Valuation area
              w~bwtar                 "Valuation type
              w~lbkum                 "Total value stock
              w~salk3                 "Value of total valuated stock
              w~verpr                 "Moving ave. price/periodic unit
              w~peinh                 "Price unit  ADD  D10K913194
         FROM marc AS c LEFT OUTER JOIN mara AS a
              ON   cmatnr = amatnr
                        LEFT OUTER JOIN makt AS k
              ON   cmatnr = kmatnr
                        LEFT OUTER JOIN mbew AS w
              ON   cmatnr = wmatnr  AND
                   cwerks = wbwkey
         INTO TABLE i_splus
           WHERE c~matnr IN s_matnr      "Material no.
           AND   c~werks IN s_werks.     "Plant     
    thanks
    mrutyun^

  • How to create a Type Object with Dynamic select query columns in a Function

    Hi Every One,
    I'm trying to figure out how to write a piplined function that executes a dynamic select query and construct a Type Object in order to assigned it to the pipe row.
    I have tried by
    SELECT a.DB_QUERY INTO actual_query FROM mytable a WHERE a.country_code = 'US';
    c :=DBMS_SQL.OPEN_CURSOR;
    DBMS_SQL.PARSE(c,actual_query,DBMS_SQL.NATIVE);
    l_status := DBMS_SQL.EXECUTE(c);
    DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
    FOR j in 1..col_cnt LOOP
    DBMS_SQL.DEFINE_COLUMN(c,j,v_val,2000);
    END LOOP;
    FOR j in 1..col_cnt LOOP
    DBMS_SQL.COLUMN_VALUE(c,j,v_val);
    END LOOP;
    But got stuck, how to iterate the values and assign to a Type Object from the cursor. Can any one guide me how to do the process.
    Thanks,
    mallikj2

    Hi Justin,
    First of thanks for your reply, and coming to my requirement, I need to report the list of items which are there in the dynamic select statement what am getting from the DB. The select statement number of columns may vary in my example for different countries the select item columns count is different. For US its '15', for UK it may be 10 ...like so, and some of the column value might be a combination or calculation part of other table columns (The select query contains more than one table in the from clause).
    In order to execute the dynamic select statement and return the result i choose to write a function which will parse the cursor for dynamic query and then iterate the values and construct a Type Object and append it to the pipe row.
    Am relatively very new for these sort of things, welcome in case of any suggestions to make it simple (Instead of the function what i thought to work with) also a sample narrating the new procedure will be appreciated.
    Thanks in Advance,
    mallikj2.

  • Supress the ROW_ID column in the Select Query.

    Hi,
    I have one custom form and from main form I am calling the Line Form.
    But when I am clicking the LINE button then Form is getting open but it is giving one Error message like
    FRM-40505: Oracle Error:unable to perform query
    Once I check the Detail error.
    it is giving me this message.
    ORA-00904: "ROW_ID": invalid identifier
    And I checked the query my query is returning the ROW_ID column.
    Please help on Suppressing the Row_id column getting selected from the query.
    Thanks
    Nihar

    Hi Nihar;
    Please see:
    Transactions Workbench Error: Listing of FRM Errors [ID 1321612.1]
    Regard
    Helios

  • Cursor in select query in row to column format

    Hi
    I have the query like below
    SELECT d.department_id,
                 CURSOR(SELECT e.first_name,
                         e.last_name
                  FROM   employees e
                  WHERE  e.department_id = d.department_id
           ) emps
    FROM   depatments dI want the result set in a format of Row To columns like
    10                             20
    <cursor result>   <cursor result>pls give ur suggestions how to achieve this in a efficient way?I tried the method of "max(decode(.." but dont think so its possible with this

    vishnu prakash wrote:
    Hi
    I have the query like below
    SELECT d.department_id,
    CURSOR(SELECT e.first_name,
    e.last_name
    FROM   employees e
    WHERE  e.department_id = d.department_id
    ) emps
    FROM   depatments dI want the result set in a format of Row To columns like
    10                             20
    <cursor result>   <cursor result>pls give ur suggestions how to achieve this in a efficient way?I tried the method of "max(decode(.." but dont think so its possible with thisNumber of column of a select query is static. Must be known at the parsing time itself. But in your case i dont think the number of columns will be limited to 2 (10 and 20) there could be many more.
    You can search this forum to see how to PIVOT your data. There are lot of example. You can also try dynamic pivot. Its all in here, just search.

  • Column order in a select * query

    Suppose I have 256 columns in a table and if I query select * from  tablename ,what will the column order in the result.Will this be always same as order as in created statement?

    If the columns were all in the original CREATE TABLE statement, then, yes, the ordering of columns in SELECT * FROM will match the order from the CREATE TABLE statement.
    If columns were added after the initial create, then the original columns will come first (in their order) and then the added columns (in their order), etc.
    In the real world, it is a very bad practice to use SELECT * and have expectations about the ordering of the columns. Consider this scenario:
    Table T was created and implemented in production a year ago with columns A, B, C
    A project started up three months ago and added column D but the project is stalled in development. So in development T had columns A, B, C, D
    Later, another project started up and added columns E and F. Unlike the other project, it has progressed to Test. and Production. So in Development the table has columns A, B, C, D, E, F. In test and production the table has columns A, B, C, E, F.
    Now that stuck project has progressed to Test and Production. Now T has columns A, B, C, E, F, D in test and production but still A, B, C, D, E, F in development.
    Until someone notices and decides to fix it (where and how?)
    Be very, very careful about using SELECT *.

  • Unknown Column Name "XYZ" not detemined untill runtime.Select query.

    Hi,
    I have written a query in ABAP.I am getting following error.Can some one help me resolve this.There is a column "LANDX" in standard table T005 of PI which i need to get values from. The problem is that the column is visible only at runtime and not otherwise.How can i fetch data from this coulmn writing a select query for this.
    Query written is:
    SELECT landx from T005 into table it_t005.
    Error:
    "Unknown column name "XYZ" not determined untill runtime,you cannot specify a field list."

    Hi Deepika u were right. that there is a landx field but it is included in that table.
    so u cant exactly get it.
    now u can get ur country name and iso code just like this.
    tables: t005t  , t005.
    data: BEGIN OF it OCCURS 100,
            landx like t005t-landx,
            intca like t005-intca,
            END OF it.
    SELECT t005t~landx t005~intca   into CORRESPONDING FIELDS OF TABLE it
      from T005t
      INNER JOIN t005 on ( t005t~land1 = t005~land1 ).
    it is fulfilling ur need.
    Edited by: Matt on Feb 3, 2009 7:49 AM - Please don't use txtspk

  • How to use : bind character in DB adapter Select Query SOA11g. Getting Error code :17003 .java.sql.SQLException: Invalid column index error

    Hi All,
    The Actual query to perform is below.
    SELECT name,number from emp  WHERE CASE WHEN :1='T' AND term_date IS Not NULL THEN 1 WHEN :1='A' AND term_date IS NULL THEN 1 WHEN :1='ALL' THEN 1 ELSE  1 END = 1;
    I have tried in DB adapter like below as a parameter for :1 as #vInputParam
    SELECT name,number from emp  WHERE CASE WHEN #vInputParam='T' AND term_date IS Not NULL THEN 1 WHEN #vInputParam='A' AND term_date IS NULL THEN 1 WHEN #vInputParam='ALL' THEN 1 ELSE  1 END = 1;
    Getting Error code :17003 .java.sql.SQLException: Invalid column index error.
    Please suggest me on using ':' bind character in DB adapter Select Query SOA11g.
    Can someone help me on this please?
    Thanks,
    Hari

    Hi,
    Could you please make sure your binding style(Oracle Positional,Oracle named..etc) of the Seeded VO and Custom Vo are same.
    This is the option you will get when you are extending your vo. So make sure that both are same.
    You can refer the below link too
    VO extension leads to "Invalid column index" exception
    Thanks
    Bharat

  • Calling an  pipeline function in a Select query

    Hello gurus ,
    i have a query calling pipeline function
    WITH t AS
         (SELECT dep_code, emp_id
            FROM test1
           WHERE dep_code = 'C1' AND emp_id = '123')
    SELECT *
      FROM TABLE
              (CAST
                  ((pk_get_emp_dtls.fn_t_get_emp_dtls (t.dep_code,
                                                       t.empid,
                                                       TRUNC (SYSDATE)
                   ) AS ps_ot_emp_dtls
           t;in this above query i want to use the emp id ,dept code from the with clause as parameters in the function pk_get_emp_dtls.fn_t_get_emp_dtls
    but error occures SQL command not ended properly
    Regards,
    Friend
    Edited by: most wanted!!!! on Nov 14, 2012 6:17 AM

    I see Solomon beat me to it...
    SQL> create or replace type o_emp as object (empno number, ename varchar2(10))
      2  /
    Type created.
    SQL>
    SQL> create or replace type t_emp as table of o_emp
      2  /
    Type created.
    SQL>
    SQL> create or replace function get_emp(p_deptno in number) return t_emp pipelined as
      2    v_emp o_emp := o_emp(null,null);
      3    cursor cur_emp is
      4      select empno, ename
      5      from   emp
      6      where  deptno = p_deptno;
      7  begin
      8    for i in cur_emp
      9    loop
    10      v_emp.empno := i.empno;
    11      v_emp.ename := i.ename;
    12      pipe row (v_emp);
    13    end loop;
    14    return;
    15  end;
    16  /
    Function created.
    SQL>
    SQL>
    SQL> with t as (select deptno from dept where dname = 'SALES')
      2  select x.*
      3  from   t, table(get_emp(t.deptno)) x
      4  /
         EMPNO ENAME
          7499 ALLEN
          7521 WARD
          7654 MARTIN
          7698 BLAKE
          7844 TURNER
          7900 JAMES
    6 rows selected.
    SQL> with t as (select deptno from dept where dname = 'SALES')
      2  select x.*
      3  from   table(get_emp(t.deptno)) x, t
      4  /
    from   table(get_emp(t.deptno)) x, t
    ERROR at line 3:
    ORA-00904: "T"."DEPTNO": invalid identifier

  • Call the Function against a select query in 500 procedures...

    Hello Gurus,
    I have a scenario, where i had made one function(UDF Function) to calculate something and in every procedure i call that function and calculate my requirement.
    Yesterday, i made a select query using reg exp for the same calculation..
    So my question is, what should be the proper approach..
    I need to implement this on 500 procedures...
    And the UDF function is
    CREATE OR REPLACE FUNCTION "UDF_TEXTSPLIT" (
    p_list VARCHAR2,
    p_del VARCHAR2 := ','
    ) RETURN split_tbl pipelined
    IS
    l_idx PLS_INTEGER;
    l_list VARCHAR2(7999) ;
    l_value VARCHAR2(7999);
    BEGIN
    l_list := p_list;
    LOOP
    l_idx := INSTR(l_list,p_del);
    IF l_idx > 0 THEN
    pipe ROW(SUBSTR(l_list,1,l_idx-1));
    l_list := SUBSTR(l_list,l_idx+LENGTH(p_del));
    ELSE
    pipe ROW(l_list);
    EXIT;
    END IF;
    END LOOP;
    RETURN;
    END Udf_Textsplit;
    I have made this query:
    SELECT a.b,z. b1 FROM
    (SELECT ROWNUM d,REGEXP_SUBSTR(str1, '[^> ]+', 1, LEVEL) b
    FROM (SELECT 'xxx>zzz>gg' str1 FROM dual)
    CONNECT BY REGEXP_SUBSTR(str1, '[^> ]+', 1, LEVEL) IS NOT NULL)a,
    (SELECT ROWNUM d,REGEXP_SUBSTR(str1, '[^> ]+', 1, LEVEL) b1
    FROM (SELECT '100>500>20' str1 FROM dual)
    CONNECT BY REGEXP_SUBSTR(str1, '[^> ]+', 1, LEVEL) IS NOT NULL)z
    WHERE a.d=z.d
    Do i use the same select query in all 500 procedures or call the (UDF Function) in every procedure..
    So which will be faster...
    Your approach would be very much appreciated...
    Thanks,
    Haraprasad...

    Hmm, do I edit 500 procedures to replace a function call with a SQL statement, or edit 1 function to use a sql statement instead of the current algorithm?
    This is why we use code modules that do one thing and do it well. As long as the new version of the function takes the same arguments and returns the same results as the old, then the callers will never know that the way the function works has changed.
    Whenther you put the select statement in 500 procedures, or 1 function, there will still be a context switch every time you use it. The tiny additional overhead of calling a function before the context switch would be unnoticeable.
    John

  • Select query output as a separate column

    Hi,
    How to represent the different values in the same table column as an output in the separate columns using the select query ?
    For example,
    Table "A" has column "col1"
    col1 contains values as below:
    col1
    ====
    1
    2
    3
    4
    5
    now want to display the above column values as a separate column as the output.
    col_alias1 col_alias2 col_alias3 col_alias4 col_alias5
    1 2 3 4 5
    How it can be done ?
    Regards
    Edited by: user640001 on Jan 31, 2011 11:19 PM

    Hi,
    You can try something mentioned in this link.
    http://www.oracle-base.com/articles/misc/StringAggregationTechniques.php
    or try this
    with t as (
    select 'PID12' as product_id,  1 as status_id, 'Time1' as time from dual union all
    select 'PID13', 2, 'Time2' as time from dual union all
    select 'PID14', 3, 'Time3' as time from dual)
    select min(case when status_id = 1 then product_id || ' ' || time end) as Recieved, min(case when status_id = 2 then product_id || ' ' || time end) as Accepted,
           min(case when status_id = 3 then product_id || ' ' || time end) as Delivered from tcheers
    VT
    Edited by: VT on Feb 1, 2011 5:28 PM

  • How to implement 'Quick Select' column in a query result table?

    Hi,
    I have a requirement in OAF to design a search page with 'Quick select' column.
    One of the column in the query result table should be a quick select.
    Once user clicks on the quick select column, we have to navigate back to the previous page with the row value selected.
    Can anyone help me in this.
    Thanks.

    Also refer the search exercise in the toolbox tutorials.
    you can implement the quick search in the same way as update and delete buttons.
    --Prasanna                                                                                                                                                                                                                                                                                                                                   

  • Convert columns to rows by a select query

    I have a table with 10 columns. Pk is combination of 3 columns, let us say A, B and C. I need a select query which returns 7 rows with four columns each let us say A,B,C and D where D contains the value of non PK column. i.e. for first row, D will contain value of fourth column of the table, for second row, D will contain fifth column of the table and so on.
    Please help.

    Maybe NOT TESTED!
    select col_a,col_b,col_c,column_4 col_d
      from (select col_a,col_b,col_c,col_d,col_e,col_f,col_g,col_h,col_i,col_j
              from the_table
    unpivot include nulls (column_4 for source_column in (col_d as 'col_d',
                                                          col_e as 'col_e',
                                                          col_f as 'col_f',
                                                          col_g as 'col_g',
                                                          col_h as 'col_h',
                                                          col_i as 'col_i',
                                                          col_j as 'col_j'
                          )Regards
    Etbin

Maybe you are looking for